Index: automake.in =================================================================== RCS file: /cvs/automake/automake/automake.in,v retrieving revision 1.1523 diff -u -p -r1.1523 automake.in --- automake.in 30 Nov 2003 17:00:36 -0000 1.1523 +++ automake.in 1 Dec 2003 11:02:38 -0000 @@ -181,11 +181,27 @@ my $ELSE_PATTERN = my $ENDIF_PATTERN = '^endif(?:\s+(!?)\s*([A-Za-z][A-Za-z0-9_]*))?\s*(?:#.*)?' . "\$"; my $PATH_PATTERN = '(\w|[/.-])+'; +my $INCLUDE_KEYWORD = 'include'; +my $SUBDIR_INCLUDE_KEYWORD = 'subdir_include'; # This will pass through anything not of the prescribed form. -my $INCLUDE_PATTERN = ('^include\s+' +my $INCLUDE_PATTERN = ('^' . $INCLUDE_KEYWORD . '\s+' . '((\$\(top_srcdir\)/' . $PATH_PATTERN . ')' . '|(\$\(srcdir\)/' . $PATH_PATTERN . ')' . '|([^/\$]' . $PATH_PATTERN . '))\s*(#.*)?' . "\$"); +my $SUBDIR_INCLUDE_PATTERN = ('^' . $SUBDIR_INCLUDE_KEYWORD . '\s+' + . '((\$\(top_srcdir\)/' . $PATH_PATTERN . ')' + . '|(\$\(srcdir\)/' . $PATH_PATTERN . ')' + . '|([^/\$]' . $PATH_PATTERN . '))\s*(#.*)?' . "\$"); + +# Canonised variable suffixes +my @canonised_macro_names = + qw(SOURCES); +# Canonised variable contents (foo->path/foo) +my @canonised_macro_values = + qw(SOURCES); +# Canonised macro lists (foo ->path_foo) +my @canonised_macro_lists = + qw(PROGRAMS); # Match `-d' as a command-line argument in a string. my $DASH_D_PATTERN = "(^|\\s)-d(\\s|\$)"; @@ -216,7 +232,7 @@ my @common_files = ansi2knr.1 ansi2knr.c compile config.guess config.rpath config.sub configure configure.ac configure.in depcomp elisp-comp install-sh libversion.in mdate-sh missing mkinstalldirs - py-compile texinfo.tex ylwrap), + py-compile texinfo.tex ylwrap Makefile.rules), @libtool_files, @libtool_sometimes); # Commonly used files we auto-include, but only sometimes. @@ -1697,6 +1713,38 @@ sub handle_single_transform_list ($$$$@) return @result; } +# $VALUE +# transform_file_list ($PREPEND, @FILES) +# ---------------------------------------- +# insert $PREPEND before every file path that is not absolute +# +sub transform_file_list ($$) +{ + my ($prepend, $tmpfiles) = @_; + my $result = ""; + my @files = (); + @files = split(/ /, $tmpfiles); + while (scalar @files > 0) + { + $_ = shift @files; + + if ($_ =~ s/^\$\(top_srcdir\)\///) + { + $result .= " \$\(top_srcdir\)\/" . $_; + } + elsif ( $_ =~ s/^\$\(srcdir\)\///) + { + $result .= " \$\(srcdir\)\/$prepend" . $_; + } + else + { + $result .= " $prepend" . $_; + } + } + verb "transformed value: '$result'\n"; + return $result . "\n"; +} + # $LINKER # define_objects_from_sources ($VAR, $OBJVAR, $NODEFINE, $ONE_FILE, @@ -2145,7 +2193,7 @@ sub handle_programs # Canonicalize names and check for misspellings. my $xname = &check_canonical_spelling ($one_file, '_LDADD', '_LDFLAGS', '_SOURCES', '_OBJECTS', - '_DEPENDENCIES'); + '_DEPENDENCIES', '_CFLAGS'); $where->push_context ("while processing program `$one_file'"); $where->set (INTERNAL->get); @@ -2250,7 +2298,7 @@ sub handle_libraries # Canonicalize names and check for misspellings. my $xlib = &check_canonical_spelling ($onelib, '_LIBADD', '_SOURCES', '_OBJECTS', '_DEPENDENCIES', - '_AR'); + '_AR', '_CFLAGS'); if (! var ($xlib . '_AR')) { @@ -2371,7 +2419,20 @@ sub handle_ltlibraries # Canonicalize names and check for misspellings. my $xlib = &check_canonical_spelling ($onelib, '_LIBADD', '_LDFLAGS', '_SOURCES', '_OBJECTS', - '_DEPENDENCIES'); + '_DEPENDENCIES', '_CFLAGS'); + +# Tell the source code what library we are building +# my $tempvariable = ''; +# if ( &variable_defined ($xlib . '_CFLAGS')) +# { +# # Define the lib_CFLAGS variable. +# $tempvariable .= &variable_value ($xlib . '_CFLAGS'); +# &variable_delete ($xlib . '_CFLAGS'); +# } +# my $libname_short = $xlib; +# $libname_short =~ s/_la$// ; +# $libname_short = uc ($libname_short); +# &define_variable ($xlib . '_CFLAGS', ' -D' . $libname_short . '_COMPILATION ' . $tempvariable); # Check that the library fits the standard naming convention. my $libname_rx = "^lib.*\.la"; @@ -5413,19 +5474,62 @@ sub check_trailing_slash ($\$) return $$line =~ /\\$/; } +# include () +# worker routine to include a file. +# +sub include($$$$@) +{ + my ($path, $relative_dir, $where, $canonise, @include_stack) = @_; + my $prepend_path = ""; + + if ($path =~ s/^\$\(top_srcdir\)\///) + { + push (@include_stack, "\$\(top_srcdir\)/$path"); + error ("attempt to translate a top_srcdir include file: $path") if $canonise eq TRUE; + # Distribute any included file. + + # Always use the $(top_srcdir) prefix in DIST_COMMON, + # otherwise OSF make will implicitly copy the included + # file in the build tree during `make distdir' to satisfy + # the dependency. + # (subdircond2.test and subdircond3.test will fail.) + push_dist_common ("\$\(top_srcdir\)/$path"); + } + else + { + $path =~ s/\$\(srcdir\)\///; + push (@include_stack, "\$\(srcdir\)/$path"); + # Always use the $(srcdir) prefix in DIST_COMMON, + # otherwise OSF make will implicitly copy the included + # file in the build tree during `make distdir' to satisfy + # the dependency. + # (subdircond2.test and subdircond3.test will fail.) + push_dist_common ("\$\(srcdir\)/$path"); + $prepend_path = $path; + $prepend_path =~ s/[^\/]*$//; + $path = $relative_dir . "/" . $path if $relative_dir ne '.'; + } + $where->push_context ("`$path' included from here"); + &read_am_file ($path, $where, $prepend_path); + $where->pop_context; +} -# &read_am_file ($AMFILE, $WHERE) +# &read_am_file ($AMFILE, $WHERE, $PREPEND) # ------------------------------- # Read Makefile.am and set up %contents. Simultaneously copy lines # from Makefile.am into $output_trailer, or define variables as # appropriate. NOTE we put rules in the trailer section. We want # user rules to come after our generated stuff. -sub read_am_file ($$) +# Prepend $PREPEND to all file paths if ne "" +sub read_am_file ($$$) { - my ($amfile, $where) = @_; + my ($amfile, $where, $prepend_path) = @_; + my $prepend_macro = $prepend_path; + $prepend_macro =~ s/\//_/; my $am_file = new Automake::XFile ("< $amfile"); verb "reading $amfile"; + verb "prepending $prepend_path" if $prepend_path ne ""; # Keep track of the youngest output dependency. my $mtime = mtime $amfile; @@ -5533,6 +5637,7 @@ sub read_am_file ($$) my $cond = new Automake::Condition @cond_stack; $output_trailer .= $cond->subst_string; $output_trailer .= $_; + error ("can't translate saw-bk, was_rule, $_") if $prepend_path ne ""; } elsif ($prev_state == IN_COMMENT) { @@ -5560,6 +5665,7 @@ sub read_am_file ($$) $last_where, VAR_ASIS) if $cond != FALSE; $comment = $spacing = ''; + # error ("define $last_var_name, $last_var_value") if $prepend_path ne ""; } } } @@ -5611,8 +5717,59 @@ sub read_am_file ($$) $last_var_value = $3 . "\n"; } + if ($last_var_name =~ /_([^_]+)$/o) + { + my $var_suffix = $1; + if ($prepend_path ne "") + { + grep + { + if ($_ eq $var_suffix) + { + $last_var_name = $prepend_macro . $last_var_name; + } + } + @canonised_macro_names; + } + } + + if (!/\\$/) { + if ($last_var_name =~ /_([^_]+)$/o) + { + my $var_suffix = $1; + if ($prepend_path ne "") + { + grep + { + if ($_ eq $var_suffix) + { +# error ("prepending path '$prepend_path' to '$last_var_value' "); + $last_var_value = transform_file_list($prepend_path, $last_var_value); + } + } + @canonised_macro_values; + } + } + + if ($last_var_name =~ /_([^_]+)$/o) + { + my $var_suffix = $1; + if ($prepend_path ne "") + { + grep + { + if ($_ eq $var_suffix) + { +# error ("prepending literal '$prepend_macro' to '$last_var_value' "); + $last_var_value = transform_file_list($prepend_macro, $last_var_value); + } + } + @canonised_macro_lists; + } + } + Automake::Variable::define ($last_var_name, VAR_MAKEFILE, $last_var_type, $cond, $last_var_value, $comment, @@ -5623,35 +5780,11 @@ sub read_am_file ($$) } elsif (/$INCLUDE_PATTERN/o) { - my $path = $1; - - if ($path =~ s/^\$\(top_srcdir\)\///) - { - push (@include_stack, "\$\(top_srcdir\)/$path"); - # Distribute any included file. - - # Always use the $(top_srcdir) prefix in DIST_COMMON, - # otherwise OSF make will implicitly copy the included - # file in the build tree during `make distdir' to satisfy - # the dependency. - # (subdircond2.test and subdircond3.test will fail.) - push_dist_common ("\$\(top_srcdir\)/$path"); - } - else - { - $path =~ s/\$\(srcdir\)\///; - push (@include_stack, "\$\(srcdir\)/$path"); - # Always use the $(srcdir) prefix in DIST_COMMON, - # otherwise OSF make will implicitly copy the included - # file in the build tree during `make distdir' to satisfy - # the dependency. - # (subdircond2.test and subdircond3.test will fail.) - push_dist_common ("\$\(srcdir\)/$path"); - $path = $relative_dir . "/" . $path if $relative_dir ne '.'; - } - $where->push_context ("`$path' included from here"); - &read_am_file ($path, $where); - $where->pop_context; + include $1, $relative_dir, $where, FALSE, @include_stack; + } + elsif (/$SUBDIR_INCLUDE_PATTERN/o) + { + include $1, $relative_dir, $where, TRUE, @include_stack; } else { @@ -5723,7 +5856,7 @@ sub read_main_am_file &define_standard_variables; # Read user file, which might override some of our values. - &read_am_file ($amfile, new Automake::Location); + &read_am_file ($amfile, new Automake::Location, ""); } Index: tests/Makefile.am =================================================================== RCS file: /cvs/automake/automake/tests/Makefile.am,v retrieving revision 1.537 diff -u -p -r1.537 Makefile.am --- tests/Makefile.am 30 Nov 2003 13:35:29 -0000 1.537 +++ tests/Makefile.am 1 Dec 2003 11:02:40 -0000 @@ -431,6 +431,8 @@ subdirbuiltsources.test \ subcond.test \ subcond2.test \ subcond3.test \ +subdir_include.test \ +subdir_include_distcheck.test \ subobj.test \ subobj2.test \ subobj3.test \