package ExtUtils::CBuilder::Base;
-
+$ExtUtils::CBuilder::Base::VERSION = '0.280226';
use strict;
+use warnings;
use File::Spec;
use File::Basename;
use Cwd ();
use Config;
use Text::ParseWords;
-use IO::File;
-use Data::Dumper;$Data::Dumper::Indent=1;
use IPC::Cmd qw(can_run);
use File::Temp qw(tempfile);
-use vars qw($VERSION);
-$VERSION = '0.280203';
-
# More details about C/C++ compilers:
# http://developers.sun.com/sunstudio/documentation/product/compiler.jsp
# http://gcc.gnu.org/
$self->{config}{$k} = $v unless exists $self->{config}{$k};
}
$self->{config}{cc} = $ENV{CC} if defined $ENV{CC};
- $self->{config}{ccflags} = $ENV{CFLAGS} if defined $ENV{CFLAGS};
+ $self->{config}{ccflags} = join(" ", $self->{config}{ccflags}, $ENV{CFLAGS})
+ if defined $ENV{CFLAGS};
$self->{config}{cxx} = $ENV{CXX} if defined $ENV{CXX};
$self->{config}{cxxflags} = $ENV{CXXFLAGS} if defined $ENV{CXXFLAGS};
$self->{config}{ld} = $ENV{LD} if defined $ENV{LD};
- $self->{config}{ldflags} = $ENV{LDFLAGS} if defined $ENV{LDFLAGS};
+ $self->{config}{ldflags} = join(" ", $self->{config}{ldflags}, $ENV{LDFLAGS})
+ if defined $ENV{LDFLAGS};
unless ( exists $self->{config}{cxx} ) {
- my ($ccpath, $ccbase, $ccsfx ) = fileparse($self->{config}{cc}, qr/\.[^.]*/);
+
+ my ($ccbase, $ccpath, $ccsfx ) = fileparse($self->{config}{cc}, qr/\.[^.]*/);
+
+ ## If the path is just "cc", fileparse returns $ccpath as "./"
+ $ccpath = "" if $self->{config}{cc} =~ /^$ccbase$ccsfx$/;
+
foreach my $cxx (@{$cc2cxx{$ccbase}}) {
- if( can_run( File::Spec->catfile( $ccpath, $cxx, $ccsfx ) ) ) {
- $self->{config}{cxx} = File::Spec->catfile( $ccpath, $cxx, $ccsfx );
+ my $cxx1 = File::Spec->catfile( $ccpath, $cxx . $ccsfx);
+
+ if( can_run( $cxx1 ) ) {
+ $self->{config}{cxx} = $cxx1;
last;
}
- if( can_run( File::Spec->catfile( $cxx, $ccsfx ) ) ) {
- $self->{config}{cxx} = File::Spec->catfile( $cxx, $ccsfx );
+ my $cxx2 = $cxx . $ccsfx;
+
+ if( can_run( $cxx2 ) ) {
+ $self->{config}{cxx} = $cxx2;
last;
}
+
if( can_run( $cxx ) ) {
$self->{config}{cxx} = $cxx;
last;
}
unless ( exists $self->{config}{cxx} ) {
$self->{config}{cxx} = $self->{config}{cc};
- my $cflags = $self->{config}{cflags};
+ my $cflags = $self->{config}{ccflags};
$self->{config}{cxxflags} = '-x c++';
$self->{config}{cxxflags} .= " $cflags" if defined $cflags;
}
sub arg_defines {
my ($self, %args) = @_;
- return map "-D$_=$args{$_}", keys %args;
+ return map "-D$_=$args{$_}", sort keys %args;
}
sub compile {
my ($self, %args) = @_;
die "Missing 'source' argument to compile()" unless defined $args{source};
-
+
my $cf = $self->{config}; # For convenience
-
+
my $object_file = $args{object_file}
? $args{object_file}
: $self->object_file($args{source});
- my $include_dirs_ref =
+ my $include_dirs_ref =
(exists($args{include_dirs}) && ref($args{include_dirs}) ne "ARRAY")
? [ $args{include_dirs} ]
: $args{include_dirs};
@{ $include_dirs_ref || [] },
$self->perl_inc(),
);
-
+
my @defines = $self->arg_defines( %{$args{defines} || {}} );
-
+
my @extra_compiler_flags =
$self->split_like_shell($args{extra_compiler_flags});
my @cccdlflags = $self->split_like_shell($cf->{cccdlflags});
$self->arg_object_file($object_file),
);
my @cc = $self->split_like_shell($args{'C++'} ? $cf->{cxx} : $cf->{cc});
-
+
$self->do_system(@cc, @flags, $args{source})
or die "error building $object_file from '$args{source}'";
}
sub lib_file {
- my ($self, $dl_file) = @_;
+ my ($self, $dl_file, %args) = @_;
$dl_file =~ s/\.[^.]+$//;
$dl_file =~ tr/"//d;
- return "$dl_file.$self->{config}{dlext}";
+
+ if (defined $args{module_name} and length $args{module_name}) {
+ # Need to create with the same name as DynaLoader will load with.
+ require DynaLoader;
+ if (defined &DynaLoader::mod2fname) {
+ my $lib = DynaLoader::mod2fname([split /::/, $args{module_name}]);
+ my ($dev, $lib_dir, undef) = File::Spec->splitpath($dl_file);
+ $dl_file = File::Spec->catpath($dev, $lib_dir, $lib);
+ }
+ }
+
+ $dl_file .= ".$self->{config}{dlext}";
+
+ return $dl_file;
}
sub _prepare_mksymlists_args {
my $args = shift;
($args->{dl_file} = $args->{dl_name}) =~ s/.*::// unless $args->{dl_file};
-
+
my %mksymlists_args = (
DL_VARS => $args->{dl_vars} || [],
DL_FUNCS => $args->{dl_funcs} || {},
my ($self, $type, %args) = @_;
my $cf = $self->{config}; # For convenience
-
+
my $objects = delete $args{objects};
$objects = [$objects] unless ref $objects;
- my $out = $args{$type} || $self->$type($objects->[0]);
-
+ my $out = $args{$type} || $self->$type($objects->[0], %args);
+
my @temp_files;
@temp_files =
$self->prelink(%args, dl_name => $args{module_name})
if $args{lddl} && $self->need_prelink;
-
+
my @linker_flags = (
$self->split_like_shell($args{extra_linker_flags}),
$self->extra_link_args_after_prelink(
: $self->arg_exec_file($out);
my @shrp = $self->split_like_shell($cf->{shrpenv});
my @ld = $self->split_like_shell($cf->{ld});
-
+
$self->do_system(@shrp, @ld, @output, @$objects, @linker_flags)
or die "error building $out from @$objects";
-
+
return wantarray ? ($out, @temp_files) : $out;
}
sub split_like_shell {
my ($self, $string) = @_;
-
+
return () unless defined($string);
return @$string if UNIVERSAL::isa($string, 'ARRAY');
$string =~ s/^\s+|\s+$//g;
return () unless length($string);
-
+
# Text::ParseWords replaces all 'escaped' characters with themselves, which completely
# breaks paths under windows. As such, we forcibly replace backwards slashes with forward
# slashes on windows.
$string =~ s@\\@/@g if $^O eq 'MSWin32';
-
+
return Text::ParseWords::shellwords($string);
}