package ExtUtils::Depends; require Exporter; use File::Basename; use Carp; @ISA = (@ISA, qw(Exporter)); @EXPORT = qw( add_xs add_raw_xs remove_xs add_pm add_c remove_c add_typemap remove_tyemap add_defs remove_defs add_headers remove_headers add_boot remove_boot sort_libs setup_xs write_ext); @defines = (); %xs = (); %c = (); %typemaps = (); %defs = (); %boot = (); %headers = (); $pm = {}; @clean = (); $add = 0; $Directory = ''; sub add_xs { foreach (@_) { $xs{$Directory . "xs/" .$_} = $add++; } } sub add_raw_xs { foreach (@_) { $xs{$_} = $add++; } } sub remove_xs { foreach (@_) { delete $xs{$Directory . "xs/". $_}; } } sub add_pm { my($k,$v); while (($k,$v) = splice(@_, 0, 2)) { $k = $Directory . $k; $pm->{$k} = $v; } } sub add_c { foreach (@_) { $c{$Directory . $_} = $add++; } } sub remove_c { foreach (@_) { delete $c{$Directory . $_}; } } sub add_typemap { foreach (@_) { $typemap{$Directory . $_} = $add++; } } sub remove_typemap { foreach (@_) { delete $typemap{$Directory . $_}; } } sub add_defs { foreach (@_) { $defs{$Directory . $_} = $add++; } } sub remove_defs { foreach (@_) { delete $defs{$Directory . $_}; } } sub add_headers { foreach (@_) { $headers{$_} = $add++; } } sub remove_headers { foreach (@_) { delete $headers{$_}; } } sub add_boot { foreach (@_) { $boot{$_} = $add++; } } sub remove_boot { foreach (@_) { delete $boot{$_}; } } sub sort_libs { my ($libs) = shift; my (@libs, %seenlibs, @revlibs, @lflags); $libs =~ s/(^|\s)-[rR]\S+//g; @libs = split(/\s+/, $libs); %seenlibs = (); @revlibs=(); @lflags=(); foreach (@libs) { if (/^-l/) { unshift(@revlibs, $_); } else { unshift(@lflags, $_) unless $seenlibs{$_}++; } } @libs=(); foreach (@revlibs) { unshift(@libs, $_) unless $seenlibs{$_}++; } return (@lflags, @libs); } sub save_config { my ($module, $fname, $inc, $libs, $typemaps, $defs, $defines, $headers, $pm) = @_; # genera IFiles.pm local(*IF); my ($mdir) = $module; my ($mdir2) = $module; $mdir =~ s/.*:://; $mdir2 =~ s.::./.g; open(IF, ">$fname") || die "Cannot open '$fname': $!"; $pm->{$fname} = '$(INST_ARCHLIBDIR)/'."$mdir/Install/Files.pm"; print IF "#!/usr/bin/perl\n\npackage ${module}::Install::Files;\n\n"; print IF "\@typemaps = qw(\n"; foreach (@$typemaps) { my($b) = basename($_); print IF "\t$b\n"; $pm->{$_} = '$(INST_ARCHLIBDIR)/'. "$mdir/Install/" . $b; } print IF ");\n\n\@defs = qw(\n"; foreach (@$defs) { my($b) = basename($_); print IF "\t$b\n"; $pm->{$_} = '$(INST_ARCHLIBDIR)/'. "$mdir/Install/" . $b; } print IF ");\n\n\@headers = qw(\n"; foreach (@$headers) { my($b) = $_; $b =~ s(^[^<"]+/)(); #" print IF "\t$b\n"; #$pm->{$_} = '$(INST_ARCHLIBDIR)/'. "$mdir/Install/" . $b; } print IF ");\n\n\@defines = qw(\n"; foreach (@$defines) { print IF "\t$_\n"; } print IF ");\n\n"; print IF "\$libs = '$libs';\n"; print IF "\$inc = '$inc';\n"; print IF <<"EOT"; \$CORE = undef; foreach (\@INC) { if ( -f \$_ . "/$mdir2/Install/Files.pm") { \$CORE = \$_ . "/$mdir2/Install/"; last; } } 1; EOT close(IF); } sub setup_xs { my $xfiles = {}; my ($ldfrom, $object); $ldfrom = $object = ''; foreach (keys %xs) { my($xs) = $_; s/\.xs$/.c/; $xfiles->{$xs} = $_; push(@clean, $_); s/\.c$/.o/; push(@clean, $_); $object .= " $_"; s(.*/)(); $ldfrom .= " $_"; } foreach (keys %c) { s/\.c$/.o/; push(@clean, $_); $object .= " $_"; } return ($xfiles, $object, $ldfrom); } sub write_ext { open (EXT, ">build/extension.xsh"); print EXT "\n\n# Do not edit this file, as it is automatically generated by Makefile.PL\n\n"; print EXT "BOOT:\n{\n"; foreach (sort {$boot{$a} <=> $boot{$b}} keys %boot) { my($b) = $_; $b =~ s/::/__/g; $b = "boot_$b"; print EXT "extern void $b(CV *cv);\n"; } foreach (sort {$boot{$a} <=> $boot{$b}} keys %boot) { my($b) = $_; $b =~ s/::/__/g; $b = "boot_$b"; print EXT "callXS($b, cv, mark);\n"; } print EXT "}\n"; close(EXT); } 1;