From: Alexandre Duret-Lutz Date: Tue, 30 Dec 2003 23:49:57 +0000 (+0000) Subject: * automake.in (handle_languages): Define %DEPBASE% conditionally X-Git-Tag: Release-1-8b~117 X-Git-Url: https://sourceware.org/git/?a=commitdiff_plain;h=70fb55c1d476dfb78389535e9ee527d7fd783fb8;p=automake.git * automake.in (handle_languages): Define %DEPBASE% conditionally on subdir-objects. Define SUBDIROBJ. Do not clean *_.c files here ... (lang_c_finish): ... do it here. (handle_single_transform_list): Do not output specific rules for subdir-objects files which are not renamed. This should reduce the size of Makefiles with lots of subdirectory sources. * lib/depcomp: Simplify computation of dependency output, and use DEPDIR. * lib/am/depend2.am (%EXT%.o, %EXT%.obj, %EXT%.lo): Adjust call to depcomp. Compute depbase on-the-fly in generic fastdep rules for subdir-objects. * tests/ansi9.test: Do not grep for an explicit rule that we no longer expect. Really run $MAKE to make sure the chain of rules works. * tests/yacc5.test: Do not grep for an explicit rule that we no longer expect. Adjust to use set -e. --- diff --git a/ChangeLog b/ChangeLog index af475bb0..b483cbd7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2003-12-31 Alexandre Duret-Lutz + + * automake.in (handle_languages): Define %DEPBASE% conditionally + on subdir-objects. Define SUBDIROBJ. Do not clean *_.c files + here ... + (lang_c_finish): ... do it here. + (handle_single_transform_list): Do not output specific rules for + subdir-objects files which are not renamed. This should reduce + the size of Makefiles with lots of subdirectory sources. + * lib/depcomp: Simplify computation of dependency output, and use + DEPDIR. + * lib/am/depend2.am (%EXT%.o, %EXT%.obj, %EXT%.lo): Adjust call + to depcomp. Compute depbase on-the-fly in generic fastdep rules + for subdir-objects. + * tests/ansi9.test: Do not grep for an explicit rule that + we no longer expect. Really run $MAKE to make sure the chain + of rules works. + * tests/yacc5.test: Do not grep for an explicit rule that + we no longer expect. Adjust to use set -e. + 2003-12-27 Alexandre Duret-Lutz * automake.in (@common_files): Move configure, configure.ac, and diff --git a/NEWS b/NEWS index eac173b4..f70c7d60 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,9 @@ New in 1.8a: -* Nothing yet. +* Inference rules are used to compile sources in subdirectories when the + `subdir-objects' option is used and no per-target flags are used. This + should reduce the size of some projects a lot, because Automake used to + output an explicit rule for each such object in the past. New in 1.8: diff --git a/automake.in b/automake.in index c6cf31ea..a373e621 100755 --- a/automake.in +++ b/automake.in @@ -1087,6 +1087,27 @@ sub handle_languages # This is not used by depend2.am. my $der_ext = (&{$lang->output_extensions} ($ext))[0]; + # When we output an inference rule like `.c.o:' we + # have two cases to consider: either subdir-objects + # is used, or it is not. + # + # In the latter case the rule is used to build objects + # in the current directory, and dependencies always + # go into `./$(DEPDIR)/'. We can hard-code this value. + # + # In the former case the rule can be used to build + # objects in sub-directories too. Dependencies should + # go into the appropriate sub-directories, e.g., + # `sub/$(DEPDIR)/'. The value of this directory + # need the be computed on-the-fly. + # + # DEPBASE holds the name of this directory, plus the + # basename part of the object file (extensions Po, TPo, + # Plo, TPlo will be added later as appropriate). It is + # either hardcoded, or a shell variable (`$depbase') that + # will be computed by the rule. + my $depbase = + option ('subdir-objects') ? '$$depbase' : '$(DEPDIR)/$*'; $output_rules .= file_contents ($rule_file, new Automake::Location, @@ -1095,11 +1116,7 @@ sub handle_languages 'DERIVED-EXT' => $der_ext, - # In this situation we know that the - # object is in this directory, so - # $(DEPDIR) is the correct location for - # dependencies. - DEPBASE => '$(DEPDIR)/$*', + DEPBASE => $depbase, BASE => '$*', SOURCE => '$<', OBJ => '$@', @@ -1108,7 +1125,8 @@ sub handle_languages COMPILE => '$(' . $lang->compiler . ')', LTCOMPILE => '$(LT' . $lang->compiler . ')', - -o => $output_flag); + -o => $output_flag, + SUBDIROBJ => !! option 'subdir-objects'); } # Now include code for each specially handled object with this @@ -1209,11 +1227,6 @@ sub handle_languages if $source !~ /\$U/; (my $source_ = $source) =~ s/\$U/_/g; - # Explicitly clean the _.c files if they are in - # a subdirectory. (In the current directory they get - # erased by a `rm -f *_.c' rule.) - $clean_files{$source_} = MOSTLY_CLEAN - if $objdir ne '.'; # Output an additional rule if _.c and .c are not in # the same directory. (_.c is always in $objdir.) if ($objdir ne $srcdir) @@ -1531,13 +1544,37 @@ sub handle_single_transform_list ($$$$@) $object = $directory . '/' . $object; } - # If doing dependency tracking, then we can't print - # the rule. If we have a subdir object, we need to - # generate an explicit rule. Actually, in any case - # where the object is not in `.' we need a special - # rule. The per-object rules in this case are - # generated later, by handle_languages. - if ($renamed || $directory ne '') + # If the object file has been renamed (because per-target + # flags are used) we cannot compile the file with an + # inference rule: we need an explicit rule. + # + # If the source is in a subdirectory and the object is in + # the current directory, we also need an explicit rule. + # + # If both source and object files are in a subdirectory + # (this happens when the subdir-objects option is used), + # then the inference will work. + # + # The latter case deserves a historical note. When the + # subdir-objects option was added on 1999-04-11 it was + # thought that inferences rules would work for + # subdirectory objects too. Later, on 1999-11-22, + # automake was changed to output explicit rules even for + # subdir-objects. Nobody remembers why, but this occured + # soon after the merge of the user-dep-gen-branch so it + # might be related. In late 2003 people complained about + # the size of the generated Makefile.ins (libgcj, with + # 2200+ subdir objects was reported to have a 9MB + # Makefile), so we now rely on inference rules again. + # Maybe we'll run across the same issue as in the past, + # but at least this time we can document it. However since + # dependency tracking has evolved it is possible that + # our old problem no longer exists. + # Using inference rules for subdir-objects has been tested + # with GNU make, Solaris make, Ultrix make, BSD make, + # HP-UX make, and OSF1 make successfully. + if ($renamed || + ($directory ne '' && ! option 'subdir-objects')) { my $obj_sans_ext = substr ($object, 0, - length ($this_obj_ext)); @@ -4935,6 +4972,12 @@ sub lang_c_finish push (@objects, $base . '_.$(OBJEXT)'); push (@objects, $base . '_.lo') if var ('LIBTOOL'); + + # Explicitly clean the _.c files if they are in a + # subdirectory. (In the current directory they get erased + # by a `rm -f *_.c' rule.) + $clean_files{$base . '_.c'} = MOSTLY_CLEAN + if dirname ($base) ne '.'; } # Make all _.o (and _.lo) files depend on ansi2knr. diff --git a/lib/am/depend2.am b/lib/am/depend2.am index 0a6ec6f7..24ec0c74 100644 --- a/lib/am/depend2.am +++ b/lib/am/depend2.am @@ -56,7 +56,8 @@ ## compile rules so that they are output on a single line (instead of 5) ## would be a good compromise. Actually we use two line rather than one, ## because this way %SOURCE% is always located at the end of the first -## line and is therefore easier to spot. +## line and is therefore easier to spot. (We need an extra line when +## depbase is used.) ?GENERIC?%EXT%.o: ?!GENERIC?%OBJ%: %SOURCE% @@ -64,13 +65,13 @@ if %FASTDEP% ## In fast-dep mode, we can always use -o. ## For non-suffix rules, we must emulate a VPATH search on %SOURCE%. ?!GENERIC? if %COMPILE% -MT %OBJ% -MD -MP -MF "%DEPBASE%.Tpo" %-c% -o %OBJ% `test -f '%SOURCE%' || echo '$(srcdir)/'`%SOURCE%; \ +?SUBDIROBJ??GENERIC? depbase=`echo %OBJ% | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`; \ ?GENERIC? if %COMPILE% -MT %OBJ% -MD -MP -MF "%DEPBASE%.Tpo" %-c% -o %OBJ% %SOURCE%; \ then mv -f "%DEPBASE%.Tpo" "%DEPBASE%.Po"; else rm -f "%DEPBASE%.Tpo"; exit 1; fi else !%FASTDEP% if %AMDEP% source='%SOURCE%' object='%OBJ%' libtool=no @AMDEPBACKSLASH@ - depfile='%DEPBASE%.Po' tmpdepfile='%DEPBASE%.TPo' @AMDEPBACKSLASH@ - $(%FPFX%DEPMODE) $(depcomp) @AMDEPBACKSLASH@ + DEPDIR=$(DEPDIR) $(%FPFX%DEPMODE) $(depcomp) @AMDEPBACKSLASH@ endif %AMDEP% if %?GENERIC% ?-o? %COMPILE% %-c% %-o% %OBJ% %SOURCE% @@ -88,13 +89,13 @@ if %FASTDEP% ## In fast-dep mode, we can always use -o. ## For non-suffix rules, we must emulate a VPATH search on %SOURCE%. ?!GENERIC? if %COMPILE% -MT %OBJOBJ% -MD -MP -MF "%DEPBASE%.Tpo" %-c% -o %OBJOBJ% `if test -f '%SOURCE%'; then $(CYGPATH_W) '%SOURCE%'; else $(CYGPATH_W) '$(srcdir)/%SOURCE%'; fi`; \ +?SUBDIROBJ??GENERIC? depbase=`echo %OBJ% | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`; \ ?GENERIC? if %COMPILE% -MT %OBJOBJ% -MD -MP -MF "%DEPBASE%.Tpo" %-c% -o %OBJOBJ% `$(CYGPATH_W) '%SOURCE%'`; \ then mv -f "%DEPBASE%.Tpo" "%DEPBASE%.Po"; else rm -f "%DEPBASE%.Tpo"; exit 1; fi else !%FASTDEP% if %AMDEP% source='%SOURCE%' object='%OBJOBJ%' libtool=no @AMDEPBACKSLASH@ - depfile='%DEPBASE%.Po' tmpdepfile='%DEPBASE%.TPo' @AMDEPBACKSLASH@ - $(%FPFX%DEPMODE) $(depcomp) @AMDEPBACKSLASH@ + DEPDIR=$(DEPDIR) $(%FPFX%DEPMODE) $(depcomp) @AMDEPBACKSLASH@ endif %AMDEP% if %?GENERIC% ?-o? %COMPILE% %-c% %-o% %OBJOBJ% `$(CYGPATH_W) '%SOURCE%'` @@ -112,15 +113,14 @@ if %?LIBTOOL% if %FASTDEP% ## In fast-dep mode, we can always use -o. ## For non-suffix rules, we must emulate a VPATH search on %SOURCE%. -?GENERIC? if %LTCOMPILE% -MT %LTOBJ% -MD -MP -MF "%DEPBASE%.Tpo" %-c% -o %LTOBJ% %SOURCE%; \ -## For non-suffix rules, we must emulate a VPATH search on %SOURCE%. ?!GENERIC? if %LTCOMPILE% -MT %LTOBJ% -MD -MP -MF "%DEPBASE%.Tpo" %-c% -o %LTOBJ% `test -f '%SOURCE%' || echo '$(srcdir)/'`%SOURCE%; \ +?SUBDIROBJ??GENERIC? depbase=`echo %OBJ% | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`; \ +?GENERIC? if %LTCOMPILE% -MT %LTOBJ% -MD -MP -MF "%DEPBASE%.Tpo" %-c% -o %LTOBJ% %SOURCE%; \ then mv -f "%DEPBASE%.Tpo" "%DEPBASE%.Plo"; else rm -f "%DEPBASE%.Tpo"; exit 1; fi else !%FASTDEP% if %AMDEP% source='%SOURCE%' object='%LTOBJ%' libtool=yes @AMDEPBACKSLASH@ - depfile='%DEPBASE%.Plo' tmpdepfile='%DEPBASE%.TPlo' @AMDEPBACKSLASH@ - $(%FPFX%DEPMODE) $(depcomp) @AMDEPBACKSLASH@ + DEPDIR=$(DEPDIR) $(%FPFX%DEPMODE) $(depcomp) @AMDEPBACKSLASH@ endif %AMDEP% ## We can always use `-o' with Libtool. ?GENERIC? %LTCOMPILE% %-c% -o %LTOBJ% %SOURCE% diff --git a/lib/depcomp b/lib/depcomp index 9e5522d0..9beba448 100755 --- a/lib/depcomp +++ b/lib/depcomp @@ -1,7 +1,7 @@ #! /bin/sh # depcomp - compile a program generating dependencies as side-effects -scriptversion=2003-11-08.23 +scriptversion=2003-12-28.12 # Copyright (C) 1999, 2000, 2003 Free Software Foundation, Inc. @@ -43,6 +43,7 @@ Environment variables: depmode Dependency tracking mode. source Source file read by `PROGRAMS ARGS'. object Object file output by `PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputing dependencies. libtool Whether libtool is used (yes/no). @@ -61,18 +62,10 @@ if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi -# `libtool' can also be set to `yes' or `no'. - -if test -z "$depfile"; then - base=`echo "$object" | sed -e 's,^.*/,,' -e 's,\.\([^.]*\)$,.P\1,'` - dir=`echo "$object" | sed 's,/.*$,/,'` - if test "$dir" = "$object"; then - dir= - fi - # FIXME: should be _deps on DOS. - depfile="$dir.deps/$base" -fi +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" diff --git a/tests/ansi9.test b/tests/ansi9.test index 477044af..5740487d 100755 --- a/tests/ansi9.test +++ b/tests/ansi9.test @@ -1,5 +1,5 @@ #! /bin/sh -# Copyright (C) 2002 Free Software Foundation, Inc. +# Copyright (C) 2002, 2003 Free Software Foundation, Inc. # # This file is part of GNU Automake. # @@ -22,6 +22,7 @@ # can still be deansified. # Report from Paul D. Smith. +required=gcc . ./defs || exit 1 set -e @@ -30,6 +31,7 @@ cat >>configure.in < Makefile.am << 'END' @@ -38,10 +40,29 @@ noinst_PROGRAMS = loadavg sub/sub loadavg_SOURCES = loadavg.c loadavg_CFLAGS = -DTEST sub_sub_SOURCES = sub/sub.c +# Force ansi2knr's use, regardless of the compiler. +U=_ +ANSI2KNR=./ansi2knr END +cat > loadavg.c << 'END' +int +main () +{ + return 0; +} +END + +mkdir sub +cp loadavg.c sub/sub.c + $ACLOCAL -$AUTOMAKE --add-missing +$AUTOCONF +$AUTOMAKE --add-missing -Wno-override $FGREP 'loadavg-loadavg$U.o: loadavg$U.c' Makefile.in -$FGREP 'sub/sub$U.o: sub/sub$U.c' Makefile.in +# The following rule should not exists, because the +# default .o.c: inference rule is enough. +$FGREP 'sub/sub$U.o: sub/sub$U.c' Makefile.in && exit 1 +./configure +$MAKE sub/sub_.c diff --git a/tests/yacc5.test b/tests/yacc5.test index 7ce84397..02f868ea 100755 --- a/tests/yacc5.test +++ b/tests/yacc5.test @@ -1,5 +1,5 @@ #! /bin/sh -# Copyright (C) 2001, 2002 Free Software Foundation, Inc. +# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. # # This file is part of GNU Automake. # @@ -23,6 +23,8 @@ . ./defs || exit 1 +set -e + cat > configure.in << 'END' AC_INIT AM_INIT_AUTOMAKE(nonesuch, nonesuch) @@ -41,10 +43,10 @@ mkdir sub : > sub/maude.y -$ACLOCAL || exit 1 -$AUTOMAKE -a || exit 1 +$ACLOCAL +$AUTOMAKE -a -grep '^maude\.c:' Makefile.in || exit 1 +grep '^maude\.c:' Makefile.in ## Try again with subdir-objects. @@ -55,10 +57,11 @@ bin_PROGRAMS = maude maude_SOURCES = sub/maude.y END -$ACLOCAL || exit 1 -$AUTOMAKE -a || exit 1 +$ACLOCAL +$AUTOMAKE -a -grep '^sub/maude\.c:' Makefile.in || exit 1 +# No rule needed, the default .y.c: inference rule is enough. +grep '^sub/maude\.c:' Makefile.in && exit 1 ## Try again with per-exe flags. @@ -80,6 +83,4 @@ grep 'AM_YFLAGS.*maude' Makefile.in && exit 1 grep 'maudec' Makefile.in && exit 1 # Make sure the .o file is required. -grep '^am_maude_OBJECTS.*maude' Makefile.in || exit 1 - -exit 0 +grep '^am_maude_OBJECTS.*maude' Makefile.in