5 package ExtUtils::Depends;
14 our $VERSION = '0.302';
19 die "$class version $_[0] is required--this is only version $VERSION"
24 my ($class, $name, @deps) = @_;
37 $self->add_deps (@deps);
39 # attempt to load these now, so we'll find out as soon as possible
40 # whether the dependencies are valid. we'll load them again in
41 # get_makefile_vars to catch any added between now and then.
50 $self->{deps}{$d} = undef
51 unless $self->{deps}{$d};
57 $self->load_deps; # just in case
59 return %{$self->{deps}};
64 push @{ $self->{inc} }, @_;
68 my ($self, $newlibs) = @_;
69 $self->{libs} = $newlibs;
74 while (my ($key, $value) = each %pm) {
75 $self->{pm}{$key} = $value;
79 sub _listkey_add_list {
80 my ($self, $key, @list) = @_;
81 $self->{$key} = [] unless $self->{$key};
82 push @{ $self->{$key} }, @list;
85 sub add_xs { shift->_listkey_add_list ('xs', @_) }
86 sub add_c { shift->_listkey_add_list ('c', @_) }
89 $self->_listkey_add_list ('typemaps', @_);
93 # no-op, only used for source back-compat
94 sub add_headers { carp "add_headers() is a no-op" }
97 sub basename { (File::Spec->splitdir ($_[0]))[-1] }
98 # get the name in Makefile syntax.
99 sub installed_filename {
101 return '$(INST_ARCHLIB)/$(FULLEXT)/Install/'.basename ($_[0]);
105 # install things by adding them to the hash of pm files that gets
106 # passed through WriteMakefile's PM key.
109 $self->add_pm ($f, $self->installed_filename ($f));
117 my ($self, $filename) = @_;
119 my $file = IO::File->new (">".$filename)
120 or croak "can't open '$filename' for writing: $!\n";
122 print $file "package $self->{name}\::Install::Files;\n\n";
124 print $file "".Data::Dumper->Dump([{
125 inc => join (" ", @{ $self->{inc} }),
126 libs => $self->{libs},
127 typemaps => [ map { basename $_ } @{ $self->{typemaps} } ],
128 deps => [keys %{ $self->{deps} }],
131 print $file "\n\n# this is for backwards compatiblity\n";
132 print $file "\@deps = \@{ \$self->{deps} };\n";
133 print $file "\@typemaps = \@{ \$self->{typemaps} };\n";
134 print $file "\$libs = \$self->{libs};\n";
135 print $file "\$inc = \$self->{inc};\n";
136 # this is riduculous, but old versions of ExtUtils::Depends take
137 # first $loadedmodule::CORE and then $INC{$file} --- the fallback
138 # includes the Filename.pm, which is not useful. so we must add
139 # this crappy code. we don't worry about portable pathnames,
140 # as the old code didn't either.
141 (my $mdir = $self->{name}) =~ s{::}{/}g;
146 if ( -f \$_ . "/$mdir/Install/Files.pm") {
147 \$CORE = \$_ . "/$mdir/Install/";
153 print $file "\n1;\n";
157 # we need to ensure that the file we just created gets put into
158 # the install dir with everything else.
159 #$self->install ($filename);
160 $self->add_pm ($filename, $self->installed_filename ('Files.pm'));
165 my @pieces = split /::/, $dep;
166 my @suffix = qw/ Install Files /;
167 my $relpath = File::Spec->catfile (@pieces, @suffix) . '.pm';
168 my $depinstallfiles = join "::", @pieces, @suffix;
171 } or die " *** Can't load dependency information for $dep:\n $@\n";
173 #print Dumper(\%INC);
175 # effectively $instpath = dirname($INC{$relpath})
176 @pieces = File::Spec->splitdir ($INC{$relpath});
178 my $instpath = File::Spec->catdir (@pieces);
182 croak "No dependency information found for $dep"
185 if (not File::Spec->file_name_is_absolute ($instpath)) {
186 $instpath = File::Spec->rel2abs ($instpath);
190 File::Spec->rel2abs ($_, $instpath)
191 } @{"$depinstallfiles\::typemaps"};
194 instpath => $instpath,
195 typemaps => \@typemaps,
196 inc => "-I$instpath ".${"$depinstallfiles\::inc"},
197 libs => ${"$depinstallfiles\::libs"},
198 # this will not exist when loading files from old versions
199 # of ExtUtils::Depends.
200 (exists ${"$depinstallfiles\::"}{deps}
201 ? (deps => \@{"$depinstallfiles\::deps"})
208 my @load = grep { not $self->{deps}{$_} } keys %{ $self->{deps} };
209 foreach my $d (@load) {
211 $self->{deps}{$d} = $dep;
213 foreach my $childdep (@{ $dep->{deps} }) {
214 push @load, $childdep
216 $self->{deps}{$childdep}
218 grep {$_ eq $childdep} @load;
226 # we use a seen hash, but also keep indices to preserve
231 unless exists $seen{$_};
233 #warn "stripped ".(@_ - (keys %seen))." redundant elements\n";
234 sort { $seen{$a} <=> $seen{$b} } keys %seen;
238 sub get_makefile_vars {
241 # collect and uniquify things from the dependencies.
242 # first, ensure they are completely loaded.
245 ##my @defbits = map { split } @{ $self->{defines} };
246 my @incbits = map { split } @{ $self->{inc} };
247 my @libsbits = split /\s+/, $self->{libs};
248 my @typemaps = @{ $self->{typemaps} };
249 foreach my $d (keys %{ $self->{deps} }) {
250 my $dep = $self->{deps}{$d};
251 #push @defbits, @{ $dep->{defines} };
252 push @incbits, @{ $dep->{defines} } if $dep->{defines};
253 push @incbits, split /\s+/, $dep->{inc} if $dep->{inc};
254 push @libsbits, split /\s+/, $dep->{libs} if $dep->{libs};
255 push @typemaps, @{ $dep->{typemaps} } if $dep->{typemaps};
258 # we have a fair bit of work to do for the xs files...
262 foreach my $xs (@{ $self->{xs} }) {
263 (my $c = $xs) =~ s/\.xs$/\.c/i;
264 (my $o = $xs) =~ s/\.xs$/\$(OBJ_EXT)/i;
267 # according to the MakeMaker manpage, the C files listed in
268 # XS will be added automatically to the list of cleanfiles.
272 # we may have C files, as well:
273 foreach my $c (@{ $self->{c} }) {
274 (my $o = $c) =~ s/\.c$/\$(OBJ_EXT)/i;
280 INC => join (' ', uniquify @incbits),
281 LIBS => join (' ', uniquify $self->find_extra_libs, @libsbits),
282 TYPEMAPS => [@typemaps],
285 $self->build_dll_lib(\%vars) if $^O =~ /MSWin32/;
287 # we don't want to provide these if there is no data in them;
288 # that way, the caller can still get default behavior out of
289 # MakeMaker when INC, LIBS and TYPEMAPS are all that are required.
290 $vars{PM} = $self->{pm}
292 $vars{clean} = { FILES => join (" ", @clean), }
294 $vars{OBJECT} = join (" ", @OBJECT)
303 my ($self, $vars) = @_;
304 $vars->{macro} ||= {};
305 $vars->{macro}{'INST_DYNAMIC_LIB'} =
306 '$(INST_ARCHAUTODIR)/$(BASEEXT)$(LIB_EXT)';
309 sub find_extra_libs {
313 MSWin32 => sub { $_[0] . '\.(?:lib|a)' },
314 cygwin => sub { $_[0] . '\.dll'},
316 my $mapper = $mappers{$^O};
317 return () unless defined $mapper;
320 foreach my $name (keys %{ $self->{deps} }) {
321 (my $stem = $name) =~ s/^.*:://;
322 my $lib = $mapper->($stem);
323 my $pattern = qr/$lib$/;
328 if ((not $matching_file) && /$pattern/) {;
329 $matching_dir = $File::Find::dir;
330 $matching_file = $File::Find::name;
332 }, map { -d $_ ? ($_) : () } @INC); # only extant dirs
334 if ($matching_file && -f $matching_file) {
335 push @found_libs, ('-L' . $matching_dir, '-l' . $stem);
343 # Hook into ExtUtils::MakeMaker to create an import library on MSWin32 when gcc
344 # is used. FIXME: Ideally, this should be done in EU::MM itself.
345 package # wrap to fool the CPAN indexer
349 my $base = shift->SUPER::static_lib(@_);
351 return $base unless $^O =~ /MSWin32/ && $Config{cc} =~ /^gcc/i;
354 # This isn't actually a static lib, it just has the same name on Win32.
355 $(INST_DYNAMIC_LIB): $(INST_DYNAMIC)
356 dlltool --def $(EXPORT_LIST) --output-lib $@ --dllname $(BASEEXT).$(SO) $(INST_DYNAMIC)
358 dynamic:: $(INST_DYNAMIC_LIB)
368 ExtUtils::Depends - Easily build XS extensions that depend on XS extensions
372 use ExtUtils::Depends;
373 $package = new ExtUtils::Depends ('pkg::name', 'base::package')
374 # set the flags and libraries to compile and link the module
375 $package->set_inc("-I/opt/blahblah");
376 $package->set_libs("-lmylib");
377 # add a .c and an .xs file to compile
378 $package->add_c('code.c');
379 $package->add_xs('module-code.xs');
380 # add the typemaps to use
381 $package->add_typemaps("typemap");
382 # install some extra data files and headers
383 $package->install (qw/foo.h data.txt/);
385 $package->save_config('Files.pm');
388 'NAME' => 'Mymodule',
389 $package->get_makefile_vars()
394 This module tries to make it easy to build Perl extensions that use
395 functions and typemaps provided by other perl extensions. This means
396 that a perl extension is treated like a shared library that provides
397 also a C and an XS interface besides the perl one.
399 This works as long as the base extension is loaded with the RTLD_GLOBAL
400 flag (usually done with a
402 sub dl_load_flags {0x01}
404 in the main .pm file) if you need to use functions defined in the module.
406 The basic scheme of operation is to collect information about a module
407 in the instance, and then store that data in the Perl library where it
408 may be retrieved later. The object can also reformat this information
409 into the data structures required by ExtUtils::MakeMaker's WriteMakefile
412 When creating a new Depends object, you give it a name, which is the name
413 of the module you are building. You can also specify the names of modules
414 on which this module depends. These dependencies will be loaded
415 automatically, and their typemaps, header files, etc merged with your new
416 object's stuff. When you store the data for your object, the list of
417 dependencies are stored with it, so that another module depending on your
418 needn't know on exactly which modules yours depends.
424 Gnome2::Canvas depends on Gtk2
426 ExtUtils::Depends->new ('Gnome2::Canvas', 'Gtk2');
427 this command automatically brings in all the stuff needed
428 for Glib, since Gtk2 depends on it.
435 =item $object = ExtUtils::Depends->new($name, @deps)
437 Create a new depends object named I<$name>. Any modules listed in I<@deps>
438 (which may be empty) are added as dependencies and their dependency
439 information is loaded. An exception is raised if any dependency information
442 =item $depends->add_deps (@deps)
444 Add modules listed in I<@deps> as dependencies.
446 =item (hashes) = $depends->get_deps
448 Fetch information on the dependencies of I<$depends> as a hash of hashes,
449 which are dependency information indexed by module name. See C<load>.
451 =item $depends->set_inc (@newinc)
453 Add strings to the includes or cflags variables.
455 =item $depends->set_libs (@newlibs)
457 Add strings to the libs (linker flags) variable.
459 =item $depends->add_pm (%pm_files)
461 Add files to the hash to be passed through ExtUtils::WriteMakefile's
464 =item $depends->add_xs (@xs_files)
466 Add xs files to be compiled.
468 =item $depends->add_c (@c_files)
470 Add C files to be compiled.
472 =item $depends->add_typemaps (@typemaps)
474 Add typemap files to be used and installed.
476 =item $depends->add_headers (list)
478 No-op, for backward compatibility.
480 =item $depends->install (@files)
482 Install I<@files> to the data directory for I<$depends>.
484 This actually works by adding them to the hash of pm files that gets
485 passed through WriteMakefile's PM key.
487 =item $depends->save_config ($filename)
489 Save the important information from I<$depends> to I<$filename>, and
490 set it up to be installed as I<name>::Install::Files.
492 Note: the actual value of I<$filename> seems to be irrelevant, but its
493 usage is kept for backward compatibility.
495 =item hash = $depends->get_makefile_vars
497 Return the information in I<$depends> in a format digestible by
500 This sets at least the following keys:
507 And these if there is data to fill them:
513 =item hashref = ExtUtils::Depends::load (name)
515 Load and return dependency information for I<name>. Croaks if no such
516 information can be found. The information is returned as an anonymous
517 hash containing these keys:
523 The absolute path to the data install directory for this module.
527 List of absolute pathnames for this module's typemap files.
531 CFLAGS string for this module.
535 LIBS string for this module.
539 List of modules on which this one depends. This key will not exist when
540 loading files created by old versions of ExtUtils::Depends.
544 =item $depends->load_deps
546 Load I<$depends> dependencies, by calling C<load> on each dependency module.
547 This is usually done for you, and should only be needed if you want to call
548 C<get_deps> after calling C<add_deps> manually.
555 Version 0.2 discards some of the more esoteric features provided by the
556 older versions. As they were completely undocumented, and this module
557 has yet to reach 1.0, this may not exactly be a bug.
559 This module is tightly coupled to the ExtUtils::MakeMaker architecture.
567 Paolo Molaro <lupus at debian dot org> wrote the original version for
568 Gtk-Perl. muppet <scott at asofyet dot org> rewrote the innards for
569 version 0.2, borrowing liberally from Paolo's code.
573 The Gtk2 project, http://gtk2-perl.sf.net/
577 This library is free software; you may redistribute it and/or modify it
578 under the same terms as Perl itself.