ULTRIX 4.5 make fails during rule lookup when it tries to build a
target in a nonexistent directory that might have inference rules
associated with it (i.e., ends with a defined suffix), for example:
% echo 'nonexistent/baz.o: ;' | make -f -
Directory nonexistent/: Make: Cannot open. Stop.
We can work around this problem by using a prerequisite to create
the output directory instead of creating it directly in the rule.
Automake itself actually does this already using dirstamps, so
let's try to patch things to use the same mechanism. As a bonus,
this should reduce the number of mkdir invocations.
This breaks some of the relevant tests which are looking for specific
output. Drop the %reldir% test completely as it appears every usage
in gnulib is for this exact scenario, and patch the subdirectory test
to expect the new output.
open STDIN, "<", $input or die "$input: $!\n" if (defined $input);
my $printed_header = 0;
open STDIN, "<", $input or die "$input: $!\n" if (defined $input);
my $printed_header = 0;
my @cleanfiles;
# Hashes to record make variables used in the automake source. The allvars
my @cleanfiles;
# Hashes to record make variables used in the automake source. The allvars
# the value is always set to 1.
my (%allvars, %sourcevars);
# the value is always set to 1.
my (%allvars, %sourcevars);
+# Collected names of subdirectories that may need to be created at build time.
+# The keys are directory names, the values are targets.
+my %gl_dirstamps;
+
+# State to drop MKDIR_P lines that have been replaced by dirstamps.
+my ($have_dirstamp) = (0);
+
sub drop {
undef $_;
next;
sub drop {
undef $_;
next;
@left = map(mangle_file($_), @left);
@right = map(mangle_file($_), @right);
@left = map(mangle_file($_), @left);
@right = map(mangle_file($_), @right);
- return join(" ", @left) . ": " . join(" ", @right) . "\n";
+ my @dirstamps = get_dirstamps(@left);
+
+ return join(" ", @left) . ": " . join(" ", @dirstamps, @right) . "\n";
+}
+
+sub get_dirstamps {
+ my %h;
+
+ foreach (@_) {
+ next unless $_[0] =~ m|^(lib(/.*)?)/[^/]*$|;
+
+ $h{$gl_dirstamps{$1} = "$1/\$(am__dirstamp)"} = 1;
+ }
+
+ return keys %h;
# ordinary variable so we can deal with them later.
s/BUILT_SOURCES/gnulib_core_headers/;
# ordinary variable so we can deal with them later.
s/BUILT_SOURCES/gnulib_core_headers/;
- # Rules for "toplevel" header files do not include commands to create
- # the target directory; let's add that.
- if (defined $check_mkdir) {
- if (/gl_V_at/ || /AM_V_GEN/ and not /MKDIR_P/) {
- my $dir = "lib/$check_mkdir";
- $dir =~ s|/[^/]*||;
-
- print "\t\$(AM_V_GEN)\$(MKDIR_P) $dir\n";
- s/AM_V_GEN|gl_V_at/AM_V_at/;
- }
- undef $check_mkdir
- }
-
# Targets are similar to variables: the target and its dependencies
# need to be mangled.
if (/^([^\t:]*):/) {
# Targets are similar to variables: the target and its dependencies
# need to be mangled.
if (/^([^\t:]*):/) {
+ $have_dirstamp = /am__dirstamp/;
}
# MKDIR_P commands need to be fixed up; in principle Gnulib could also
}
# MKDIR_P commands need to be fixed up; in principle Gnulib could also
# component.
s/t-\$@/\$\@-t/g;
# component.
s/t-\$@/\$\@-t/g;
- # Finally, $(srcdir), $(builddir) and %reldir% need to be fixed up.
+ # $(srcdir), $(builddir) and %reldir% need to be fixed up.
s:\$\(srcdir\):\$\(top_srcdir\)/lib:g;
s:\$\(builddir\):\$\(top_builddir\)/lib:g;
s:%reldir%:lib:g;
s:\$\(srcdir\):\$\(top_srcdir\)/lib:g;
s:\$\(builddir\):\$\(top_builddir\)/lib:g;
s:%reldir%:lib:g;
+
+ # If we installed a dirstamp prerequisite for this target, don't
+ # emit the mkdir line which creates the output directory.
+ if ($have_dirstamp && m|\$[({]MKDIR_P[})][ '"]*lib/|) {
+ drop unless s/^(\t\$[({](AM_V_GEN|gl_V_at)[})]).*/\1:/;
+ }
+ undef $have_dirstamp if /^\t/;
} continue { s/(\n.)/\\\1/g; print; };
} continue { s/(\n.)/\\\1/g; print; };
+# Define a bunch of fake programs which will ensure Automake produces the
+# necessary dirstamp rules, as unfortunately we cannot know in advance which
+# will be generated, and the usual Automake behaviour where generated rules
+# are suppressed by rules in Makefile.am doesn't actaully work for these.
+print <<EOF foreach (keys %gl_dirstamps);
+EXTRA_PROGRAMS += $_/gl-dirstamp
+${\(y|/|_|r)}_gl_dirstamp_SOURCES =
+EOF
+
print <<'EOF' if ($use_libtool);
gnulib_lt_objects = $(libgnu_la_OBJECTS) $(gl_LTLIBOBJS)
gnulib_objects = $(gnulib_lt_objects)
print <<'EOF' if ($use_libtool);
gnulib_lt_objects = $(libgnu_la_OBJECTS) $(gl_LTLIBOBJS)
gnulib_objects = $(gnulib_lt_objects)
-AT_SETUP([fix-gnulib.pl %reldir% substitution])
-AT_KEYWORDS([fix-gnulib perl script scripts])
-
-test_gnulib_mk sys_types >test.mk.in
-AT_CHECK([grep '%reldir%' test.mk.in >/dev/null || exit 99])
-
-sed -n <test.mk.in >expout '
-$G
-$p
-$b
-/^## begin gnulib/,/^## end gnulib/!b
-/^#/{
-p
-b
-}
-s|(srcdir)|(top_srcdir)|
-s|%reldir%|lib|
-s|BUILT_SOURCES|gnulib_core_headers|
-s|sys[[/_]]|lib/&|g
-/^MOSTLYCLEANFILES/{
-h
-b
-}
-p'
-
-AT_CHECK([test_fix_gnulib -i test.mk.in -o test.mk || exit
-sed -n -e '/^## begin gnulib/,/^## end gnulib/p' \
- -e '/CLEANFILES/p' test.mk],
-[0], [expout])
-
-AT_CLEANUP
-
AT_SETUP([fix-gnulib.pl warning removal])
AT_KEYWORDS([fix-gnulib perl script scripts])
AT_SETUP([fix-gnulib.pl warning removal])
AT_KEYWORDS([fix-gnulib perl script scripts])
AT_SETUP([fix-gnulib.pl header directory creation])
AT_KEYWORDS([fix-gnulib perl script scripts])
AT_SETUP([fix-gnulib.pl header directory creation])
AT_KEYWORDS([fix-gnulib perl script scripts])
-AT_DATA([extract.sed],
-[[/AM_V_GEN/b ok
-/gl_V_at/b ok
-s/:.*/:/
-h
-b
-:ok
-s/'//g
-x
-G
-p
-n
-s/[)].*/)/
-p
+AT_DATA([extract.awk],
+[[$0 !~ /^\t/ && $1 ~ /:$/ {
+ target=$1;
+
+ for (i = 2; i <= NF; i++) {
+ if ($i ~ /am__dirstamp/)
+ target = target " " $i;
+ }
+
+ next;
+}
+
+target != "" && sub(/[$][({](AM_V_GEN|gl_V_at)[})].*$/, "[OK]") {
+ print target, $1;
+}
+
+{ target=""; }
]])
test_gnulib_mk alloca-opt sys_types stddef >test.mk.in
AT_CHECK([test_fix_gnulib -i test.mk.in -o test.mk || exit
]])
test_gnulib_mk alloca-opt sys_types stddef >test.mk.in
AT_CHECK([test_fix_gnulib -i test.mk.in -o test.mk || exit
-sed -n -f extract.sed test.mk], [0],
-[[lib/alloca.h:
- $(AM_V_GEN)$(MKDIR_P) lib
- $(AM_V_at)
-lib/sys/types.h:
- $(AM_V_GEN)$(MKDIR_P) lib/sys
- $(AM_V_at)
-lib/stddef.h:
- $(AM_V_GEN)$(MKDIR_P) lib
- $(AM_V_at)
+$AWK -f extract.awk test.mk], [0],
+[[lib/alloca.h: lib/$(am__dirstamp) [OK]
+lib/sys/types.h: lib/sys/$(am__dirstamp) [OK]
+lib/stddef.h: lib/$(am__dirstamp) [OK]