From c98183d6f3005b7012ead5a5a41b1141c744b7af Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Sun, 11 Aug 1996 07:42:38 +0000 Subject: [PATCH] Better C++, yacc, lex support --- ChangeLog | 22 ++++++++ Makefile.am | 4 +- Makefile.in | 4 +- NEWS | 1 + TODO | 2 - automake.in | 155 ++++++++++++++++++++++++++++++++++++++++------------- depend.am | 27 ++-------- depend2.am | 34 ++++++++++++ interlock | 46 ++++++++++++++++ lib/am/Makefile.am | 4 +- lib/am/depend.am | 27 ++-------- lib/am/depend2.am | 34 ++++++++++++ tests/ChangeLog | 4 ++ tests/yacc.test | 2 +- 14 files changed, 275 insertions(+), 91 deletions(-) create mode 100644 depend2.am create mode 100755 interlock create mode 100644 lib/am/depend2.am diff --git a/ChangeLog b/ChangeLog index 7fae82d..bef8d47 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,27 @@ +Sun Aug 11 00:20:16 1996 Tom Tromey + + * automake.in (handle_yacc_lex_cxx): Renamed. + + * automake.in (handle_dependencies): Handle %cxx_extensions. + Include depend2.am when appropriate. + + * depend2.am: New file; contents from depend.am but templatized. + + * automake.in (initialize_per_input): Initialize + %cxx_extensions. + (handle_source_transform): Set %cxx_extensions. + Sat Aug 10 10:29:30 1996 Tom Tromey + * interlock: New file. + + * automake.in (handle_yacc_lex): New sub. + (handle_source_transform): Removed most yacc/lex handling. + (initialize_per_input): Init yacc_sources, lex_sources. + (generate_makefile): Run handle_yacc_lex. + (handle_merge_targets): Use `scalar' and not $# to find length of + array. + * m4/AM_FEATURE_EXIT.m4: Wrote. * m4/AM_FEATURE_CTYPE.m4: Wrote. * m4/AM_FEATURE_ERRNO.m4: Wrote. diff --git a/Makefile.am b/Makefile.am index f27786c..78c5bbb 100644 --- a/Makefile.am +++ b/Makefile.am @@ -12,7 +12,7 @@ info_TEXINFOS = automake.texi # CONFIG_HEADER = config.h pkgdata_DATA = clean-kr.am clean.am compile-kr.am compile-vars.am \ -compile.am data.am dejagnu.am depend.am dist-vars.am footer.am \ +compile.am data.am dejagnu.am depend.am depend2.am dist-vars.am footer.am \ header.am header-vars.am kr-extra.am libraries.am library.am \ mans-vars.am program.am programs.am remake-hdr.am remake-subd.am \ remake.am scripts.am subdirs.am tags.am tags-subd.am tags-clean.am \ @@ -21,7 +21,7 @@ programs-clean.am data-clean.am COPYING INSTALL texinfo.tex ansi2knr.c \ ansi2knr.1 aclocal.m4 lisp.am lisp-clean.am ## These must all be executable when installed. -pkgdata_SCRIPTS = config.guess config.sub install-sh mdate-sh \ +pkgdata_SCRIPTS = config.guess config.sub install-sh interlock mdate-sh \ mkinstalldirs elisp-comp CLEANFILES = automake aclocal diff --git a/Makefile.in b/Makefile.in index 3935c33..e552684 100644 --- a/Makefile.in +++ b/Makefile.in @@ -50,7 +50,7 @@ info_TEXINFOS = automake.texi # CONFIG_HEADER = config.h pkgdata_DATA = clean-kr.am clean.am compile-kr.am compile-vars.am \ -compile.am data.am dejagnu.am depend.am dist-vars.am footer.am \ +compile.am data.am dejagnu.am depend.am depend2.am dist-vars.am footer.am \ header.am header-vars.am kr-extra.am libraries.am library.am \ mans-vars.am program.am programs.am remake-hdr.am remake-subd.am \ remake.am scripts.am subdirs.am tags.am tags-subd.am tags-clean.am \ @@ -58,7 +58,7 @@ texi-version.am texinfos-vars.am texinfos.am libraries-clean.am \ programs-clean.am data-clean.am COPYING INSTALL texinfo.tex ansi2knr.c \ ansi2knr.1 aclocal.m4 lisp.am lisp-clean.am -pkgdata_SCRIPTS = config.guess config.sub install-sh mdate-sh \ +pkgdata_SCRIPTS = config.guess config.sub install-sh interlock mdate-sh \ mkinstalldirs elisp-comp CLEANFILES = automake aclocal diff --git a/NEWS b/NEWS index 02d139f..ccc4c60 100644 --- a/NEWS +++ b/NEWS @@ -8,6 +8,7 @@ New in 1.1b: * Automake will now generate rules to regenerate aclocal.m4, if appropriate * Now uses `AM_' macro names everywhere * ansi2knr option can have directory prefix (eg `../lib/ansi2knr') +* Better C++, yacc, lex support New in 1.0: * Bug fixes diff --git a/TODO b/TODO index efee476..0bdbfa1 100644 --- a/TODO +++ b/TODO @@ -157,8 +157,6 @@ Lex, yacc support: * require AC_DECL_YYTEXT for lex * Actually use $seen_prog_yacc * Require AC_PROG_LEX or equivalent -* Consider using implicit .y.c and .l.c rules instead of current - lex/yacc trickery require AC_PROG_CXX if any C++ source files found? diff --git a/automake.in b/automake.in index 7f21d18..a58971e 100755 --- a/automake.in +++ b/automake.in @@ -386,6 +386,9 @@ sub generate_makefile &handle_programs; &handle_scripts; + # This must be run after all the sources are scanned. + &handle_yacc_lex_cxx; + # Re-init SOURCES and OBJECTS. FIXME other code shouldn't depend # on this (but currently does). $contents{'SOURCES'} = join (' ', @sources); @@ -566,6 +569,79 @@ sub get_object_extension return $dir_holds_sources; } +# Handle yacc and lex. +sub handle_yacc_lex_cxx +{ + local ($yacc_count) = scalar (keys %yacc_sources); + local ($lex_count) = scalar (keys %lex_sources); + local ($cxx_count) = scalar (keys %cxx_extensions); + + if ($yacc_count) + { + push (@suffixes, '.y'); + $output_vars .= "YACC = \@YACC\@\n"; + $output_rules .= ".y.c:\n\t"; + if ($yacc_count > 1) + { + $output_rules .= '$(INTERLOCK) y.tab.c $@ $(YACC) $(YFLAGS) $<'; + } + else + { + $output_rules .= '$(YACC) $(YFLAGS) $< && mv y.tab.c $@'; + } + $output_rules .= "\n"; + } + if ($lex_count) + { + push (@suffixes, '.l'); + $output_vars .= "LEX = \@LEX\@\n"; + $output_rules .= (".l.c:\n\t" + . "\n"); + if ($lex_count > 1) + { + $output_rules .= '$(INTERLOCK) lex.yy.c $@ $(LEX) $(LFLAGS) $<'; + } + else + { + $output_rules .= '$(LEX) $(LFLAGS) $< && mv lex.yy.c $@'; + } + $output_rules .= "\n"; + } + if ($cxx_count) + { + $output_vars .= ("CXX = \@CXX\@\n" + . "CXXFLAGS = \@CXXFLAGS\@\n" + . "CXXCOMPILE = $(CXX) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CXXFLAGS)\n" + . "CXXLINK = $(CXX) $(LDFLAGS) -o $@\n"); + + local ($ext); + foreach $ext (keys %cxx_extensions) + { + $output_rules .= ("$ext.o:\n" + . "\t\$(CXXCOMPILE) -c \$<\n"); + } + } + + if ($yacc_count > 1 || $lex_count > 1) + { + # If there is more than one distinct yacc (resp lex) source + # file in a given directory, then the `interlock' program is + # required to allow parallel builds to work correctly. FIXME + # for now, no line number. + &require_config_file ($FOREIGN, 'interlock'); + $output_vars .= 'INTERLOCK = '; + if ($config_aux_dir ne '.' && $config_aux_dir ne '') + { + $output_vars .= $config_aux_dir; + } + else + { + $output_vars .= '$(top_srcdir)'; + } + $output_vars .= "/interlock\n"; + } +} + # Handle SOURCE->OBJECT transform for one program or library. sub handle_source_transform { @@ -633,55 +709,34 @@ sub handle_source_transform { # Yacc source. &push_dist_common ($1 . '.c'); - if (! defined $targets{$1 . '.c'}) - { - # Generate a target. - $output_rules .= ($1 . '.c: ' . $_ . "\n" - . "\t" - . 'cd $(srcdir) && $(YACC) $(YFLAGS) $< && mv y.tab.c ' - . $1 . '.c' . "\n"); - } - - if (! &variable_defined ('YACC')) - { - $output_vars .= "YACC = \@YACC\@\n"; - $targets{'YACC'} = 1; - } + $yacc_sources{$_} = 1; } elsif (/^(.*)\.l$/) { # Lex source. &push_dist_common ($1 . '.c'); - if (! defined $targets{$1 . '.c'}) - { - $output_rules .= ($1 . '.c: ' . $_ . "\n" - . "\t" - . 'cd $(srcdir) && $(LEX) $(LFLAGS) $< && mv lex.yy.c ' - . $1 . '.c' . "\n"); - } - - if (! &variable_defined ('LEX')) - { - $output_vars .= "LEX = \@YACC\@\n"; - $targets{'LEX'} = 1; - } + $lex_sources{$_} = 1; } # Transform source files into .o files. List of C++ # extensions comes from Emacs 19.32 etags. - s/\.c\+\+$/$obj/g; - s/\.cc$/$obj/g; - s/\.cpp$/$obj/g; - s/\.cxx$/$obj/g; + if (s/\.c\+\+$/$obj/g + || s/\.cc$/$obj/g + || s/\.cpp$/$obj/g + || s/\.cxx$/$obj/g + || s/\.C$/$obj/g) + { + $cxx_extensions{$&} = 1; + } # FORTRAN support. s/\.f90$/$obj/g; s/\.for$/$obj/g; - # .C is C++. .y is yacc. .l is lex. .f and .F is - # fortran. .s is assembly. .M is Objective-C++. .m - # is Objective-C. - s/\.[cCylfFsmM]$/$obj/g; + # .y is yacc. .l is lex. .f and .F is fortran. .s + # is assembly. .M is Objective-C++. .m is + # Objective-C. + s/\.[cylfFsmM]$/$obj/g; push (@result, $_) unless $prefix eq 'EXTRA_'; @@ -1485,6 +1540,24 @@ sub handle_dependencies { &pretty_print ('DEP_FILES =', "", sort keys %dep_files); $output_rules .= &file_contents ('depend'); + $output_rules .= + &file_contents_with_transform ('s/\@EXT\@/.c/g;' + . 's/\@MKDEP\@/MKDEP/g', + 'depend2'); + local ($ext); + local ($need_cxx) = 0; + foreach $ext (keys %cxx_extensions) + { + $output_rules .= + &file_contents_with_transform ('s/\@EXT\@/' . $ext .'/g;' + . 's/\@MKDEP\@/CXXMKDEP/g', + 'depend2'); + $need_cxx = 1; + } + if ($need_cxx) + { + $output_vars .= 'CXXMKDEP = $(CXX) -MM $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CXXFLAGS)' . "\n"; + } } } else @@ -1990,7 +2063,7 @@ sub handle_merge_targets # If no dependencies for 'install', add 'all'. Why? That way # "make install" at top level of distclean'd distribution won't # fail because stuff in 'lib' fails to build. - if (! @install || ($#install == 1 + if (! @install || (scalar (@install) == 2 && $install[0] eq 'install-exec' && $install[1] eq 'install-data')) { @@ -2899,6 +2972,16 @@ sub initialize_per_input # Per Makefile.am. $local_maint_charset = $maint_charset; + + # All yacc and lex source filenames for this directory. Use + # filenames instead of raw count so that multiple instances are + # counted correctly (eg one yacc file can appear in multiple + # programs without harm). + %yacc_sources = (); + %lex_sources = (); + + # C++ source extensions we've seen. + %cxx_extensions = (); } diff --git a/depend.am b/depend.am index bc00da7..1074c8f 100644 --- a/depend.am +++ b/depend.am @@ -15,9 +15,10 @@ ## along with this program; if not, write to the Free Software ## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA ## 02111-1307, USA. -# This fragment is probably only useful for maintainers. It relies on -# GNU make and gcc. It is only included in the generated Makefile.in -# if `automake' is not passed the `--include-deps' flag. + +## This fragment is probably only useful for maintainers. It relies +## on GNU make and gcc. It is only included in the generated +## Makefile.in if `automake' is not passed the `--include-deps' flag. MKDEP = gcc -MM $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) @@ -38,23 +39,3 @@ $(srcdir)/.deps/.P: $(BUILT_SOURCES) -include $(DEP_FILES) $(DEP_FILES): $(srcdir)/.deps/.P - -$(srcdir)/.deps/%.P: $(srcdir)/%.c - @echo "mkdeps $< > $@" -## Use funny regexp because otherwise too much can be matched when -## srcdir begins with ".". Can't use \< since sed doesn't recognize -## "." as a word start. Regexp-quote srcdir because "." is a matching -## operator which commonly appears in filenames. Need "//*" in -## regexps because otherwise the regexp will fail when srcdir=. and -## the path to the file is relative (eg ../lib/error.c matches "./*"). - @top=`echo $(srcdir) | sed 's,^$(top_srcdir),,;s,[^/],,g;s,/,../,g'` ; \ - re=`echo "s,^$(srcdir)//*,,g;s, $(srcdir)//*, ,g;s,$(top_srcdir)//*,$$top,g" | sed 's,\.,\\\\.,g'`; \ - $(MKDEP) $< | sed "$$re" > $@-tmp - @if test -n "$o"; then \ - sed 's/\.o:/$$o:/' $@-tmp > $@; \ - rm $@-tmp; \ - else \ - mv $@-tmp $@; \ - fi - -# End of maintainer-only section diff --git a/depend2.am b/depend2.am new file mode 100644 index 0000000..39cdc1d --- /dev/null +++ b/depend2.am @@ -0,0 +1,34 @@ +## automake - create Makefile.in from Makefile.am +## Copyright (C) 1994, 1995, 1996 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, write to the Free Software +## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +## 02111-1307, USA. +$(srcdir)/.deps/%.P: $(srcdir)/%@EXT@ + @echo "mkdeps $< > $@" +## Use funny regexp because otherwise too much can be matched when +## srcdir begins with ".". Can't use \< since sed doesn't recognize +## "." as a word start. Regexp-quote srcdir because "." is a matching +## operator which commonly appears in filenames. Need "//*" in +## regexps because otherwise the regexp will fail when srcdir=. and +## the path to the file is relative (eg ../lib/error.c matches "./*"). + @top=`echo $(srcdir) | sed 's,^$(top_srcdir),,;s,[^/],,g;s,/,../,g'` ; \ + re=`echo "s,^$(srcdir)//*,,g;s, $(srcdir)//*, ,g;s,$(top_srcdir)//*,$$top,g" | sed 's,\.,\\\\.,g'`; \ + $(@MKDEP@) $< | sed "$$re" > $@-tmp + @if test -n "$o"; then \ + sed 's/\.o:/$$o:/' $@-tmp > $@; \ + rm $@-tmp; \ + else \ + mv $@-tmp $@; \ + fi diff --git a/interlock b/interlock new file mode 100755 index 0000000..a35eb98 --- /dev/null +++ b/interlock @@ -0,0 +1,46 @@ +#! /bin/sh +# interlock - wrap program invocation in lock to allow +# parallel builds to work. +# Written by Tom Tromey , Aug 10 1996 +# +# 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# Pick a filename. Hopefully no-one actually uses this name. +dirname='=interlockdir' + +while (mkdir $dirname > /dev/null 2>&1 && exit 1 || exit 0); do + # Nothing. + : +done + +# We have the lock. +prog="$1" +progoutput="$2" +realoutput="$3" +shift +shift +shift + +$prog ${1+"$@"} +ret=$? + +if test -f "$progoutput"; then + mv "$progoutput" "$realoutput" || ret=$? +fi + +# Release the lock. +rmdir $dirname > /dev/null 2>&1 + +exit $ret diff --git a/lib/am/Makefile.am b/lib/am/Makefile.am index f27786c..78c5bbb 100644 --- a/lib/am/Makefile.am +++ b/lib/am/Makefile.am @@ -12,7 +12,7 @@ info_TEXINFOS = automake.texi # CONFIG_HEADER = config.h pkgdata_DATA = clean-kr.am clean.am compile-kr.am compile-vars.am \ -compile.am data.am dejagnu.am depend.am dist-vars.am footer.am \ +compile.am data.am dejagnu.am depend.am depend2.am dist-vars.am footer.am \ header.am header-vars.am kr-extra.am libraries.am library.am \ mans-vars.am program.am programs.am remake-hdr.am remake-subd.am \ remake.am scripts.am subdirs.am tags.am tags-subd.am tags-clean.am \ @@ -21,7 +21,7 @@ programs-clean.am data-clean.am COPYING INSTALL texinfo.tex ansi2knr.c \ ansi2knr.1 aclocal.m4 lisp.am lisp-clean.am ## These must all be executable when installed. -pkgdata_SCRIPTS = config.guess config.sub install-sh mdate-sh \ +pkgdata_SCRIPTS = config.guess config.sub install-sh interlock mdate-sh \ mkinstalldirs elisp-comp CLEANFILES = automake aclocal diff --git a/lib/am/depend.am b/lib/am/depend.am index bc00da7..1074c8f 100644 --- a/lib/am/depend.am +++ b/lib/am/depend.am @@ -15,9 +15,10 @@ ## along with this program; if not, write to the Free Software ## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA ## 02111-1307, USA. -# This fragment is probably only useful for maintainers. It relies on -# GNU make and gcc. It is only included in the generated Makefile.in -# if `automake' is not passed the `--include-deps' flag. + +## This fragment is probably only useful for maintainers. It relies +## on GNU make and gcc. It is only included in the generated +## Makefile.in if `automake' is not passed the `--include-deps' flag. MKDEP = gcc -MM $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) @@ -38,23 +39,3 @@ $(srcdir)/.deps/.P: $(BUILT_SOURCES) -include $(DEP_FILES) $(DEP_FILES): $(srcdir)/.deps/.P - -$(srcdir)/.deps/%.P: $(srcdir)/%.c - @echo "mkdeps $< > $@" -## Use funny regexp because otherwise too much can be matched when -## srcdir begins with ".". Can't use \< since sed doesn't recognize -## "." as a word start. Regexp-quote srcdir because "." is a matching -## operator which commonly appears in filenames. Need "//*" in -## regexps because otherwise the regexp will fail when srcdir=. and -## the path to the file is relative (eg ../lib/error.c matches "./*"). - @top=`echo $(srcdir) | sed 's,^$(top_srcdir),,;s,[^/],,g;s,/,../,g'` ; \ - re=`echo "s,^$(srcdir)//*,,g;s, $(srcdir)//*, ,g;s,$(top_srcdir)//*,$$top,g" | sed 's,\.,\\\\.,g'`; \ - $(MKDEP) $< | sed "$$re" > $@-tmp - @if test -n "$o"; then \ - sed 's/\.o:/$$o:/' $@-tmp > $@; \ - rm $@-tmp; \ - else \ - mv $@-tmp $@; \ - fi - -# End of maintainer-only section diff --git a/lib/am/depend2.am b/lib/am/depend2.am new file mode 100644 index 0000000..39cdc1d --- /dev/null +++ b/lib/am/depend2.am @@ -0,0 +1,34 @@ +## automake - create Makefile.in from Makefile.am +## Copyright (C) 1994, 1995, 1996 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, write to the Free Software +## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +## 02111-1307, USA. +$(srcdir)/.deps/%.P: $(srcdir)/%@EXT@ + @echo "mkdeps $< > $@" +## Use funny regexp because otherwise too much can be matched when +## srcdir begins with ".". Can't use \< since sed doesn't recognize +## "." as a word start. Regexp-quote srcdir because "." is a matching +## operator which commonly appears in filenames. Need "//*" in +## regexps because otherwise the regexp will fail when srcdir=. and +## the path to the file is relative (eg ../lib/error.c matches "./*"). + @top=`echo $(srcdir) | sed 's,^$(top_srcdir),,;s,[^/],,g;s,/,../,g'` ; \ + re=`echo "s,^$(srcdir)//*,,g;s, $(srcdir)//*, ,g;s,$(top_srcdir)//*,$$top,g" | sed 's,\.,\\\\.,g'`; \ + $(@MKDEP@) $< | sed "$$re" > $@-tmp + @if test -n "$o"; then \ + sed 's/\.o:/$$o:/' $@-tmp > $@; \ + rm $@-tmp; \ + else \ + mv $@-tmp $@; \ + fi diff --git a/tests/ChangeLog b/tests/ChangeLog index 1b10f90..d534637 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,7 @@ +Sun Aug 11 00:10:42 1996 Tom Tromey + + * yacc.test: Fixed test for new yacc code. + Sat Aug 10 10:09:45 1996 Tom Tromey * defun.test: New file. diff --git a/tests/yacc.test b/tests/yacc.test index 40d0888..3c8e37c 100755 --- a/tests/yacc.test +++ b/tests/yacc.test @@ -12,4 +12,4 @@ END $AUTOMAKE || exit 1 -grep '^zardoz.c:' Makefile.in +grep 'zardoz.c' Makefile.in -- 2.7.4