Reported, with initial patch, by Gisle Vanem <gvanem@online.no>
* src/main.c (find_and_set_default_shell) [W32]: Pass search_token
directly to w32ify: no need to make a copy first. When we need to
construct a path, use snprintf() to be sure we don't overwrite
the locally-allocated buffer.
* src/w32/pathstuff.c (w32ify) [W32]: Use the malloc version of
_fullpath(), followed by strncpy(), to avoid overwriting buffers.
Introduce non-deterministic ordering into goal and prerequisite
traversal to help tease out inconsistent failures that may happen
when running in parallel build mode.
Introduce second order into each dependency chain:
1. Existing order is syntactic order reachable via 'dep->next'
2. New order is shuffled order stored as 'dep->shuf' in each 'dep'
When updating goals and prerequisites and '--shuffle' is provided,
use the shuffled order to walk the graph. When automatic variable
are set always use the syntactic order of parameters.
* Makefile.am: Add new src/shuffle.c and src/shuffle.h file.
* build_w32.bat: Ditto.
* builddos.bat: Ditto.
* makefile.com: Ditto.
* po/POTFILES.in: Ditto.
* doc/make.texi: Add documentation for --shuffle.
* doc/make.1: Ditto.
* src/dep.h (DEP): Add the shuf pointer.
* src/filedef.h (struct file): Add was_shuffled flag.
* src/main.c: (shuffle_mode): Global flag for the shuffle mode.
(usage): Add the --shuffle option.
(switches): Ditto.
(main): Set shuffle_mode based on the command line parameter.
Reshuffle prerequisites if requested.
* src/remake.c (update_goal_chain): Walk the shuffled list if enabled.
(update_file_1): Ditto.
* src/shuffle.h: Provide an interface for shuffling prerequisites.
* src/shuffle.c: Implement option parsing and prerequisite shuffling.
* tests/scripts/options/shuffle: Test shuffle option and modes.
* src/makeint.h: Declare it.
* src/arscan.c (ar_scan): Replace atoi() calls with make_toui().
Modify some integral types to be more correct.
* src/job.c (load_too_high): Replace atoi() calls with make_toui().
* src/main.c (main): Ditto.
(decode_switches): Ditto.
memcmp() is always faster than strcmp(). In places where we already
know that both buffers have sufficient size, replace strcmp() with
memcmp().
* src/main.c (main): Replace strncmp() with memcmp()==0.
* src/read.c (word1eq): Ditto.
* src/commands.c (set_file_variables): Ditto.
* src/function.c (func_filter_filterout): Ditto.
(a_word_hash_cmp): Use STRING_N_COMPARE since we know the length.
(func_sort): Replace strcmp() with memcmp().
The standard requires that tolower() returns its argument if there's
no valid lowercase conversion: it's not necessary to check isupper()
before invoking tolower().
Comparing the performance of the old ISTRING_HASH to the new one
on all the files present in GLIBC.
Data Type Old Time New Time
Alternating case 24985.754 13883.422
random case 35211.777 13569.051
all lower 18818.974 13706.645
all upper 38859.454 13506.315
* src/hash.h (ISTRING_HASH_1): Omit isupper() check.
(ISTRING_HASH_2): Ditto.
During second expansion of pattern rules only the first pattern in
each "group" was being substituted. E.g. in this makefile:
.SECONDEXPANSION:
all: hello.x
%.x: $$(wordlist 1, 99, %.1 %.%.2) ; $(info $@ from $^)
hello.1 hello.\%.2 \%.1 \%.\%.2: ;
the output would build "hello.1" and "%.%.2" because each function
is considered a single "word" and only the first pattern is replaced.
Fix the expansion so each whitespace-separated string is considered a
word and the first pattern is replaced, giving "hello.1" and
"hello.%.2".
* src/rule.c (snap_implicit_rules): Keep enough space to replace %
with $(*F) if necessary.
* src/implicit.c (pattern_search): During second expansion break each
get_next_word result into individual words and replace the first % in
each with $* or $(*F) as needed.
* tests/scripts/features/patternrules: Add tests for variations.
The hash function we use can yield different results on big- and
little-endian systems which makes test output different. Choose
names to avoid this.
* tests/scripts/features/patternrules: Choose portable target names.
* tests/scripts/features/se_explicit: Ditto.
* tests/scripts/features/se_implicit: Ditto.
If -R is given on the command line it implies -r as well; make this
same assumption if -R is provided in MAKEFLAGS set in the makefile.
* src/main.c (main): Check no_builtin_variables_flag after reading
makefiles.
* tests/scripts/options/dash-r: Add a test.
Previously we always used the file->stem value as our stem in
set_file_variables(); when that wasn't correct we had to temporarily
set that value while the function was called, then reset it afterward.
This led to issues (for example when we assumed the stem was a cached
string but it wasn't).
Avoid this by passing in the stem as an argument so that different
values can be provided.
Add tests to verify this.
* src/commands.c (set_file_variables): Take second parameter stem to
relieve the callers of set_file_variables() from setting/restoring
file->stem.
* src/commands.h (set_file_variables): Ditto.
(execute_file_commands): Pass file->stem to set_file_variables().
* src/file.c (expand_deps): Pass d->stem to set_file_variables() and
remove set and restore of file->stem.
* src/implicit.c (pattern_search): Pass stem to set_file_variables()
and remove set and restore of file->stem.
* tests/scripts/features/se_explicit: Add new tests.
* tests/scripts/features/se_implicit: Ditto.
* tests/scripts/features/se_statpat: Ditto.
* tests/scripts/variables/automatic: Ditto.
During normal pattern rule expansion only the first pattern (%) is
expanded; however during secondary expansion all patterns were
expanded. Modify secondary expansion to match the behavior of normal
expansion.
Implementation tweaked by Paul Smith <psmith@gnu.org>
* src/file.c (expand_deps): Don't use subst_expand() which replaces
all % with $*: instead replace only the first one, by hand.
Fix a memory leak where the dep structure was not always freed.
* tests/scripts/features/statipattrules: Use .RECIPEPREFIX not TAB.
Add a series of tests verifying that static pattern rules with and
without secondary expansion both return the same results.
Original patch from Dmitry Goncharov <dgoncharov@users.sf.net>
Fix the ar flags to match the default values in make. If the
U option is supported, add it to the end not the beginning,
since ARFLAGS now starts with a "-".
* tests/test_driver.pl: Add defaults for global variables.
(get_osname): Preserve $osname if it's set from $^O
* tests/scripts/features/archive: Set the default arflags.
If "U" is available add it to the end of the flags.
If the re-exec fails, be sure to remove a temp makefile that was
created to read from stdin.
* src/job.c (exec_command): Return on failure.
(child_execute_job): Call exit if exec_command returns.
* src/job.h (exec_command): Don't mark as NORETURN.
* src/main.c (main): Unlink stdin temporary file if re-exec fails.
* tests/run_make_tests.pl: Get value for ERR_nonexe_file/ERR_exe_dir.
* tests/scripts/features/temp_stdin: Test that temp file unlink works.
The -f, -file, and --makefile options were not properly handled when
re-exec'ing due to makefile updates. This problem, plus a patch and
tests, was reported by Dmitry Goncharov <dgoncharov@users.sf.net>.
While examining this I found another bug: after re-exec we forgot the
batch file was temporary and never deleted it.
I decided to fix all these problems at once using a different fix
than Dmitry's: I created a new internal-only command-line option,
--temp-stdin. When reconstructing the make options for a re-exec,
replace the -f/--file/--makefile option that reads from stdin with
--temp-stdin=<filename> so that the re-exec'd version of make knows
it's a temporary batch file and will delete it.
We no longer need to add the -o options because the re-exec'd make
knows this is a temporary makefile and treats it as such.
To simplify, replace the --file and --makefile options taking a
filename, with just -f<filename> on re-exec.
Some examples of the rewrite:
User command line Re-exec command line
----------------- --------------------
-f- --temp-stdin=<batch>
--file - --temp-stdin=<batch>
-f - --makefile a.mk --temp-stdin=<batch> -fa.mk
--file=a.mk -fa.mk
-fa.mk -fa.mk
-Rf a.mk -Rf a.mk
-Rf- -R --temp-stdin=<batch>
* src/main.c (stdin_offset): Remember the offset into the makefiles
list of the batch file read from stdin. Remove stdin_nm.
(struct command_switch): Create a new --temp-stdin option, which
also updates the makefiles list.
(main): Add the temporary filename to the string cache.
Move the tempfile handling after checking makefile arguments for "-"
so that files provided via --temp-stdin are also handled specially.
When rewriting re-exec options, we may need one more than we had
originally so create a new argv list. Walk through the original
list and convert it to the new list, following the above process.
(decode_switches): Set the stdin_offset flag if we see --temp-stdin.
* tests/scripts/options/dash-f: Add many more tests, provided by
Dmitry Goncharov <dgoncharov@users.sf.net>.
The fix for SV 60595 causes make to re-execute when the makefile is
read from stdin. E.g.
$ printf 'all:; $(info hello)' | make -sf -
Reported by Sergei Trofimovich <siarheit@google.com>
Test added by Paul Smith <psmith@gnu.org>
* src/main.c (main): Set the mtime of the stdin temporary file.
* tests/scripts/features/reinvoke: Add a test.
We already use undef makefile strings to mean "re-use the previous
makefile", so if the string is empty we'll assume it means "don't
use a makefile at all" (don't add -f).
* tests/run_make_tests.pl (run_make_test): If the makefile string
is empty, don't create a makefile or add -f.
* tests/scripts/features/include: Change empty makefile to "\n".
* tests/scripts/misc/close_stdout: Ditto.
* tests/scripts/options/dash-r: Ditto.
* src/main.c (main): Show the temp filename on error. Also on
Windows prefer TMP, then TEMP, and only lastly TMPDIR.
* tests/test_driver.pl: Add TMP, TEMP, and USERPROFILE to the list
of environment variables to preserve.
If a $(shell ...) invocation failed due to a command-not-found error,
make wrote the stdout of that shell to our stderr for some reason.
That seems very wrong.
If the command's stderr was not redirected then its output would have
already been written to its stderr, and if it was redirected then we
shouldn't take it upon ourselves to force it to go to stderr!
* src/function.c (func_shell_base): Append shell stdout even if the
shell command failed.
* tests/run_make_tests.pl: Determine the error generated for
command-not-found situations.
* tests/scripts/functions/shell: Verify that redirecting stderr to
stdout will behave properly if the command is not found.
If a prereq of a pattern is explicitly mentioned as a prereq of an
unrelated rule, it should not be considered an intermediate file.
* tests/scripts/features/double_colon: Add tests mentioning unrelated
explicit targets.
* tests/scripts/features/grouped_targets: Ditto.
* tests/scripts/features/implicit_search: Ditto.
* tests/scripts/features/patternrules: Ditto.
* tests/scripts/features/se_implicit: Ditto.
* tests/scripts/features/statipattrules: Ditto.
Since $(info ) function output is written using two system calls for
the message and the newline, it's possible for output from another
parallel make job to sneak in between them.
Reported by Paul Eggert <eggert@cs.ucla.edu>, who saw the report from
Lars Ingebrigtsen <https://bugs.gnu.org/53358>.
* src/function.c (func_error): Paul provided a fix but instead I
rewrote the entire function: it's not possible for it to be invoked
with anything other than exactly one argument so don't worry about
re-combining the arguments.