1 package Module::Build::PPMMaker;
9 $VERSION = eval $VERSION;
11 # This code is mostly borrowed from ExtUtils::MM_Unix 6.10_03, with a
12 # few tweaks based on the PPD spec at
13 # http://www.xav.com/perl/site/lib/XML/PPD.html
15 # The PPD spec is based on <http://www.w3.org/TR/NOTE-OSD>
19 return bless {@_}, $package;
23 my ($self, %args) = @_;
24 my $build = delete $args{build};
27 if (exists $args{codebase}) {
28 @codebase = ref $args{codebase} ? @{$args{codebase}} : ($args{codebase});
30 my $distfile = $build->ppm_name . '.tar.gz';
31 print "Using default codebase '$distfile'\n";
32 @codebase = ($distfile);
36 foreach my $info (qw(name author abstract version)) {
37 my $method = "dist_$info";
38 $dist{$info} = $build->$method() or die "Can't determine distribution's $info\n";
41 $self->_simple_xml_escape($_) foreach $dist{abstract}, @{$dist{author}};
43 # TODO: could add <LICENSE HREF=...> tag if we knew what the URLs were for
46 <SOFTPKG NAME=\"$dist{name}\" VERSION=\"$dist{version}\">
47 <ABSTRACT>$dist{abstract}</ABSTRACT>
48 @{[ join "\n", map " <AUTHOR>$_</AUTHOR>", @{$dist{author}} ]}
52 # We don't include recommended dependencies because PPD has no way
53 # to distinguish them from normal dependencies. We don't include
54 # build_requires dependencies because the PPM installer doesn't
55 # build or test before installing. And obviously we don't include
58 foreach my $type (qw(requires)) {
59 my $prereq = $build->$type();
60 while (my ($modname, $spec) = each %$prereq) {
61 next if $modname eq 'perl';
63 my $min_version = '0.0';
64 foreach my $c ($build->_parse_conditions($spec)) {
65 my ($op, $version) = $c =~ /^\s* (<=?|>=?|==|!=) \s* ([\w.]+) \s*$/x;
67 # This is a nasty hack because it fails if there is no >= op
69 $min_version = $version;
74 # PPM4 spec requires a '::' for top level modules
75 $modname .= '::' unless $modname =~ /::/;
77 $ppd .= qq! <REQUIRE NAME="$modname" VERSION="$min_version" />\n!;
81 # We only include these tags if this module involves XS, on the
82 # assumption that pure Perl modules will work on any OS.
83 if (keys %{$build->find_xs_files}) {
84 my $perl_version = $self->_ppd_version($build->perl_version);
85 $ppd .= sprintf(<<'EOF', $self->_varchname($build->config) );
86 <ARCHITECTURE NAME="%s" />
90 foreach my $codebase (@codebase) {
91 $self->_simple_xml_escape($codebase);
92 $ppd .= sprintf(<<'EOF', $codebase);
93 <CODEBASE HREF="%s" />
102 my $ppd_file = "$dist{name}.ppd";
103 my $fh = IO::File->new(">$ppd_file")
104 or die "Cannot write to $ppd_file: $!";
106 my $io_file_ok = eval { IO::File->VERSION(1.13); 1 };
107 $fh->binmode(":utf8")
108 if $io_file_ok && $fh->can('binmode') && $] >= 5.008 && $Config{useperlio};
116 my ($self, $version) = @_;
118 # generates something like "0,18,0,0"
119 return join ',', (split(/\./, $version), (0)x4)[0..3];
122 sub _varchname { # Copied from PPM.pm
123 my ($self, $config) = @_;
124 my $varchname = $config->{archname};
125 # Append "-5.8" to architecture name for Perl 5.8 and later
127 my $vstring = sprintf "%vd", $^V;
128 $vstring =~ s/\.\d+$//;
129 $varchname .= "-$vstring";
142 my $rx = join '|', keys %escapes;
144 sub _simple_xml_escape {
145 $_[1] =~ s/($rx)/$escapes{$1}/go;
155 Module::Build::PPMMaker - Perl Package Manager file creation
159 On the command line, builds a .ppd file:
165 This package contains the code that builds F<.ppd> "Perl Package
166 Description" files, in support of ActiveState's "Perl Package
167 Manager". Details are here:
168 L<http://aspn.activestate.com/ASPN/Downloads/ActivePerl/PPM/>
173 Dave Rolsky <autarch@urth.org>, Ken Williams <kwilliams@cpan.org>
178 Copyright (c) 2001-2006 Ken Williams. All rights reserved.
180 This library is free software; you can redistribute it and/or
181 modify it under the same terms as Perl itself.
186 perl(1), Module::Build(3)