Thread: [Module-build-general] Article on perl.com
Status: Beta
Brought to you by:
kwilliams
|
From: Dave R. <au...@ur...> - 2003-02-13 04:31:08
|
I wrote an article about Module::Build for perl.com, and it's now available at http://www.perl.com/pub/a/2003/02/12/module1.html There will be another sometime in the next few weeks, I hope. -dave /*======================= House Absolute Consulting www.houseabsolute.com =======================*/ |
|
From: <and...@an...> - 2003-02-13 06:26:14
|
>>>>> On Wed, 12 Feb 2003 22:30:04 -0600 (CST), Dave Rolsky <au...@ur...> said: > I wrote an article about Module::Build for perl.com, and it's now > available at http://www.perl.com/pub/a/2003/02/12/module1.html Thanks for that article! Please send me your patch to CPAN.pm that supports Build.PL. I cannot promise that I can work on it (tuits, tuits!), but I'll at least consider doing it. There's one thing that immediately came to my mind but you didn't discuss it. You write: Another possibility is to create functionally equivalent Build.PL and Makefile.PL scripts. If you're using Module::Build because you need to customize installation behavior in a way that is difficult to do with ExtUtils::MakeMaker, this pretty much defeats the purpose of using Module::Build at all, and in any case having two separate pieces of code that do the same thing is always unappealing. Let's imagine, Module::Build could write an *equivalent* Makefile.PL. One that could then be used with ExtUtils::MakeMaker (and without Module::Build). If that were possible (even just for 80% of the modules out there), that would convince many developers to switch, as they would just distribute both Build.PL and Makefile.PL (no duplicated work). The result would not bother anybody among the user community, as they would not even notice that Module::Build had been working. For the 20% of complicated modules, Module::Build could just die() with a few FIXME messages and that might be an incentive to many a developer to actually produce patches. Maybe I'm missing something, and surely this has been discussed before, but if you could discuss this idea, I'd be interested to hear your arguments. -- andreas |
|
From: Dave R. <au...@ur...> - 2003-02-13 18:49:01
|
On Thu, 13 Feb 2003, Andreas J. Koenig wrote: > Please send me your patch to CPAN.pm that supports Build.PL. I cannot > promise that I can work on it (tuits, tuits!), but I'll at least > consider doing it. Doh, I forgot the patch. Also, I wanted to point out that it is smart enough to try to install Module::Build if it sees a Build.PL file in the distro. /*======================= House Absolute Consulting www.houseabsolute.com =======================*/ Only in .: cpan-patch diff -ur ../CPAN-1.59_54-old/lib/CPAN.pm ./lib/CPAN.pm --- ../CPAN-1.59_54-old/lib/CPAN.pm 2001-11-18 11:48:02.000000000 -0600 +++ ./lib/CPAN.pm 2001-11-18 13:00:26.000000000 -0600 @@ -3852,17 +3852,40 @@ my($mpl) = MM->catfile($packagedir,"Makefile.PL"); my($mpl_exists) = -f $mpl; - unless ($mpl_exists) { + my($bpl) = MM->catfile($packagedir,"Build.PL"); + my($bpl_exists) = -f $bpl; + unless ($mpl_exists or $bpl_exists) { # NFS has been reported to have racing problems after the # renaming of a directory in some environments. # This trick helps. sleep 1; - my $mpldh = DirHandle->new($packagedir) + my $dh = DirHandle->new($packagedir) or Carp::croak("Couldn't opendir $packagedir: $!"); - $mpl_exists = grep /^Makefile\.PL$/, $mpldh->read; - $mpldh->close; + foreach ($dh->read) { + $mpl_exists = /^Makefile\.PL$/; + $bpl_exists = /^Build\.PL$/; + } + $dh->close; } - unless ($mpl_exists) { + + # If this is a module that uses Module::Build then we need to + # install Module::Build. However, Module::Build uses _itself_ to + # install so to avoid a recursive prereq follow of doom, we + # explicitly do not try to install Module::Build when already + # install Module::Build. - Dave Rolsky + if ($bpl_exists and not grep { $_ eq "Module::Build" } $self->containsmods) { + my $nmo = $CPAN::META->instance("CPAN::Module","Module::Build"); + + unless ($nmo->inst_file and $nmo->uptodate) { + $CPAN::Frontend->myprint("The module you are installing requires the Module::Build package. +Either you do not have this module installed or you do not have the latest version. +It is recommended that you install the latest version now or +else it may not be possible to install this module"); + $self->follow_prereqs("Module::Build"); + } + } + + unless ($mpl_exists or $bpl_exists) { $self->debug(sprintf("makefilepl[%s]anycwd[%s]", $mpl, CPAN::anycwd(), @@ -3873,7 +3896,7 @@ $self->{'configure'} = $configure; } elsif (-f MM->catfile($packagedir,"Makefile")) { $CPAN::Frontend->myprint(qq{ -Package comes with a Makefile and without a Makefile.PL. +Package comes with a Makefile and without a Makefile.PL or Build.PL. We\'ll try to build it with that Makefile then. }); $self->{writemakefile} = "YES"; @@ -3886,9 +3909,9 @@ } $cf =~ s|[/\\:]||g; # risk of filesystem damage $cf = "unknown" unless length($cf); - $CPAN::Frontend->myprint(qq{Package seems to come without Makefile.PL. - (The test -f "$mpl" returned false.) - Writing one on our own (setting NAME to $cf)\a\n}); + $CPAN::Frontend->myprint(qq{Package seems to come without Makefile.PL or Build.PL. + (The tests -f "$mpl" and -f "$bpl" returned false.) + Writing a Makefile.PL on our own (setting NAME to $cf)\a\n}); $self->{had_no_makefile_pl}++; sleep 3; @@ -3899,7 +3922,7 @@ or Carp::croak("Could not open >$mpl: $!"); $fh->print( qq{# This Makefile.PL has been autogenerated by the module CPAN.pm -# because there was no Makefile.PL supplied. +# because there was no Makefile.PL or Build.PL supplied. # Autogenerated on: }.scalar localtime().qq{ use ExtUtils::MakeMaker; @@ -3907,9 +3930,14 @@ }); $fh->close; + + $mpl_exists = 1; } } + $self->{makescript} = $mpl_exists ? "Makefile.PL" : $bpl_exists ? "Build.PL" : ""; + $self->{maketype} = $mpl_exists ? 'make' : $bpl_exists ? "Module::Build" : ""; + return $self; } @@ -4370,7 +4398,7 @@ # $switch = "-MExtUtils::MakeMaker ". # "-Mops=:default,:filesys_read,:filesys_open,require,chdir" # if $] > 5.00310; - $system = "$perl $switch Makefile.PL $CPAN::Config->{makepl_arg}"; + $system = "$perl $switch $self->{makescript} $CPAN::Config->{makepl_arg}"; } unless (exists $self->{writemakefile}) { local($SIG{ALRM}) = sub { die "inactivity_timeout reached\n" }; @@ -4407,16 +4435,17 @@ } else { $ret = system($system); if ($ret != 0) { - $self->{writemakefile} = "NO Makefile.PL returned status $ret"; + $self->{writemakefile} = "NO $self->{makescript} returned status $ret"; return; } } - if (-f "Makefile") { + if (($self->{maketype} eq "make" && -f "Makefile") || + ($self->{maketype} eq "Module::Build" && -f "Build")) { $self->{writemakefile} = "YES"; delete $self->{make_clean}; # if cleaned before, enable next } else { $self->{writemakefile} = - qq{NO Makefile.PL refused to write a Makefile.}; + qq{NO $self->{makescript} refused to write a Makefile.}; # It's probably worth to record the reason, so let's retry # local $/; # my $fh = IO::File->new("$system |"); # STDERR? STDIN? @@ -4430,7 +4459,11 @@ if (my @prereq = $self->unsat_prereq){ return 1 if $self->follow_prereqs(@prereq); # signal success to the queuerunner } - $system = join " ", $CPAN::Config->{'make'}, $CPAN::Config->{make_arg}; + if ($self->{maketype} eq 'make') { + $system = join " ", $CPAN::Config->{'make'}, $CPAN::Config->{make_arg}; + } else { + $system = join " ", $self->perl, File::Spec->catfile( File::Spec->curdir, "Build" ), $CPAN::Config->{make_arg}; + } if (system($system) == 0) { $CPAN::Frontend->myprint(" $system -- OK\n"); $self->{'make'} = "YES"; @@ -4532,6 +4565,7 @@ # but we must have run it my $build_dir = $self->{build_dir} or die "Panic: no build_dir?"; my $makefile = File::Spec->catfile($build_dir,"Makefile"); + my $buildprereq = File::Spec->catfile($build_dir,"_build","prereq"); my(%p) = (); my $fh; if (-f $makefile @@ -4560,6 +4594,16 @@ } last; } + } elsif (-f $buildprereq + and + $fh = FileHandle->new("<$buildprereq")) { + while (<$fh>) { + my ($mod,$ver) = split /\s*=\s*/; + if ( defined $p{$mod} ) { + warn "Warning: PREREQ_PM mentions $mod more than once, last mention wins"; + } + $p{$mod} = $ver; + } } $self->{prereq_pm_detected}++; return $self->{prereq_pm} = \%p; @@ -4606,7 +4650,12 @@ return; } - my $system = join " ", $CPAN::Config->{'make'}, "test"; + my $system; + if ($self->{maketype} eq "make") { + $system = join " ", $CPAN::Config->{'make'}, "test"; + } elsif ($self->{maketype} eq "Module::Build") { + $system = join " ", $self->perl, File::Spec->catfile( File::Spec->curdir, "Build" ), "test"; + } if (system($system) == 0) { $CPAN::Frontend->myprint(" $system -- OK\n"); $self->{make_test} = "YES"; @@ -4637,7 +4686,12 @@ return; } - my $system = join " ", $CPAN::Config->{'make'}, "clean"; + my $system; + if ($self->{maketype} eq "make") { + $system = join " ", $CPAN::Config->{'make'}, "clean"; + } elsif ($self->{maketype} eq "Module::Build") { + $system = join " ", $self->perl, File::Spec->catfile( File::Spec->curdir, "Build" ), "clean"; + } if (system($system) == 0) { $CPAN::Frontend->myprint(" $system -- OK\n"); @@ -4712,8 +4766,14 @@ return; } - my $system = join(" ", $CPAN::Config->{'make'}, - "install", $CPAN::Config->{make_install_arg}); + my $system; + if ($self->{maketype} eq "make") { + $system = join(" ", $CPAN::Config->{'make'}, + "install", $CPAN::Config->{make_install_arg}); + } elsif ($self->{maketype} eq "Module::Build") { + $system = join(" ", $self->perl, File::Spec->catfile( File::Spec->curdir, "Build" ), + "install", $CPAN::Config->{make_install_arg}); + } my($stderr) = $^O =~ /Win/i ? "" : " 2>&1 "; my($pipe) = FileHandle->new("$system $stderr |"); my($makeout) = ""; |
|
From: Dave R. <au...@ur...> - 2003-02-13 18:52:59
|
On Thu, 13 Feb 2003, Andreas J. Koenig wrote: > Please send me your patch to CPAN.pm that supports Build.PL. I cannot > promise that I can work on it (tuits, tuits!), but I'll at least > consider doing it. It's after my sig. It's against 1.59_54 but it may just apply cleanly against the latest, for all I know. I'm pretty sure it works ;) One thing it could do better is prereq handling. Right now it just reads in _build/prereq and parses it, but it should really load Module::Build and ask it about the prereqs instead. This is what CPANPLUS currently does. > Let's imagine, Module::Build could write an *equivalent* Makefile.PL. > One that could then be used with ExtUtils::MakeMaker (and without > Module::Build). If that were possible (even just for 80% of the > modules out there), that would convince many developers to switch, as > they would just distribute both Build.PL and Makefile.PL (no > duplicated work). The result would not bother anybody among the user > community, as they would not even notice that Module::Build had been > working. For the 20% of complicated modules, Module::Build could just > die() with a few FIXME messages and that might be an incentive to many > a developer to actually produce patches. Maybe I'm missing something, > and surely this has been discussed before, but if you could discuss > this idea, I'd be interested to hear your arguments. I'm not sure I understand what you're suggesting. Are you saying that "./Build dist" could write out a Makefile.PL script? That's not a bad idea, I suppose. -dave /*======================= House Absolute Consulting www.houseabsolute.com =======================*/ |
|
From: Ken W. <ke...@ma...> - 2003-02-16 03:41:15
|
On Thursday, February 13, 2003, at 12:25 AM, Andreas J. Koenig wrote: > Let's imagine, Module::Build could write an *equivalent* Makefile.PL. > One that could then be used with ExtUtils::MakeMaker (and without > Module::Build). If that were possible (even just for 80% of the > modules out there), that would convince many developers to switch, as > they would just distribute both Build.PL and Makefile.PL (no > duplicated work). Yeah, that's not a half-bad idea. The rub, of course, is that many options to Module::Build->new() might not translate very easily to MakeMaker options. But we could at least take a stab at it and see what happens. Of course, a tool that translates the *other* direction would be really nice too, for getting existing CPAN modules into the M::B world if the user so desires. This would likely involve a lot of voodoo, like perhaps hijacking WriteMakefile() and looking at the options given to the function, and perhaps scanning the Makefile.PL to see whether there's extra stuff in there that might be doing something significant. One good reason to do the EU::MM -> M::B step is that even if the M::B versions of things never made it to CPAN, we could generate META.yml files for those things that we're able to convert, and then generate some kind of dependency mapping for CPAN. -Ken |