From: Stefano Lattarini Date: Sat, 26 May 2012 09:39:29 +0000 (+0200) Subject: [ng] suffix: drop Automake-time chaining of suffix rules X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=645bb2101df2040ebedb65341cc786704c56f194;p=thirdparty%2Fautomake.git [ng] suffix: drop Automake-time chaining of suffix rules This change simplifies the Automake::Rule module a little, moves yet more logic from Automake runtime to GNU make runtime (in the spirit of Automake-NG), and gets us rid of some never-documented nor completely specified Automake magics. OTOH, it also breaks some idioms that, while only relevant for uncommon cases, have been working since the first Automake releases. Still, it is easy to slightly modify those idioms to have the use cases they were catering to correctly handled with the new semantics (examples of this are given below); the only downside being the need of a little more verbosity and explicitness on the user's part. So, with the present change, automake starts using a much simpler and dumber algorithm to determine how to build an object associated to a source whose extension in not one of those it handles internally. The new algorithm goes like this. For any file listed in a '_SOURCES' variable whose suffix is not recognized internally by automake (in contrast to known suffixes like '.c' or '.f90'), automake will obtain the expected target object file by stripping the suffix from the source file, and appending either '.$(OBJEXT)' or '.lo' to it (which one depends on whether the object is built as part of a program, a static library, or a libtool library). It will then be assumed (but not checked!) that the user has defined a rule (either explicit or defined from a pattern rule) which can turn that source file into this corresponding object file. For example, on an input like: bin_PROGRAMS = foo foo_SOURCES = mu.ext1 fu.ext1 zu.ext1 automake will expect that the three objects 'mu.$(OBJEXT)', 'fu.$(OBJEXT)' and 'zu.$(OBJEXT)' are to be used in the linking of the 'foo' program, and that the user has provided proper recipes for all those objects to be built at make time, as well as a link command for linking 'foo'. Here is an example of how those declarations could look like: %.$(OBJEXT): %.ext1 my-compiler -c -o $@ $< # We need to compile mu with debugging enabled. mu.$(OBJEXT): mu.ext1 my-compiler -DDEBUG=1 -c -o $@ $< foo_LINK = $(CC) -o $@ In this particular case, the idiom above is basically the same one that would be required in mainline automake (apart for the fact that, there, old-fashioned suffix rules should be used instead of pattern rules). To see what is truly changed with the new algorithm, we have to look at a more indirect usage. Mainline Automake follows the chain of user-defined pattern rules to determine how to build the object file deriving from a source file with a custom user extension; for example, upon reading: %.cc: %.zoo: $(preprocess) $< > $@ bin_PROGRAMS = foo foo_SOURCES = bar.zoo automake knew that it has to bring in the C++ support (compilation rules, requirement for AC_PROG_CXX in configure.ac, etc), and use the C++ linker to link the 'foo' executable. But after the present change, automake *won't follow those implicit chains of pattern rules* anymore; so that the idiom above will have to be re-worked like follows to preserve its intent and behaviour: %.cc: %.zoo: $(preprocess) $< > $@ bin_PROGRAMS = foo # The use of '.cc' is required to let Automake know to bring in # stuff for the handling of C++ compilation, and to use the C++ # linker to build 'foo'. nodist_foo_SOURCES = bar.cc EXTRA_DIST = foo.zoo Finally, we must note another, slightly annoying first consequence of this change of semantics: one can't use anymore "header files" with extensions unrecognized to Automake anymore; for example, an usage like this: # Won't work anymore: will cause errors at make runtime. %.h: %.my-hdr $(preprocess-header) $< >$@ foo_SOURCES = foo.c bar.my-hdr BUILT_SOURCES = bar.h will cause the generated Makefile to die on "make all", with an error like: make[1]: *** No rule to make target 'bar.o', needed by 'zardoz'. Stop. while an usage like this: # Won't work anymore: will cause errors at automake runtime. %.h: %.my-hdr $(preprocess-header) $< >$@ foo_SOURCES = foo.c foo.my-hdr BUILT_SOURCES = foo.h will cause automake itself to die, reporting an error like: object 'foo.$(OBJEXT)' created by 'foo.my-hdr' and 'foo.c' We don't believe the above breakage is a real issue though, because the use case can still be served by placing the "non standard" headers in EXTRA_DIST rather than in a _SOURCES variable: # This will work. %.h: %.my-hdr $(preprocess-header) $< >$@ foo_SOURCES = foo.c EXTRA_DIST = foo.my-hdr BUILT_SOURCES = foo.h A more detailed list of changes follow ... * automake.in (register_language): Don't call 'register_suffix_rule' on the source and object extensions of the registered languages. (handle_single_transform): Implement the new simple algorithm described in details above (plus an hack to continue supporting Vala-related '.vapi' files in _SOURCES variables). Remove the only call ever to ... (derive_suffix): ... this function, which has thus been removed. * lib/Automake/Rule.pm ($_suffix_rules_default, $suffix_rules, register_suffix_rule): Remove. (@EXPORT, reset): Adjust. (define): Don't call 'register_suffix_rule' on the suffixes of target and dependency when a pattern rule is seen. * t/specflg10.sh: Move ... * t/am-default-source-ext.sh: ... to this more proper name, and adjusted. * t/suffix12.sh: Renamed ... * t/suffix-custom-subobj.sh: ... to this, and remove a botched heading comment. * t/suffix3.sh: Adjust. * t/suffix5.sh: Likewise. * t/suffix8.sh: Likewise. * t/suffix10.sh: Likewise. * t/suffix13.sh: Likewise. * t/suffix-chain.sh: Likewise. * t/suffix-hdr.sh: Likewise. * t/suffix-custom.sh: New test. * t/suffix-custom-link.sh: Likewise. * t/suffix-custom-default-ext.sh: Likewise. * t/yacc-lex-cxx-alone.sh: Likewise. * NG-NEWS: Update. Signed-off-by: Stefano Lattarini --- diff --git a/NG-NEWS b/NG-NEWS index 216c95bba..c464ea305 100644 --- a/NG-NEWS +++ b/NG-NEWS @@ -177,26 +177,6 @@ Pattern rules and suffix rules not supported anymore either; Automake-NG will error out if you try to define them. -* To retain support for user-defined file extensions in the '_SOURCES' - variables (see "Handling new file extensions" in the Automake manual), - Automake-NG still tries to parse and understand suffix-based pattern - rules. So, an usage like: - - SUFFIXES = .baz .c - .baz.c: - cp $< $@ - foo_SOURCES = foo.c bar.baz - DISTCLEANFILES = bar.c - - which was valid with mainline Automake, should be translated for - Automake-NG as: - - %.c: %.baz - cp $< $@ - bin_PROGRAMS = foo - foo_SOURCES = foo.c sub/bar.baz - DISTCLEANFILES = bar.c - Distribution ============ @@ -257,6 +237,95 @@ Obsolete Features Removed a long time. +Source Files with Unknown Extensions +==================================== + +* Automake-NG used a much simpler and dumber algorithm that mainline + Automake to determine how to build an object associated to a source + whose extension in not one of those handled internally by automake. + + The new algorithm goes like this. For any file listed in a '_SOURCES' + variable whose suffix is not recognized internally by automake (in + contrast to known suffixes like '.c' or '.f90'), automake will obtain + the expected target object file by stripping the suffix from the source + file, and appending either '.$(OBJEXT)' or '.lo' to it (which one depends + on whether the object is built as part of a program, a static library, or + a libtool library). It will then be assumed that the user has defined a + rule (either explicit or defined from a pattern rule) which can turn that + source file into this corresponding object file. For example, on an + input like: + + bin_PROGRAMS = foo + foo_SOURCES = mu.ext1 fu.ext1 zu.ext1 + + automake will expect that the three objects mu.$(OBJEXT), fu.$(OBJEXT) + and zu.$(OBJEXT) are to be used in the linking of the 'foo' program, and + that the user has provided proper recipes for all those objects to be + built at make time, as well as a link command for linking 'foo'. Here + is an example of how those declarations could look like: + + %.$(OBJEXT): %.ext1 + my-compiler -c -o $@ $< + foo_LINK = $(CC) -o $@ + + In this particular case, the idiom above is basically the same one that + would be required in mainline automake (apart for the fact that, there, + old-fashioned suffix rules should be used instead of pattern rules). To + see what is truly changed with the new algorithm, we have to look at a + more indirect usage. + + Mainline Automake follows the chain of user-defined pattern rules to + determine how to build the object file deriving from a source file with + a custom user extension; for example, upon reading: + + .zoo.cc: + $(preprocess) $< > $@ + bin_PROGRAMS = foo + foo_SOURCES = bar.zoo + + *mainline* Automake knows that it has to bring in the C++ support + (compilation rules, requirement for AC_PROG_CXX in configure.ac, etc), + and use the C++ linker to link the 'foo' executable. + + But Autommake-NG *won't follow those implicit chains of pattern rules* + anymore; so that the idiom above will have to be re-worked like follows + to preserve its intent and behaviour: + + %.cc: %.zoo: + $(preprocess) $< > $@ + bin_PROGRAMS = foo + # The use of '.cc' is required to let Automake know to bring in + # stuff for the handling of C++ compilation, and to use the C++ + # linker to build 'foo'. + nodist_foo_SOURCES = bar.cc + EXTRA_DIST = foo.zoo + + And there is another major consequence of this change of semantics: one + can't use anymore "header files" with extensions unrecognized to Automake + anymore; for example, an usage like this will cause errors at make + runtime: + + # Won't work anymore. + %.h: %.my-hdr + $(preprocess-header) $< >$@ + foo_SOURCES = foo.c bar.my-hdr + BUILT_SOURCES = bar.h + + errors that might look like: + + make[1]: *** No rule to make target 'bar.o', needed by 'zardoz'. Stop. + + The simple workaround is to place the "non-standard" headers in EXTRA_DIST + rather than in a _SOURCES variable: + + # This will work. + %.h: %.my-hdr + $(preprocess-header) $< >$@ + foo_SOURCES = foo.c + EXTRA_DIST = foo.my-hdr + BUILT_SOURCES = foo.h + + Miscellaneous ============= diff --git a/automake.in b/automake.in index eeafd295b..0bb68298f 100644 --- a/automake.in +++ b/automake.in @@ -1667,7 +1667,6 @@ sub handle_single_transform ($$$$$%) # language function. my $aggregate = 'AM'; - $extension = &derive_suffix ($extension, $obj); my $lang; if ($extension_map{$extension} && ($lang = $languages{$extension_map{$extension}})) @@ -1815,24 +1814,26 @@ sub handle_single_transform ($$$$$%) [@specifics, %transform]); } } - elsif ($extension eq $obj) + elsif ($extension eq '.vapi') + { + # Explicitly pass vala headers through. This is a bit of an + # hack, but good enough FTM. + next; + } + else { + # Assume the user has defined a proper explicit or pattern + # rule to turn a source file with this extension in an object + # file with the same basename and a '.$(OBJEXT)' extension (if + # build as part of a program or static library) or a '.lo' + # extension (if built as part of a libtool library). + $extension = $obj; # This is probably the result of a direct suffix rule. # In this case we just accept the rewrite. $object = "$base$extension"; $object = "$directory/$object" if $directory ne ''; $linker = ''; } - else - { - # No error message here. Used to have one, but it was - # very unpopular. - # FIXME: we could potentially do more processing here, - # perhaps treating the new extension as though it were a - # new source extension (as above). This would require - # more restructuring than is appropriate right now. - next; - } err_am "object '$object' created by '$full' and '$object_map{$object}'" if (defined $object_map{$object} @@ -5718,34 +5719,6 @@ sub register_language (%) $link_languages{$link} = $lang; } } - - # Upate the $suffix_rule map. - foreach my $suffix (@{$lang->extensions}) - { - foreach my $dest (&{$lang->output_extensions} ($suffix)) - { - register_suffix_rule (INTERNAL, $suffix, $dest); - } - } -} - -# derive_suffix ($EXT, $OBJ) -# -------------------------- -# This function is used to find a path from a user-specified suffix $EXT -# to $OBJ or to some other suffix we recognize internally, e.g. 'cc'. -sub derive_suffix ($$) -{ - my ($source_ext, $obj) = @_; - - while (! $extension_map{$source_ext} - && $source_ext ne $obj - && exists $suffix_rules->{$source_ext} - && exists $suffix_rules->{$source_ext}{$obj}) - { - $source_ext = $suffix_rules->{$source_ext}{$obj}[0]; - } - - return $source_ext; } diff --git a/lib/Automake/Rule.pm b/lib/Automake/Rule.pm index 24066235c..d6c73e7e4 100644 --- a/lib/Automake/Rule.pm +++ b/lib/Automake/Rule.pm @@ -29,8 +29,7 @@ use Automake::DisjConditions; require Exporter; use vars '@ISA', '@EXPORT', '@EXPORT_OK'; @ISA = qw/Automake::Item Exporter/; -@EXPORT = qw (reset register_suffix_rule - rules $suffix_rules +@EXPORT = qw (reset rules depend %dependencies %actions register_action reject_rule msg_rule msg_cond_rule err_rule err_cond_rule rule rrule ruledef rruledef); @@ -94,10 +93,6 @@ non-object). =cut -# Same as $suffix_rules (declared below), but records only the -# default rules supplied by the languages Automake supports. -use vars '$_suffix_rules_default'; - =item C<%dependencies> Holds the dependencies of targets which dependencies are factored. @@ -119,36 +114,6 @@ only when keys exists in C<%dependencies>. use vars '%actions'; -=item <$suffix_rules> - -This maps the source extension for all suffix rules seen to -a C whose keys are the possible output extensions. - -Note that this is transitively closed by construction: -if we have - exists $suffix_rules{$ext1}{$ext2} - && exists $suffix_rules{$ext2}{$ext3} -then we also have - exists $suffix_rules{$ext1}{$ext3} - -So it's easy to check whether C<.foo> can be transformed to -C<.$(OBJEXT)> by checking whether -C<$suffix_rules{'.foo'}{'.$(OBJEXT)'}> exists. This will work even if -transforming C<.foo> to C<.$(OBJEXT)> involves a chain of several -suffix rules. - -The value of C<$suffix_rules{$ext1}{$ext2}> is a pair -C<[ $next_sfx, $dist ]> where C<$next_sfx> is target suffix -for the next rule to use to reach C<$ext2>, and C<$dist> the -distance to C<$ext2'>. - -The content of this variable should be updated via the -C function. - -=cut - -use vars '$suffix_rules'; - =back =head2 Error reporting functions @@ -280,16 +245,6 @@ other internal data. sub reset() { %_rule_dict = (); - # The first time we initialize the variables, - # we save the value of $suffix_rules. - if (defined $_suffix_rules_default) - { - $suffix_rules = $_suffix_rules_default; - } - else - { - $_suffix_rules_default = $suffix_rules; - } %dependencies = ( @@ -345,85 +300,6 @@ sub reset() %actions = (); } -=item C - -Register a suffix-based pattern rule defined on C<$where> that -transforms files ending in C<$src> into files ending in C<$dest>. - -This upgrades the C<$suffix_rules> variables. - -=cut - -sub register_suffix_rule ($$$) -{ - my ($where, $src, $dest) = @_; - - verb "Sources ending in $src become $dest"; - - # When transforming sources to objects, Automake uses the - # %suffix_rules to move from each source extension to - # '.$(OBJEXT)', not to '.o' or '.obj'. However some people - # define suffix rules for '.o' or '.obj', so internally we will - # consider these extensions equivalent to '.$(OBJEXT)'. We - # CANNOT rewrite the target (i.e., automagically replace '.o' - # and '.obj' by '.$(OBJEXT)' in the output), or warn the user - # that (s)he'd better use '.$(OBJEXT)', because Automake itself - # output suffix rules for '.o' or '.obj' ... - $dest = '.$(OBJEXT)' if ($dest eq '.o' || $dest eq '.obj'); - - # Reading the comments near the declaration of $suffix_rules might - # help to understand the update of $suffix_rules that follows ... - - # Register $dest as a possible destination from $src. - # We might have the create the \hash. - if (exists $suffix_rules->{$src}) - { - $suffix_rules->{$src}{$dest} = [ $dest, 1 ]; - } - else - { - $suffix_rules->{$src} = { $dest => [ $dest, 1 ] }; - } - - # If we know how to transform $dest in something else, then - # we know how to transform $src in that "something else". - if (exists $suffix_rules->{$dest}) - { - for my $dest2 (keys %{$suffix_rules->{$dest}}) - { - my $dist = $suffix_rules->{$dest}{$dest2}[1] + 1; - # Overwrite an existing $src->$dest2 path only if - # the path via $dest which is shorter. - if (! exists $suffix_rules->{$src}{$dest2} - || $suffix_rules->{$src}{$dest2}[1] > $dist) - { - $suffix_rules->{$src}{$dest2} = [ $dest, $dist ]; - } - } - } - - # Similarly, any extension that can be derived into $src - # can be derived into the same extensions as $src can. - my @dest2 = keys %{$suffix_rules->{$src}}; - for my $src2 (keys %$suffix_rules) - { - if (exists $suffix_rules->{$src2}{$src}) - { - for my $dest2 (@dest2) - { - my $dist = $suffix_rules->{$src}{$dest2} + 1; - # Overwrite an existing $src2->$dest2 path only if - # the path via $src is shorter. - if (! exists $suffix_rules->{$src2}{$dest2} - || $suffix_rules->{$src2}{$dest2}[1] > $dist) - { - $suffix_rules->{$src2}{$dest2} = [ $src, $dist ]; - } - } - } - } -} - =item C Return the C object for the rule @@ -751,21 +627,10 @@ sub define ($$$$$;$) my $chars_rx = '[a-zA-Z0-9_(){}$+@\-]+'; my $suffix_rule_rx = "^(\\.$chars_rx+)(\\.$chars_rx+)(?:\\s|\$)"; - my $pattern_rx ="^%(\\.$chars_rx+)"; - # Let's see if the rule is a suffix-based pattern rule we can handle. - if ($target =~ /^%(\.$chars_rx)$/o) - { - my $objsuf = $1; - if ($deps =~ /^\s*%(\.$chars_rx)(\s|$)/o) - { - my $srcsuf = $1; - register_suffix_rule ($where, $srcsuf, $objsuf); - } - } # We don't support old-fashioned suffix rules anymore, but want to # report them as errors. - elsif ($target =~ /$suffix_rule_rx/o) + if ($target =~ /$suffix_rule_rx/o) { error $where, "use pattern rules, not old-fashioned suffix rules"; } diff --git a/t/specflg10.sh b/t/am-default-source-ext.sh similarity index 78% rename from t/specflg10.sh rename to t/am-default-source-ext.sh index 6af4d28ef..d3ab899e6 100755 --- a/t/specflg10.sh +++ b/t/am-default-source-ext.sh @@ -42,29 +42,41 @@ END cat > sub2/Makefile.am << 'END' bin_PROGRAMS = bla if COND -AM_DEFAULT_SOURCE_EXT = .foo .quux +AM_DEFAULT_SOURCE_EXT = .c .quux endif %.c: %.foo cat $< >$@ -BUILT_SOURCES = bla.c -CLEANFILES = bla.c +EXTRA_DIST = $(addsuffix .foo,$(bin_PROGRAMS)) +CLEANFILES = $(addsuffix .c,$(bin_PROGRAMS)) END cat > foo.c << 'END' -int main (void) { return 0; } +/* Valid C, invalid C++. */ +int main (void) +{ + int new = 0; + return new; +} END - -cp foo.c sub/bar.cpp -cp foo.c sub/baz.cpp cp foo.c sub2/bla.foo +cat > sub/bar.cpp << 'END' +/* Valid C++, invalid C. */ +using namespace std; +int main (void) +{ + return 0; +} +END +cp sub/bar.cpp sub/baz.cpp + $ACLOCAL $AUTOCONF # Conditional AM_DEFAULT_SOURCE_EXT does not work yet :-( # (this limitation could be lifted). AUTOMAKE_fails --add-missing -grep 'defined conditionally' stderr +grep 'AM_DEFAULT_SOURCE_EXT.*defined conditionally' stderr sed '/^if/d; /^endif/d' sub2/Makefile.am > t mv -f t sub2/Makefile.am @@ -72,7 +84,7 @@ mv -f t sub2/Makefile.am # AM_DEFAULT_SOURCE_EXT can only assume one value # (lifting this limitation is not such a good idea). AUTOMAKE_fails --add-missing -grep 'at most one value' stderr +grep 'AM_DEFAULT_SOURCE_EXT.*at most one value' stderr sed 's/ \.quux//' sub2/Makefile.am > t mv -f t sub2/Makefile.am diff --git a/t/suffix-chain.sh b/t/suffix-chain.sh index 2ff72f955..e1f96b2f6 100755 --- a/t/suffix-chain.sh +++ b/t/suffix-chain.sh @@ -28,7 +28,8 @@ END cat > Makefile.am <<'END' bin_PROGRAMS = foo -foo_SOURCES = foo.c1 +nodist_foo_SOURCES = foo.c +EXTRA_DIST = foo.c0 %.c0: %.c1 (echo 'int main (void)' && echo '{' && cat $<) > $@ %.c: %.c0 diff --git a/t/suffix-custom-default-ext.sh b/t/suffix-custom-default-ext.sh new file mode 100755 index 000000000..0bc729524 --- /dev/null +++ b/t/suffix-custom-default-ext.sh @@ -0,0 +1,70 @@ +#! /bin/sh +# Copyright (C) 2002-2012 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Interaction between user-defined extensions for files in _SOURCES +# and the use of AM_DEFAULT_SOURCE_EXT. + +required=c++ +. ./defs || Exit 1 + +cat >> configure.ac <<'END' +AC_PROG_CXX +AC_OUTPUT +END + +cat > Makefile.am <<'END' +AM_DEFAULT_SOURCE_EXT = .cc +bin_PROGRAMS = foo bar baz qux +%.cc: %.zoo + sed 's/INTEGER/int/g' $< >$@ +EXTRA_DIST = $(addsuffix .zoo,$(bin_PROGRAMS)) +generated_cc_sources = $(addsuffix .cc,$(bin_PROGRAMS)) +CLEANFILES = $(generated_cc_sources) +# We don't want the generated C++ files to be distributed, and this +# is the best workaround we've found so far. Not very clean, but it +# works. +dist-hook: + rm -f $(addprefix $(distdir)/,$(generated_cc_sources)) +END + +# This is deliberately valid C++, but invalid C. +cat > foo.zoo <<'END' +using namespace std; +INTEGER main (void) +{ + return 0; +} +END +cp foo.zoo bar.zoo +cp foo.zoo baz.zoo +cp foo.zoo qux.zoo + +$ACLOCAL +$AUTOMAKE +$AUTOCONF + +./configure + +$MAKE all +$MAKE distdir +ls -l $distdir +test ! -f $distdir/foo.cc +test ! -f $distdir/bar.cc +test ! -f $distdir/baz.cc +test ! -f $distdir/qux.cc +$MAKE distcheck + +: diff --git a/t/suffix-custom-link.sh b/t/suffix-custom-link.sh new file mode 100755 index 000000000..0b7814f3a --- /dev/null +++ b/t/suffix-custom-link.sh @@ -0,0 +1,73 @@ +#! /bin/sh +# Copyright (C) 2002-2012 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Check that Automake support entries with user-defined extensions of +# files in _SOURCES, and we can override the choice of a link in case +# the Automake default (C linker) would be inappropriate. + +required=c++ +. ./defs || Exit 1 + +cat >> configure.ac <<'END' +AC_PROG_CXX +AC_OUTPUT +END + +cat > Makefile.am <<'END' +%.$(OBJEXT): %.xt + sed -e 's/@/o/g' -e 's/!/;/g' $< >$*-t.cc \ + && $(CXX) -c $*-t.cc \ + && rm -f $*-t.cc \ + && mv -f $*-t.$(OBJEXT) $@ +bin_PROGRAMS = foo +foo_SOURCES = 1.xt 2.xt +foo_LINK = $(CXX) -o $@ +END + +cat > 1.xt <<'END' +#include +void say_hell@ (v@id)! +int main (v@id) +{ + say_hell@ ()! + std::exit(0)! +} +END + +cat > 2.xt <<'END' +#include +void say_hell@ (v@id) +{ + using namespace std! + c@ut << "Hell@, W@rld\n" << endl! +} +END + +$ACLOCAL +$AUTOMAKE +$AUTOCONF + +./configure + +$MAKE all +if cross_compiling; then :; else + ./foo + ./foo | grep 'Hello, World' +fi + +$MAKE distcheck + +: diff --git a/t/suffix12.sh b/t/suffix-custom-subobj.sh similarity index 93% rename from t/suffix12.sh rename to t/suffix-custom-subobj.sh index ecdba676d..daaa5c757 100755 --- a/t/suffix12.sh +++ b/t/suffix-custom-subobj.sh @@ -16,8 +16,6 @@ # Tests that pattern rules with subdir objects are understood. # Originally reported by John Ratliff against suffix rules. -# This test currently fails, because Automake-NG don't scan nor -# process pattern rules. required=cc . ./defs || Exit 1 diff --git a/t/suffix-custom.sh b/t/suffix-custom.sh new file mode 100755 index 000000000..158be9c66 --- /dev/null +++ b/t/suffix-custom.sh @@ -0,0 +1,106 @@ +#! /bin/sh +# Copyright (C) 2012 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Check that Automake support entries with user-defined extensions of +# files in _SOURCES, if there is a rule to turn files with that +# extension in object files. +# See also related test 'suffix-custom-go.sh' for a check using a +# real-world third party compiler (Go from Google). + +required=cc +. ./defs || Exit 1 + +cat >> configure.ac <<'END' +AC_CONFIG_HEADERS([config.h]) +AC_DEFINE([EXIT_OK], [0], [Exit status for success]) +AC_DEFINE([EXIT_KO], [1], [Exit status for failure]) +AC_PROG_CC +AC_OUTPUT +END + +cat > Makefile.am <<'END' +AM_DEFAULT_SOURCE_EXT = .my-c +MY_CFLAGS = $(if $(filter .,$(srcdir)),,-I $(srcdir)) $(CPPFLAGS) +%.$(OBJEXT): %.my-c + sed -e 's/@/o/g' -e 's/~/0/g' $< >$*-t.c \ + && $(CC) $(MY_CFLAGS) -c $*-t.c \ + && rm -f $*-t.c \ + && mv -f $*-t.$(OBJEXT) $@ +bin_PROGRAMS = foo +bin_PROGRAMS += zardoz +zardoz_SOURCES = main.c protos.h greet.my-c cleanup.my-c +END + +cat > foo.my-c <<'END' +#include +#include +int main (v@id) +{ + printf ("Dummy\n"); + exit (~); +} +END + +cat > protos.h << 'END' +void greet (void); +int cleanup (void); +#include +END + +cat > greet.my-c << 'END' +#include "pr@t@s.h" +void greet (v@id) +{ + printf ("Hell@, "); +} +END + +cat > cleanup.my-c << 'END' +#include "pr@t@s.h" +int cleanup (v@id) +{ + return (fcl@se (std@ut) == ~); +} +END + +cat > main.c <<'END' +#include +#include "protos.h" +int main (void) +{ + greet (); + puts ("W@rld!\n"); + return (cleanup () ? EXIT_OK : EXIT_KO); +} +END + +$ACLOCAL +$AUTOHEADER +$AUTOMAKE +$AUTOCONF + +./configure + +$MAKE all +if cross_compiling; then :; else + ./foo + ./zardoz + ./zardoz | grep 'Hello, W@rld!' +fi + +$MAKE distcheck + +: diff --git a/t/suffix-hdr.sh b/t/suffix-hdr.sh index 178d84d2b..67c7034c6 100755 --- a/t/suffix-hdr.sh +++ b/t/suffix-hdr.sh @@ -14,7 +14,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -# Use of "custom" headers (with custom suffix) in a _PROGRAMS variable. +# Use of "custom" headers (with custom suffix). required='cc native' . ./defs || Exit 1 @@ -26,13 +26,14 @@ END cat > Makefile.am << 'END' noinst_PROGRAMS = zardoz -zardoz_SOURCES = foo.my-c bar.my-h +nodist_zardoz_SOURCES = foo.c +EXTRA_DIST = bar.my-h foo.my-c BUILT_SOURCES = bar.h %.c: %.my-c sed 's/INTEGER/int/' $< >$@ %.h: %.my-h sed 's/SUBSTITUTE/#define/' $< >$@ -CLEANFILES = foo.c $(BUILT_SOURCES) +CLEANFILES = $(nodist_zardoz_SOURCES) $(BUILT_SOURCES) END cat > foo.my-c << 'END' diff --git a/t/suffix10.sh b/t/suffix10.sh index cd34fc75a..243ed2331 100755 --- a/t/suffix10.sh +++ b/t/suffix10.sh @@ -31,7 +31,9 @@ EOF cat >Makefile.am << 'END' lib_LTLIBRARIES = libfoo.la -libfoo_la_SOURCES = foo.x-x +nodist_libfoo_la_SOURCES = foo.y +CLEANFILES = $(nodist_libfoo_la_SOURCES) +EXTRA_DIST = $(nodist_libfoo_la_SOURCES:.y=.x-x) %.y: %.x-x rm -f $@ $@-t ## The leading ':;' works around a bug in bash <= 3.2. @@ -64,5 +66,7 @@ $AUTOMAKE --add-missing $MAKE test $MAKE all +test -f libfoo.la +$MAKE distcheck : diff --git a/t/suffix13.sh b/t/suffix13.sh index 86c59751a..f1d3b4174 100755 --- a/t/suffix13.sh +++ b/t/suffix13.sh @@ -29,13 +29,15 @@ EOF cat >Makefile.am << 'END' AUTOMAKE_OPTIONS = subdir-objects %.c: %.baz - case $@ in sub/*) $(MKDIR_P) sub;; *) :;; esac + test -d $(@D) || $(MKDIR_P) $(@D) cp $< $@ DISTCLEANFILES = sub/bar.c bin_PROGRAMS = foo -foo_SOURCES = foo.c sub/bar.baz +foo_SOURCES = foo.c +nodist_foo_SOURCES = sub/bar.c +EXTRA_DIST = sub/bar.baz foo_CFLAGS = -DRETVAL=0 END diff --git a/t/suffix3.sh b/t/suffix3.sh index 66be6cc1f..bdf22cd59 100755 --- a/t/suffix3.sh +++ b/t/suffix3.sh @@ -27,23 +27,17 @@ END cat > Makefile.am << 'END' %.cc: %.zoo sed 's/INTEGER/int/g' $< >$@ -bin_PROGRAMS = foo -foo_SOURCES = foo.zoo -# This is required by "make distcheck". The useless indirection is -# reequired to avoid false positives by the grepping checks below. -FOO = foo -CLEANFILES = $(FOO).cc +bin_PROGRAMS = zardoz +nodist_zardoz_SOURCES = foo.cc +EXTRA_DIST = foo.zoo +CLEANFILES = foo.cc END $ACLOCAL $AUTOMAKE -# The foo.cc intermediate step is implicit, it's a mistake if -# Automake requires this file somewhere. Also, Automake should -# not require the file 'foo.c' anywhere. -$FGREP foo.c Makefile.in && Exit 1 -# However Automake must figure that foo.zoo is eventually -# transformed into foo.o, and use this latter file (to link foo). +# Automake has been clearly told that foo.zoo is eventually transformed +# into foo.o, and to use this latter file (to link foo). $FGREP 'foo.$(OBJEXT)' Makefile.in # Finally, our dummy package doesn't use C in any way, so it the # Makefile shouldn't contain stuff related to the C compiler. @@ -68,10 +62,6 @@ END $MAKE all $MAKE distcheck -# TODO: should we check that intermediate file 'foo.cc' has -# been removed? Or is this requiring too much from the make -# implementation? - # Intermediate files should not be distributed. $MAKE distdir test ! -r $me-1.0/foo.cc diff --git a/t/suffix5.sh b/t/suffix5.sh index 4963a58f8..fb32ae190 100755 --- a/t/suffix5.sh +++ b/t/suffix5.sh @@ -52,7 +52,7 @@ done $ACLOCAL $AUTOMAKE -grep '_OBJECTS.*foo\.lo' Makefile.in +#grep '_OBJECTS.*foo\.lo' Makefile.in $AUTOCONF ./configure diff --git a/t/suffix8.sh b/t/suffix8.sh index c1f254e5c..f4920ea47 100755 --- a/t/suffix8.sh +++ b/t/suffix8.sh @@ -41,9 +41,9 @@ libfoo_la_SOURCES = bar.x_ %.y_: %.x_ cp $< $@ -%.o: %.y_ +%.o: %.x_ cp $< $@ -%.obj: %.y_ +%.obj: %.x_ cp $< $@ %.z_: %.y_ cp $< $@ diff --git a/t/yacc-lex-cxx-alone.sh b/t/yacc-lex-cxx-alone.sh new file mode 100755 index 000000000..e9548a54c --- /dev/null +++ b/t/yacc-lex-cxx-alone.sh @@ -0,0 +1,116 @@ +#! /bin/sh +# Copyright (C) 2011-2012 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Yacc + C++ support for a program built only from yacc sources. +# Lex + C++ support for a program built only from lex sources. + +required='c++ yacc' +. ./defs || Exit 1 + +cat >> configure.ac << 'END' +AC_PROG_CXX +AC_PROG_LEX +AC_PROG_YACC +AC_OUTPUT +END + +cat > Makefile.am << 'END' +bin_PROGRAMS = foo bar +foo_SOURCES = foo.yy +bar_SOURCES = bar.lxx + +.PHONY: check-dist +check-dist: distdir + echo ' ' $(am__dist_common) ' ' | grep '[ /]foo\.cc' + echo ' ' $(am__dist_common) ' ' | grep '[ /]bar\.cxx' + ls -l $(distdir) + test -f $(distdir)/foo.cc + test -f $(distdir)/bar.cxx +END + +cat > foo.yy << 'END' +%{ +// Valid C++, but deliberately invalid C. +#include +#include +// "std::" qualification required by Sun C++ 5.9. +int yylex (void) { return std::getchar (); } +void yyerror (const char *s) { return; } +%} +%% +a : 'a' { exit(0); }; +%% +int main (void) +{ + yyparse (); + return 1; +} +END + +cat > bar.lxx << 'END' +%{ +#define YY_NO_UNISTD_H 1 +int isatty (int fd) { return 0; } +%} +%% +"x" return EOF; +. +%% +// Valid C++, but deliberately invalid C. +#include +int main (void) +{ + /* We don't use a 'while' loop here (like a real lexer would do) + to avoid possible hangs. */ + if (yylex () == EOF) + std::exit (0); + else + std::exit (1); +} + +/* Avoid possible link errors. */ +int yywrap (void) { return 1; } +END + +$ACLOCAL +$AUTOCONF +$AUTOMAKE -a + +./configure + +$MAKE + +# The Yacc-derived and Lex-derived C++ sources must be created, and not +# removed once compiled (i.e., not treated like "intermediate files" in +# the GNU make sense). +test -f foo.cc +test -f bar.cxx + +if cross_compiling; then :; else + echo a | ./foo + echo b | ./foo && Exit 1 + echo x | ./bar + echo y | ./bar && Exit 1 + : # Don't trip on 'set -e'. +fi + +# The Yacc-derived and Lex-derived C++ sources must be shipped. +$MAKE check-dist + +# Sanity check on distribution. +$MAKE distcheck + +: