Hello, I wrote 2 patches for Automake:
- 1) one for SWIG (Simplified Wrapper and Interface Generator, http://www.swig.org/) from a fork of LTLIBRARIES: sub handle_swig - 2) another for Cint, a C++ interpretor used mainly in particle physics research. I added 2 variables _SOURCES_CINT_DICT = _CINTFLAGS = The trick consist to complete automaticly _SOURCE with the sources generated by Cint from the definition of _SOURCES_CINT_DICT. It's look like Lex/Yacc, but with an horrible design ... for example, the implementation in LTLIBRARIES is: ... &handle_source_cint ($xname, $where); # complete _SOURCES before: my $linker = &handle_source_transform ($xname, $one_file, $obj, $where, NONLIBTOOL => 1, LIBTOOL => 0); ... As it was told in the mailing list, Automake can't support all minor development. Except if Automake is modularised. So, I wrote a short patch (look at the end of my mail) to add a simple hook system to Automake. The hook are located in the strategical place in the Automake source code. For example: Hook::Manager::instance->execute_hook ('handle_source', $xname, $where); The module are specified like this automake -m Foo.pm or with (to be implemented) AM_INIT_AUTOMAKE([Foo.pm]) The module are searched in the PERL5LIB env. Then, when the module is initialised, it add this callback like this: sub BEGIN { Hook::Manager::instance->register_hook ('handle_source', \&handle_source_cint); } I think this patch resolve simply and quickly the problem to create and maintain extension to Automake. It's probably possible to do a better design. But I'm not sure of this interest at short-term. The aim isn't to redesign the Autotools. But to add the possibility to maintain extension, now. cheers, Fabrice Salvaire ================= The hook patch: ================= --- automake-1.9.5-ref/automake.in 2005-02-12 11:06:56.000000000 +0100 +++ automake-1.9.5-dev/automake.in 2005-05-06 06:44:57.000000000 +0200 @@ -141,6 +141,7 @@ use Automake::Rule; use Automake::RuleDef; use Automake::Wrap 'makefile_wrap'; +use Automake::Hook; use File::Basename; use Carp; @@ -2264,6 +2265,8 @@ $where->push_context ("while processing program `$one_file'"); $where->set (INTERNAL->get); + Hook::Manager::instance->execute_hook ('handle_source', $xname, $where); + my $linker = &handle_source_transform ($xname, $one_file, $obj, $where, NONLIBTOOL => 1, LIBTOOL => 0); @@ -2581,6 +2595,7 @@ reject_var ("${xlib}_LDADD", "use `${xlib}_LIBADD', not `${xlib}_LDADD'"); + Hook::Manager::instance->execute_hook ('handle_source', $xlib, $where); my $linker = &handle_source_transform ($xlib, $onelib, $obj, $where, NONLIBTOOL => 0, LIBTOOL => 1); @@ -6374,6 +6389,27 @@ # $CONTENTS +# &find_am_file ($BASENAME) +# ------------------------------------------------ +# +# +sub find_am_file ($) +{ + my ($basename) = @_; + + foreach my $dir (@libdir) + { + my $file = "$dir/am/$basename.am"; + + return $file if (-e $file); + } + + # error + die "file am/$basename.am not found in @libdir\n"; +} + + +# $CONTENTS # &file_contents ($BASENAME, $WHERE, [%TRANSFORM]) # ------------------------------------------------ # Return contents of a file from $libdir/am, automatically skipping @@ -6381,8 +6417,9 @@ sub file_contents ($$%) { my ($basename, $where, %transform) = @_; + my ($comments, $variables, $rules) = - file_contents_internal (1, "$libdir/am/$basename.am", $where, + file_contents_internal (1, find_am_file ($basename), $where, %transform); return "$comments$variables$rules"; } @@ -7151,6 +7188,7 @@ handle_gettext; handle_libraries; handle_ltlibraries; + Hook::Manager::instance->execute_hook ('handle_libraries'); handle_programs; handle_scripts; @@ -7396,6 +7434,7 @@ # compatibility. Use -Werror and -Wno-error today. 'Werror' => sub { parse_warnings 'W', 'error'; }, 'Wno-error' => sub { parse_warnings 'W', 'no-error'; }, + 'm|module:s' => sub { Hook::Manager::instance->push_module ($_[1]) }, ); use Getopt::Long; Getopt::Long::config ("bundling", "pass_through"); @@ -7471,6 +7510,9 @@ $configure_ac = require_configure_ac; +# Init the hook manager +Hook::Manager::instance->init (); + # Do configure.ac scan only once. scan_autoconf_files; --- automake-1.9.5-ref/lib/Automake/Hook.pm 1970-01-01 01:00:00.000000000 +0100 +++ automake-1.9.5-dev/lib/Automake/Hook.pm 2005-05-06 06:39:30.000000000 +0200 @@ -0,0 +1,86 @@ +package Hook::Manager; + +use 5.005; +use warnings; +use strict; + +use File::Basename; + +our $instance; + +sub instance +{ + $instance = new Hook::Manager unless ($instance); + + return $instance; +} + +sub new +{ + my $invocant = shift; + my $class = ref ($invocant) || $invocant; + + my $obj = bless ({}, $class); + + $obj->{modules} = []; + + $obj->{hooks} = {}; + + return $obj; +} + +sub push_module +{ + my ($obj, @module) = @_; + + my $module_list = $obj->{modules}; + + push @$module_list, @module; +} + +sub init +{ + my $obj = shift; + + my $module_list = $obj->{modules}; + + foreach my $module (@$module_list) + { + require $module; # error ? + + my ($name, $path, $suffix) = fileparse ($module, '.am'); + + push @Automake::libdir, $path; + + $module::libdir = $path; + } +} + +sub register_hook #($$&) +{ + my ($obj, $name, $callback) = @_; + + push @{$obj->{hooks}{$name}}, $callback; + + print STDERR "Register Hook $name\n"; +} + +sub execute_hook +{ + my $obj = shift; + my $name = shift; + + if (my $hook_list = $obj->{hooks}{$name}) + { + foreach my $callback (@$hook_list) + { + &$callback (@_); + } + } +} + +1;