Here is a patch that allows projects using sources derived using suffix rules (corba, esql, whatever...) to be built in parallel. The initial discussion which lead to this patch is available from the list archives ( try http://sourceware.cygnus.com/ml/automake/2000-03/msg00112.html ). I basically followed this advice and produced a per exec/lib hook if there are any derived sources to be generated. I've tested it on my ACE/TAO based CORBA project and it works well for me (my project builds around 40-50% faster on a dual processor box). Please try it out. The patch is against cvs using cvs diff -u. Regards, Alex. Index: ChangeLog =================================================================== RCS file: /cvs/automake/automake/ChangeLog,v retrieving revision 1.872 diff -u -r1.872 ChangeLog --- ChangeLog 2000/06/02 23:27:02 1.872 +++ ChangeLog 2000/06/19 14:53:46 @@ -1,3 +1,27 @@ +2000-06-19 Alex Hornby <[EMAIL PROTECTED]> + + * automake.in (handle_source_transform): Added support for per + target built source detection using suffix rules. This allows + projects with built sources to build with make -j without prior + dependency computation. + (read_am_file) : Improved suffix rule matching to find rules not + split on period. This uses match_suffixes_to_rule to do the actual + work. + (match_suffixes_to_rule): new function + (%reverse_suffix_rules): new global, holds object to source + mappings + (longest_suffix): new function, finds longest suffix rule matching + a source file. + (previous_suffix): new function, finds suffix of file that + generated this one, if any. + + * library.am (XBUILTSOURCEHOOK): new variable, added to support for per + target built sources + + * ltlibrary.am: likewise + + * program.am: likewise + 2000-06-02 Morten Eriksen <[EMAIL PROTECTED]> * depcomp: workaround for problem with SGI IRIX sed (it can only Index: automake.in =================================================================== RCS file: /cvs/automake/automake/automake.in,v retrieving revision 1.786 diff -u -r1.786 automake.in --- automake.in 2000/05/12 00:02:29 1.786 +++ automake.in 2000/06/19 14:53:53 @@ -1477,6 +1477,22 @@ $linker = $temp if $linker eq ''; &define_pretty_variable ($xpfx . $one_file . "_OBJECTS", '', @result) unless $prefix =~ /EXTRA_/; + + local ($bs, @builtsources); + foreach $bs ( @files ) + { + local ($sf) = longest_suffix($bs); + if ( $sf ne '' && previous_suffix($sf) ne $sf ) + { + print "$bs identified as a built source\n" if $verbose; + push @builtsources, $bs; + } + } + if ( scalar @builtsources != 0) + { + &define_pretty_variable ($one_file . "_BUILTSOURCES", '', + @builtsources); + } } local (@keys) = sort keys %used_pfx; @@ -1492,7 +1508,7 @@ $one_file, $obj, @files); $linker = $temp if $linker eq ''; - &define_pretty_variable ($one_file . "_OBJECTS", '', @result) + &define_pretty_variable ($one_file . "_OBJECTS", '', @result); } else { @@ -1794,11 +1810,18 @@ $xexe = 's/\@EXEEXT\@//g;'; } + local ($xbuilthook) = ''; + if (&variable_defined($xname . '_BUILTSOURCES') ) + { + $xbuilthook = "\t" . '\$(MAKE) \$(' . $xname . '_BUILTSOURCES)'; + } + $output_rules .= &file_contents_with_transform ('s/\@PROGRAM\@/' . $one_file . '/go;' . 's/\@XPROGRAM\@/' . $xname . '/go;' . 's/\@XLINK\@/' . $xlink . '/go;' + . 's/\@XBUILTSOURCEHOOK\@/' . $xbuilthook . '/go;' . $xexe, 'program'); } @@ -1905,10 +1928,18 @@ &handle_source_transform ($xlib, $onelib, $obj); + local ($xbuilthook) = ''; + if (&variable_defined($xlib . '_BUILTSOURCES') ) + { + $xbuilthook = "\t" . '\$(MAKE) \$(' . $xlib . '_BUILTSOURCES)'; + } + $output_rules .= &file_contents_with_transform ('s/\@LIBRARY\@/' . $onelib . '/go;' . 's/\@XLIBRARY\@/' - . $xlib . '/go;', + . $xlib . '/go;' + . 's/\@XBUILTSOURCEHOOK\@/' . + $xbuilthook . '/go;', 'library'); } @@ -2058,13 +2089,21 @@ . 'dir)/go;'); } + local ($xbuilthook) = ''; + if (&variable_defined($xlib . '_BUILTSOURCES') ) + { + $xbuilthook = "\t" . '\$(MAKE) \$(' . $xlib . '_BUILTSOURCES)'; + } + $output_rules .= &file_contents_with_transform ('s/\@LTLIBRARY\@/' . $onelib . '/go;' . 's/\@XLTLIBRARY\@/' . $xlib . '/go;' . $rpath - . 's/\@XLINK\@/' . $xlink . '/go;', + . 's/\@XLINK\@/' . $xlink . '/go;' + . 's/\@XBUILTSOURCEHOOK\@/' . + $xbuilthook . '/go;', 'ltlibrary'); } @@ -5316,6 +5355,80 @@ } } +# Finds longest initial suffix, then longest trailing for that intial +sub match_suffixes_to_rule +{ + local ($rule) = @_; + local @result = (); + + local $s = ''; + local @sufbylen = (); + + # Gather all know suffixes + if ( variable_defined("SUFFIXES") ) + { + @sufbylen = sort { length($b)<=>length($a) } + ( @suffixes, &variable_value_as_list ('SUFFIXES', '') ); + } + else + { + @sufbylen = sort { length($b)<=>length($a) }( @suffixes); + } + + # Match longest source suffix + foreach $s ( @sufbylen ) + { + if ( $rule =~ m/^$s/ ) + { + $result[0] = $s; + last; + } + } + # Match longest target suffix + foreach $s ( @sufbylen ) + { + if ( $rule =~ m/${result[0]}${s}$/ ) + { + $result[1] = $s; + last; + } + } + + return @result; +} + +# This function takes a source file name and return the longest suffix that +# matches +sub longest_suffix +{ + local ($filename) = @_; + local ($longest_suffix) = ''; + local ($suf); + foreach $suf ( keys %reverse_suffix_rules ) + { + if ( length($suf) > length($longest_suffix) && + $filename =~ m/${suf}$/ ) + { + $longest_suffix = $suf; + } + } + return $longest_suffix; +} + +# This function gives the suffix this suffix was generated from +# In the case of normal static source files, it will always return +# the same as the input +sub previous_suffix +{ + local ($source_ext) = @_; + while ( defined $reverse_suffix_rules{$source_ext}) + { + $source_ext = $reverse_suffix_rules{$source_ext}; + } + return $source_ext; +} + + # This function is used to find a path from a user-specified suffix to # `o' or to some other suffix we recognize internally, eg `cc'. sub derive_suffix @@ -6242,13 +6355,15 @@ # Check the rule for being a suffix rule. If so, store in # a hash. - local ($source_suffix); - local ($object_suffix); - - if (($source_suffix, $object_suffix) = ($1 =~ $SUFFIX_RULE_PATTERN)) + local ($source_suffix) = ''; + local ($object_suffix) = ''; + + ($source_suffix, $object_suffix) = match_suffixes_to_rule($1); + if ($source_suffix ne '' && $object_suffix ne '') { $suffix_rules{$source_suffix} = $object_suffix; - print "Sources ending in .$source_suffix become .$object_suffix\n" if $verbose; + $reverse_suffix_rules{$object_suffix} = $source_suffix; + print "Sources ending in $source_suffix become $object_suffix\n" if +$verbose; $source_suffix_pattern = "(" . join ('|', keys %suffix_rules) . ")"; } @@ -6842,6 +6957,9 @@ # corresponding output extension. %suffix_rules = (); + # Reverse mapping of suffix rules. Used for detecting built sources + %reverse_suffix_rules = (); + # This is a regular expression which matches all the known source # suffix. A source suffix is one that appears in the first # position of a suffix rule. @@ -6975,6 +7093,7 @@ } close (FC_FILE); + return $result_vars . $result_rules . $comment; } Index: library.am =================================================================== RCS file: /cvs/automake/automake/library.am,v retrieving revision 1.11 diff -u -r1.11 library.am --- library.am 1999/05/04 12:32:36 1.11 +++ library.am 2000/06/19 14:53:53 @@ -16,6 +16,8 @@ ## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA ## 02111-1307, USA. @LIBRARY@: $(@XLIBRARY@_OBJECTS) $(@XLIBRARY@_DEPENDENCIES) +## Per target built sources may be specified +@XBUILTSOURCEHOOK@ -rm -f @LIBRARY@ $(@XLIBRARY@_AR) @LIBRARY@ $(@XLIBRARY@_OBJECTS) $(@XLIBRARY@_LIBADD) $(RANLIB) @LIBRARY@ Index: ltlibrary.am =================================================================== RCS file: /cvs/automake/automake/ltlibrary.am,v retrieving revision 1.2 diff -u -r1.2 ltlibrary.am --- ltlibrary.am 1997/04/04 02:21:13 1.2 +++ ltlibrary.am 2000/06/19 14:53:53 @@ -16,4 +16,6 @@ ## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA ## 02111-1307, USA. @LTLIBRARY@: $(@XLTLIBRARY@_OBJECTS) $(@XLTLIBRARY@_DEPENDENCIES) +## Per target built sources may be specified +@XBUILTSOURCEHOOK@ $(@XLINK@) @RPATH@ $(@XLTLIBRARY@_LDFLAGS) $(@XLTLIBRARY@_OBJECTS) $(@XLTLIBRARY@_LIBADD) $(LIBS) Index: program.am =================================================================== RCS file: /cvs/automake/automake/program.am,v retrieving revision 1.17 diff -u -r1.17 program.am --- program.am 1997/08/25 23:25:05 1.17 +++ program.am 2000/06/19 14:53:53 @@ -16,6 +16,8 @@ ## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA ## 02111-1307, USA. @PROGRAM@@EXEEXT@: $(@XPROGRAM@_OBJECTS) $(@XPROGRAM@_DEPENDENCIES) +## Per target built sources may be specified +@XBUILTSOURCEHOOK@ ## Remove program before linking. Otherwise the link will fail if the ## program is running somewhere. FIXME: this could be a loss if ## you're using an incremental linker. Maybe we should think twice?
