use strict; use warnings; use Cwd; use Config; use Module::Build; use File::Spec::Functions qw( rel2abs catdir catfile updir path ); diag( my $in_parrot_tree = in_parrot_tree() ); diag( my $dl_env_var = get_dl_env_var() ); diag( my ($libp, $incp) = get_paths() ); diag( my ($cflags, $lflags) = get_compiler_flags( $in_parrot_tree ) ); diag( my $parrot = get_parrot_path( $in_parrot_tree ) ); diag( my $path_sep = get_path_separator() ); my $class = Module::Build->subclass( code => <<"END_HERE", use File::Spec; sub ACTION_build { my \$self = shift; my \@cmd = ( qw( $parrot -o ), map { File::Spec->catfile( 't', "greet.\$_" ) } qw( pbc pir ) ); system( \@cmd ) == 0 or die "Cannot compile PBC for test: \$?"; \$self->SUPER::ACTION_build( \@_ ); } sub ACTION_test { my \$self = shift; \$ENV{$dl_env_var} = join( '$path_sep', split( /$path_sep/, ( \$ENV{$dl_env_var} || '' ) ), '$libp' ) if $in_parrot_tree; \$self->SUPER::ACTION_test( \@_ ); } END_HERE ); my $builder = $class->new( module_name => 'Parrot::Embed', license => 'perl', dist_author => 'chromatic ', dist_version_from => 'lib/Parrot/Embed.pm', build_requires => { 'Test::More' => 0, 'ExtUtils::CBuilder' => 0, }, add_to_cleanup => [ 'Parrot-Embed-*' ], include_dirs => [ $incp ], extra_compiler_flags => $cflags, extra_linker_flags => $lflags, ); $builder->create_build_script(); sub in_parrot_tree { my $cwd = cwd(); return $cwd =~ /\bext\b.Parrot/; } sub get_dl_env_var { return $Config{ldlibpthname}; return 'DYLD_LIBRARY_PATH' if $^O =~ /darwin/; return 'PATH' if $^O =~ /Win32/; return 'LD_LIBRARY_PATH'; } sub get_path_separator { return ';' if $^O =~ /Win32/; return ':'; } sub get_compiler_flags { my $in_parrot_tree = shift; return get_flags_from_parrot_src() if $in_parrot_tree; return get_flags_from_pkg_config() if $ENV{PKG_CONFIG_PATH}; } sub get_flags_from_pkg_config { require ExtUtils::PkgConfig; my %pkg_info = ExtUtils::PkgConfig->find( 'parrot' ); return @pkg_info{qw( cflags libs )}; } sub get_flags_from_parrot_src { my $updir = updir(); my $file = catfile( $updir, $updir, 'parrot.pc' ); open( my $fh, '<', $file ) or die "Cannot read $file: $!\n"; my %vars; while (<$fh>) { chomp; last unless /\S/; my ($var, $value) = split(/=/, $_); $vars{$var} = $value; } while (<$fh>) { chomp; last unless /\S/; my ($var, $value) = split(/: /, $_); $value =~ s/\${(\w+)}/$vars{$1}/g; $vars{$var} = $value; } $vars{Cflags} .= ' -I' . catdir( ($updir) x 2, 'include' ); $vars{Libs} .= $^O =~ /Win32/ ? ' ..\..\libparrot.lib' : " -L$libp"; return @vars{qw( Cflags Libs )}; } sub get_paths { my $updir = updir(); my @lib_dir = $^O =~ /Win32/ ? () : qw( blib lib ); my $lib_path = rel2abs( catdir( ($updir) x 2, @lib_dir ) ); my $inc_path = rel2abs( catdir( ($updir) x 2, 'include' ) ); return( $lib_path, $inc_path ); } sub get_parrot_path { my $in_parrot_tree = shift; return get_parrot_path_internal() if $in_parrot_tree; return get_parrot_path_external(); } sub get_parrot_path_internal { my $updir = updir(); my $path = catfile(($updir) x 2, get_parrot_executable_name()); die "parrot apparently not built!\n" unless -e $path; return $path; } sub get_parrot_path_external { my $parrot = get_parrot_executable_name(); for my $path ( path() ) { my $file = catfile( $path, $parrot ); next unless -e $file; return $file; } die "parrot apparently not installed in \$PATH\n"; } sub get_parrot_executable_name { return 'parrot' unless $^O =~ /Win32/; return 'parrot.exe'; } sub diag { return unless $ENV{PE_DEBUG}; print STDERR "<$_>\n" for @_; }