package Config::AutoConf::Linker; use ExtUtils::CBuilder; use 5.008002; use warnings; use strict; use Config::AutoConf; use File::Spec; use File::Temp qw/tempdir/; sub detect_library_link_commands { my $CCOMP = shift; my $dir = tempdir(CLEANUP => 1); _write_files($dir); my $CREATE_LIB; my $LINK_WITH_LIB; ## Handle Mac should be just this [HACK! HACK!] $CCOMP->{config}{lddlflags} =~ s/-bundle/-dynamiclib/; ## Now, try to compile it directly using EU::CB my @source_files = map { File::Spec->catfile($dir,$_) } ('library.c', 'test.c'); ## Create object files my @objects = map { $CCOMP->compile(source => $_) } @source_files; ## Calculate filenames my $libfile = File::Spec->catfile($dir, "libfoo$LIBEXT"); my $exefile = File::Spec->catfile($dir, "foo$EXEEXT"); $CCOMP->link( objects => [$objects[0]], module_name => "foo", lib_file => $libfile ); if (-f $libfile) { $CREATE_LIB = sub { my $CC = shift; $CC->{config}{lddlflags} =~ s/-bundle/-dynamiclib/; return $CC->link(@_); }; $CCOMP->link_executable(exe_file => $exefile, extra_linker_flags => "-L$dir -lfoo", objects => [$objects[1]]); if (-f $exefile && -x _ ) { $LINK_WITH_LIB = sub { my $CC = shift; return $CC->link_executable(@_); } } else { $LINK_WITH_LIB = undef; } } else { my $LD = $CCOMP->{config}{ld}; system($LD,"-shared","-o",$libfile,$objects[0]); if (-f $libfile) { $CREATE_LIB = sub { my $CC = shift; my %conf = @_; system($LD,"-shared","-o",$conf{lib_file},@{$conf{objects}}); }; system($LD, "-o",$exefile,"-L$dir", "-lfoo", $objects[1]); if (-f $exefile && -x _) { $LINK_WITH_LIB = sub { my $CC = shift; my %conf = @_; my @CFLAGS = split /\s+/, $conf{extra_linker_flags}; system($LD,"-o",$conf{exe_file},@CFLAGS,@{$conf{objects}}); } } else { $LINK_WITH_LIB = undef; } } else { $CREATE_LIB = undef; $LINK_WITH_LIB = undef; } } return ($CREATE_LIB, $LINK_WITH_LIB); } sub _write_files { my $fh; my $outpath = shift; while() { if (m!==\[(.*?)\]==!) { my $fname = $1; $fname = File::Spec->catfile($outpath, $fname); open $fh, ">$fname" or die "Can't create temporary file $fname\n"; } elsif ($fh) { print $fh $_; } } } 1; =head1 NAME Config-AutoConf-Linker - Utilities to detect how to link a library =head1 SYNOPSIS use Config::AutoConf::Linker; use ExtUtils::CBuilder; my $CC = ExtUtils::CBuilder->new(quiet => 0); my ($library_linker, $link_with_lib) = Config::AutoConf::Linker::detect_library_link_commands($CC); =head1 DESCRIPTION =head2 detect_library_link_commands =head1 SEE ALSO perl(1) =head1 AUTHOR Alberto Manuel Brandão Simões, Eambs@cpan.orgE =head1 COPYRIGHT AND LICENSE Copyright (C) 2009 by Alberto Manuel Brandão Simões =cut __DATA__ ==[library.c]== int answer(void) { return 42; } ==[test.c]== #include int main() { int a = answer(); printf("%d\n", a); return 0; }