Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Controlled build systems

by sock (Monk)
on Sep 16, 2005 at 06:55 UTC ( [id://492545]=perlquestion: print w/replies, xml ) Need Help??

sock has asked for the wisdom of the Perl Monks concerning the following question:

Fellow monks,

I've been working with build systems and different enviroments as of lately. Essentially what I'm trying to do is create a build system that will automatically fetch all of the required perl modules and dependancies from cpan and install them automatically.
Consider the following build script:
#!/usr/bin/env perl # Build.PL use strict; use warnings; use lib 'boot/lib'; use Module::Build; use File::Spec(); our %provides = ( 'LWP' => 'libwww-perl', ); my $build_pkg = 'Module::Build'; my $build = $build_pkg->new ( module_name => 'World::Builder', license => 'perl', requires => { 'Class::Accessor' => '==0.22', 'LWP' => '==5.803', }, recursive_test_files => 1, create_readme => 1, test_files => qw/t/, PL_files => { 'config/rc.PL' => 'rc', }, add_to_cleanup => [ '*.tmp' , 'rc' ], ); $build->notes('no_db' => $build->args('no_db') ); our $install_base = $build->{properties}{install_base}; our $base_dir = $build->{properties}{base_dir}; our $build_dir = "/tmp/wb_build_$$"; my $plib = $ENV{PERL5LIB}; $ENV{PERL5LIB} = "$ENV{PWD}/lib:$install_base/lib/site_perl:$ENV{PWD}/ +boot/lib:$plib"; mkdir $build_dir; check_install_base($build); check_perl($build); check_prereq_failures($build); checked_system("rm -rf $build_dir"); $build->create_build_script; exit; sub check_prereq_failures { my($build) = @_; return unless $build->prereq_failures(); $ENV{PATH} = "$install_base/bin:$ENV{PATH}"; if(my $failures = $build->prereq_failures()->{requires}) { my @prereqs = sort keys %{$failures}; foreach my $prereq (@prereqs) { my $prereq_ver = $failures->{$prereq}{need}; $prereq_ver =~ s/^[^\d]*//; # remove any '==', + '>=' etc. print STDERR "Installing $prereq_ver\n"; eval { # check %provides for override _install_prereq($provides{$prereq} || +$prereq, $prereq_ver); }; } print STDERR "restarting after installation of prerequ +isites\n"; sleep 1; exec $0, @ARGV; } } sub _install_prereq { my($module, $version) = @_; $module =~ s/::/-/g; my $orig_dir = $ENV{PWD}; $ENV{SABLOTLIBPATH} = "$base_dir/app/lib"; $ENV{SABLOTINCPATH} = "$base_dir/app/include"; my $perl = $build->find_perl_interpreter; checked_system("tar xzf $base_dir/vendor/cpan/$module-$version.tar +.gz -C $build_dir"); chdir "$build_dir/$module-$version"; checked_system("yes '' | $perl Makefile.PL"); checked_system("make"); checked_system("make install"); chdir $orig_dir; } # we want to make sure an install_base was specified # defaulting to './app'. dirty hack job sub check_install_base { my($build) = @_; unless($build->{properties}{install_base}) { my $install_base = $build->{properties}{base_dir} . '/ +app'; $install_base = File::Spec->rel2abs(File::Spec->canonp +ath($install_base)); $install_base =~ s{/[^/]+/\.\./}{/}; # remove '..'s print STDERR "restarting with default install_base '$i +nstall_base'\n"; exec $0, @ARGV, "--install_base=$install_base"; } } # will check that we're running the correct installation of perl, if n +ot it will # build it and restart with the correct perl sub check_perl { my($build) = @_; my $orig_dir = $ENV{PWD}; my $prospective_perl = File::Spec->canonpath( File::Spec->rel2 +abs($build->install_destination('bin')) ) . "/perl"; # are we running the correct perl? if($build->find_perl_interpreter ne $prospective_perl) { if(! -x $prospective_perl) { checked_system("tar xzf $base_dir/vendor/perl* +.tar.gz -C $build_dir"); chdir glob("$build_dir/perl*"); checked_system("./Configure -de -Dusethreads - +Dprefix=$install_base -Aundef:installusrbinperl"); checked_system("make -j2"); checked_system("make install"); chdir $orig_dir; } print STDERR "restarting in terms of correct Perl\n"; exec $prospective_perl, $0, @ARGV; } } sub checked_system { my($cmd) = @_; if(my $err = system($cmd)) { print "command \"$cmd\" failed: $err: $!\n"; die $err; } } 1;

What I'm doing is trying to create an application with its own perl build and all of the modules that it requires. This way I can control versions and such and really keep things tight and clean. It currently has a vendor directory with the perl sources and a sub directory called cpan with the cpan modules used.

This feels kinda messy. I've come here before asking for this sort of thing and I'll ask again. What can I do to simplify this process and clean up this build script. Some things I'd like to do are limiting the output and such of the system() calls as well as create a summary/statistics bit at the end of the build for errors and such. Does anyone have any advise on where I can take something like this?

Replies are listed 'Best First'.
Re: Controlled build systems
by xdg (Monsignor) on Sep 16, 2005 at 10:51 UTC

    Before you head too far down this road, have you looked at PAR? If not, consider reading the PAR::Tutorial and see if it gets you close to your objective.

    -xdg

    Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

      I'll second this. PAR may not always be the right solution for everyone, but lan' sakes has it made my life easier! I've cut down my 'Marion the Librarian' time to about 1/5 of what it was, leaving me more time to make Oracle trigger errors.

      --
      tbone1, YAPS (Yet Another Perl Schlub)
      And remember, if he succeeds, so what.
      - Chick McGee

Re: Controlled build systems
by radiantmatrix (Parson) on Sep 16, 2005 at 15:52 UTC

    You could very easily use the ExtUtils::MakeMaker system to establish dependencies for your core script, then using the CPAN module(s) to install your app will automatically retrieve and build dependencies.

    <-radiant.matrix->
    Larry Wall is Yoda: there is no try{} (ok, except in Perl6; way to ruin a joke, Larry! ;P)
    The Code that can be seen is not the true Code
    "In any sufficiently large group of people, most are idiots" - Kaa's Law
Re: Controlled build systems
by Anonymous Monk on Sep 17, 2005 at 14:18 UTC
    Please don't force this on anyone, but if you must follow that path, just switch to Module::Install
      Ahhh, I've seen this one before. I did a good bit of looking into it but then thought that because the complexity of the build script it wouldn't carry over very well.
      Guns don't kill people, ninjas do.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://492545]
Approved by lidden
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (2)
As of 2024-04-26 05:03 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found