Commit graph

417 commits

Author SHA1 Message Date
Paul Smith
4da2055a10 Rework output sync to lock a temp file on POSIX
Some POSIX systems do not allow locks to be taken on non-files, such
as pipes.  This is a problem since very often make is invoked with
its stdout redirected to a pipe.  Also, if stdout is redirected to a
file that already has a lock on it for some other reason (perhaps a
shared file such as /dev/null) it can cause a hang.

This means our previous method of locking stdout, although it had some
nice advantages, is not portable enough.  Instead, use a temporary
file and take the lock on that.  We pass the name of the file to child
make processes.  On Windows we continue to use a shared mutex for
output sync.

Remove POSIX emulation functions like fcntl from Windows; instead
follow the lead of the jobserver and create an interface in os.h for
output sync, and move the OS-specific content to posixos.c and
w32os.c.

* NEWS: Add a note.
* src/makeint.h (ALL_SET): Check that all bits are set.
* src/os.h: Add bits for checking the state of stdin/stdout/stderr.
Add prototypes for OS-specific output sync methods.
* src/posixos.c (check_io_state): Determine the status of stdin,
stdout, stderr an return a suite of bits describing them.
(osync_enabled): If the global variable holding the FD of the lock
file (osync_handle) is valid return true.
(osync_setup): Create a temporary file and remember its name in a
global variable (osync_tmpfile), and set osync_handle.
(osync_get_mutex): If output sync is enabled, return the filename
of the lock file prefixed with "fnm:" to denote a filename.
(osync_parse_mutex): If the provided filename has the wrong format
disable output sync.  Else open the lock file and set osync_handle.
(osync_clear): Close osync_handle.  If we're the parent make, then
also unlink the temporary file.
(osync_acquire): Take a lock on the osync_handle descriptor.
(osync_release): Release the lock on the osync_handle descriptor.
(fd_set_append): Add APPEND mode to a file descriptor.
* src/w32/w32os.c: Perform the same actions as posixos.c, copying
the details from src/w32/compat/posixfcn.c.  Use a mutex rather
than locking a temporary file.
* src/output.h: Remove all the OS-specific content.
* src/output.c: Remove all the OS-specific content.
(set_append_mode): Remove and replace with fd_set_append().
(sync_init): Remove and replace with check_io_state().
(acquire_semaphore): Remove and replace with osync_acquire().
(release_semaphore): Remove and replace with osync_release().
(setup_tmpfile): If the IO state is not obtained, get it.  If stdout
and/or stderr are valid, set up a tempfile to capture them.
(output_init): Set io_state if not set already, and check it when
deciding whether to close stdout on exit.
* src/main.c (main): If we're syncing, set up the mutex using the
new osync_setup() / osync_parse_mutex() methods.
(prepare_mutex_handl_string): Replace with osync_parse_mutex().
(die): Call osync_clear().
* src/w32/compat/posixfcn.c: Remove implementations of fcntl(),
record_sync_mutex(), create_mutex(), and same_stream().
2022-08-30 15:44:43 -04:00
Paul Smith
5eff618c8c test_driver: check for leftover temp files after each test
Reset the temp directory for every test to a local directory, then
after each test see if any new temp files were created and not
deleted: if they were then fail the test.  Rather than delete the
temp files we leave them there and avoid reporting files that were
seen before, so the user can investigate them.

Rewrite the temp_stdin tests to rely on this built-in behavior
rather than implementing the checks directly.

* tests/test_driver.pl: Create a $TEMPDIR variable pointing to a
temporary directory outside the test temp directory.
(toplevel) Before starting any tests create a temp directory and set
the POSIX and Windows temp directory environment variables to use it.
(compare_output) Check the contents of the temp directory.  If any
new files have appeared, fail the test.
* tests/scripts/features/temp_stdin: Remove check_tempfile() and
all users of it, plus setting of temp environment variables.
2022-08-29 00:09:10 -04:00
Dmitry Goncharov
10e130b207 [SV 62908] Don't free fifo_name twice during error handling
* src/posixos.c (jobserver_setup): Set fifo_name to NULL after free.
* tests/scripts/features/jobserver: Add tests.
2022-08-22 21:27:08 -04:00
Paul Smith
62da1c45e5 Fix bootstrap.bat for bootstrapping on Windows
* README.git: Clarify that these methods are lightly tested.
* build_w32.bat: Don't support any config step: fail if not completed.
Move the config steps into bootstrap.bat.  Don't print compile lines
by default and add a --verbose option to show them.
* bootstrap.bat: Ensure we have curl and sed before we do anything.
Pull the latest necessary files from gnulib.  Create a convert.sed
script that can update the various template files, and update
Basic.mk, config.h.W32, and gmk-default.h.
* tests/run_make_tests.pl: Remove CRLF rather than using chop.  If we
run perl in Git for Bash it seems to handle newlines differently.
* tests/scripts/features/temp_stdin: Remove the make copy and close
STDIN so we can delete the temp file on Windows.
* .gitignore: Ignore the convert.sed script.
2022-08-22 21:19:18 -04:00
Paul Smith
7ad2593b2d Support implementing the jobserver using named pipes
Using anonymous pipes for jobserver support has some advantages:
for example there is nothing on disk that needs to be cleaned up.
However it has many obscure problems, related to the fact that in
order for it to work we need to ensure these resources are properly
passed through to child processes that want to use the jobserver.
At the same time we don't want to pass the pipe to process which
DON'T know about the jobserver.

Other processes can open file descriptors which we then think are
our jobserver, but aren't.  And, we open the pipe file descriptors
in blocking mode which doesn't work for all users.

See issues such as SV 57178, SV 57242, and SV 62397

To avoid these issues, use named pipes (on systems where they are
available) instead of anonoymous pipes.  This simplifies many things:
we never need to pass open file descriptors to our children; they
can open the jobserver named pipe.  We don't need to worry about
recursive vs. non-recursive children.  Users don't have to "pass
through" the resources if they are invoking sub-makes.  Each child
can open its own file descriptor and set blocking as needed.

The downside is the named pipe exists on disk and so must be cleaned
up when the "top-level" make instance exits.

In order to allow make to continue to be used in build systems where
older versions of GNU make, or other tools that want to use the
jobserver, but don't understand named pipes, introduce a new option
--jobserver-style that allows the user to choose anonymous pipes.

* NEWS: Announce the change and the --jobserver-style option.
* doc/make.1: Add --jobserver-style documentation.
* doc/make.texi (Special Variables): Add missing items to .FEATURES.
(Options Summary): Add --jobserver-style.
(POSIX Jobserver): Named pipes, changes to --jobserver-auth, and the
--jobserver-style option.
(Windows Jobserver): Document --jobserver-style for Windows.
* configure.ac: Check for mkfifo.
* src/config.h-vms.template: Undefined HAVE_MKFIFO.
* src/config.h.W32.template: Ditto.
* src/main.c: Add jobserver-style as a new command line option.
(main): Add jobserver-fifo to .FEATURES if supported.  Pass the style
option to jobserver_setup().
* src/os.h (jobserver_setup): Accept a style string option.
* src/posixos.c (enum js_type): Enumeration of the jobserver style.
(js_type): Which style we are currently using.
(fifo_name): The path to the named pipe (if in use).
(jobserver_setup): If no style is given, or "fifo" is given, set up a
named pipe: get a temporary file and use mkfifo() on it, then open it
for reading and writing.  If something fails fall back to anonymous
pipes.
(jobserver_parse_auth): Parse jobserver-auth to determine the style.
If we are using a named pipe, open it.  If we're using anonymous pipes
ensure they're valid as before.
(jobserver_get_invalid_auth): Don't invalidate the jobserver when
using named pipes.
(jobserver_clear): Clean up memory used for named pipes.
(jobserver_acquire_all): Unlink the named pipe when done.
* src/w32/w32os.c (jobserver_setup): Check the style argument.
* tests/scripts/features/jobserver: Use --jobserver-style to test
the anonymous pipe behavior, and also test named pipe/semaphore
behavior.  Check invalid jobserver-style options.
* tests/scripts/functions/shell: Use --jobserver-style to test the
anonymous pipe behavior, and also test named pipe/semaphore
behavior.
2022-08-02 23:36:35 -04:00
Dmitry Goncharov
07eea3aa49 [SV 62706] Only second-expand targets that might be built
Second-expand only the prerequisites of the targets being built.
Defer second-expanding the prerequisites of targets until we need
to decide if they should be built.

* NEWS: Mention the change in behavior.
* doc/make.texi (Secondary Expansion): Document the new behavior.
* src/filedef.h (struct file): Add flag snapped.
(expand_deps): Declare a function to second expand the
prerequisites of a target.
* src/file.c (rehash_file): Merge flag snapped.
(expand_deps): Remove qualifier static. Check flag snapped.
(snap_deps): Remove the loop which performed second expansion for all
targets.
* src/remake.c (update_file_1): Second expand the prerequisites of
the considered target.
* tests/scripts/features/se_explicit: Add tests.
* tests/scripts/features/se_implicit: Ditto.
* tests/scripts/features/se_statpat: Ditto.
2022-07-30 18:40:28 -04:00
Paul Smith
16e14b4114 Disable the jobserver in non-recursive children
Savannah issues such as SV 57242 and SV 62397 show how passing
references to closed file descriptors via the --jobserver-auth option
in MAKEFLAGS can lead to problematic outcomes.

When computing the child environment for a non-recursive shell, add
an extra option to MAKEFLAGS to disable the file descriptors for the
jobserver.

Unfortunately this doesn't modify the value of the make variable
MAKEFLAGS, it only modifies the value of the sub-shell environment
variable MAKEFLAGS.  This can lead to confusion if the user is not
considering the distinction.

* src/makeint.h: Publish the jobserver-auth value.  Add a global
definition of the name of the command line option.
* src/os.h (jobserver_get_invalid_auth): New function to return a
string invalidating the jobserver-auth option.
* src/w32/w32os.c (jobserver_get_invaid_auth): Implement it.  On
Windows we use a semaphore so there's no need to invalidate.
* src/posixos.c (jobserver_parse_auth): If we parse the invalid
auth string, don't set up the jobserver.
(jobserver_get_invalid_auth): Return an invalid option.
* src/variable.h (target_environment): Specify if the target
environment is for a recursive shell or non-recursive shell.
* src/variable.c (target_environment): Move checking for MAKELEVEL
into the loop rather than doing it at the end.
Along with this, check for MAKEFLAGS and MFLAGS, and update them
based on whether we're invoking a recursive or non-recursive child,
and also on whether it's necessary to invalidate the jobserver.
* src/function.c (func_shell_base): Shell functions can never be
recursive to pass 0 to target_environment().
* src/job.c (start_job_command): Specify whether the child is
recursive when calling target_environment().
* src/main.c: Export jobserver_auth.  sync_mutex doesn't need to
be exported.  Use the global definition for the option name.
* tests/scripts/variables/MAKEFLAGS: Add tests for $MAKEFLAGS.
2022-07-30 18:40:28 -04:00
Paul Smith
77881d2281 Ensure that MAKEFLAGS is set when invoking $(shell ...)
* src/main.c (main): Don't reset the jobserver if the number of
slots has not changed.
(define_makeflags): Add all normal flags even when ALL is not set.
* tests/scripts/functions/shell: Test invoking make in $(shell ...).
* tests/scripts/variables/MAKEFLAGS: Test the value of MAKEFLAGS in
$(shell ...).
2022-07-30 18:40:28 -04:00
Paul Smith
98da874c43 [SV 10593] Export variables to $(shell ...) commands
Export all variables, including exported makefile variables, when
invoking a shell for the $(shell ...) function.  If we detect a
recursive variable expansion, silently ignore that variable and do
not export it.  We do print a debug message.

* NEWS: Announce the potential backward-incompatibility.
* doc/make.texi (Shell Function): Document the export behavior.
* src/main.c (main): Add "shell-export" to .FEATURES.
* src/job.h: New function to free struct childbase.
* src/job.c (free_childbase): Implement it; call from free_child.
* src/function.c (func_shell_base): Use target_environment() to
obtain the proper environment for the shell function.
Use free_childbase() to free memory.
(windows32_openpipe): Don't reset the environment: the caller
already provided a proper PATH variable in envp.
* src/variable.c (target_environment): If we detect a recursive
expansion and we're called from func_shell, ignore the variable.
(sync_Path_environment): Simplify and reduce memory allocation.
* tests/scripts/functions/shell: Add tests for this.
2022-07-09 10:44:21 -04:00
Dmitry Goncharov
88d6c22a48 [SV 62650] Show correct warning when combining targets
* src/file.c (rehash_file): Fix warning message.
(rehash_file): Fix comment to match the behavior.
* tests/scripts/features/se_explicit: Fix test.
* tests/scripts/features/mult_rules: Add a new test.
2022-07-09 10:44:00 -04:00
Dmitry Goncharov
c3b39d0654 [SV 62514] Honor command line interface flags
Commit f2771aa614 introduced a bug where some switches were left out
of MAKEFLAGS.  Instead of resetting switches, get the same results by
filtering out duplicates.

* src/makeint.h: Remove reset_switches.
* src/main.c: (reset_switches): Remove reset_switches.
* (main): Remove call to reset_switches.
* (decode_switches): Filter out duplicate flags.
* src/variable.c: (set_special_var):  Remove call to reset_switches.
* tests/scripts/variables/MAKEFLAGS: Verify that duplicate flags are
properly filtered out.
2022-07-09 10:43:33 -04:00
Paul Smith
3ec497f8f8 Don't add GNUMAKEFLAGS to the environment
If GNUMAKEFLAGS was not present in the environment when we started,
don't add it.

* src/main.c (main): Don't mess with GNUMAKEFLAGS unless it exists.
* tests/scripts/variables/GNUMAKEFLAGS: Test this behavior.
2022-06-19 14:35:27 -04:00
Paul Smith
59abb46bc9 * tests/scripts/features/temp_stdin: Remove nested "my"
* tests/scripts/features/statipattrules: Remove unset variable refs.
2022-06-04 19:04:37 -04:00
Dmitry Goncharov
6d6f12b0c3 * tests/scripts/features/archives: Fix typo 2022-06-04 19:04:37 -04:00
Sergei Trofimovich
621d3196fa [SV 62100] Add '--shuffle' option support
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.
2022-06-04 19:04:37 -04:00
Dmitry Goncharov
668eda0527 [SV 62206] Fix %-substitution in second expansion of pattern rules
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.
2022-04-24 17:52:07 -04:00
Dmitry Goncharov
4e1be4a60c [SV 62175] Rework secondary expansion tests
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.
2022-04-24 14:56:26 -04:00
Paul Smith
2da3bb46f2 * tests/scripts/options/dash-f: [SV 62118] Close STDIN
On Windows we can't delete open files, so close STDIN before
removing the temporary input file.
2022-04-24 13:48:03 -04:00
Paul Smith
b264d3d4f8 * tests/scripts/features/reinvoke: [SV 62088] Close STDIN
On Windows we can't delete open files, so close STDIN before
removing the temporary input file.
2022-04-24 13:48:03 -04:00
Dmitry Goncharov
f14824878d [SV 62356] If -R is set in the makefile, disable -r
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.
2022-04-24 10:39:32 -04:00
Dmitry Goncharov
8c2aa889bb [SV 62324] Simplify set_file_variables by passing in the stem
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.
2022-04-24 10:39:32 -04:00
Dmitry Goncharov
bb21dd4d2d [SV 62278] Only expand the first pattern during secondary expansion
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.
2022-04-24 10:39:32 -04:00
Paul Smith
88ceff8b2f [SV 62173] Fix archive tests for non-GNU systems
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.
2022-04-24 10:39:32 -04:00
Dmitry Goncharov
9755d4c09c * tests/scripts/options/dash-l: [SV 62172] Skip if not available 2022-04-24 10:39:32 -04:00
Dmitry Goncharov
949c0464a9 [SV 62145] Remove a stdin temp file on re-exec failure.
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.
2022-04-24 10:39:32 -04:00
Paul Smith
416664b1e7 * tests/scripts/features/errors: Fix Perl warnings
* tests/scripts/options/dash-f: Ditto.
2022-04-18 16:57:06 -04:00
Paul Smith
667d70eac2 [SV 62118] Correctly handle -f- options on re-exec
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>.
2022-02-27 18:01:13 -05:00
Paul Smith
b9078e5bd3 * tests/scripts/variables/MAKE_RESTARTS: Remove TAB chars 2022-02-27 18:01:13 -05:00
Paul Smith
236589642e Remove extraneous characters from fatal() calls
The fatal() method adds ".  Stop.\n" to every message.

* src/amiga.c (MyExecute): Remove newline from fatal() message.
* src/job.c (<various>): Ditto.
* src/file.c (snap_deps): Remove "." from fatal() message.
* src/main.c (main): Ditto.
* src/load.c: Ditto.
* tests/scripts/targets/NOTINTERMEDIATE: Fix expected output.
2022-02-27 18:01:13 -05:00
Dmitry Goncharov
40a6751abf [SV 62088] Avoid re-exec due to stdin.
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.
2022-02-27 18:00:47 -05:00
Paul Smith
1bc35a7ae7 tests: Allow run_make_test() to avoid passing -f
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.
2022-02-27 17:47:42 -05:00
Paul Smith
342a9bb54b Don't write $(shell ...) stdout to stderr on failure
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.
2022-02-06 18:46:32 -05:00
Dmitry Goncharov
1fd0bfaf1e [SV 61805] Support quoted whitespace in .SHELLFLAGS with .ONESHELL
* src/job.c (construct_command_argv_internal): Call recursively to
parse .SHELLFLAGS when .ONESHELL is active.
* tests/scripts/targets/ONESHELL: Add tests.
2022-02-06 18:46:32 -05:00
Paul Smith
8eb171e469 * tests/scripts/features/double_colon: Update for modern tests. 2022-02-06 18:46:32 -05:00
Paul Smith
7154e316b7 * tests/scripts/features/implicit_search: Add -r for safety. 2022-02-06 18:46:32 -05:00
Dmitry Goncharov
f3e345c869 [SV 48643] Add more tests of intermediates and unrelated targets
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.
2022-02-06 18:46:32 -05:00
Paul Smith
cbe0d2e47f * tests/scripts/features/implicit_search: [SV 48643] Cleanups. 2022-02-06 18:46:32 -05:00
Jouke Witteveen
2b25eac587 * src/function.c (parse_textint): Handle ints without 0 properly.
* tests/scripts/functions/intcmp: Add tests for values without 0.
2022-01-17 19:11:59 -05:00
Paul Smith
e72c5e021f [SV 61226] Revert changes to detect missing included files
The fix for SV 60595 introduced a backward-incompatibility: rules that
purported to rebuild included files, but didn't actually do so, were
treated as errors whereas before they were ignored.  This breaks a
common idiom in makefiles where an empty recipe is created for an
included makefile so make doesn't complain if it doesn't exist.

Unfortunately this means make cannot diagnose some types of errors.

Extra tests supplied by Dmitry Goncharov <dgoncharov@users.sf.net>.

* doc/make.texi (Including Other Makefiles): Clarify this behavior.
* src/main.c (main): Don't run the new check-for-errors behavior.
* tests/scripts/features/reinvoke: Reset tests of the "old" behavior
and add new tests for this situation.
2022-01-17 18:45:47 -05:00
Paul Smith
320714ae85 * tests/scripts/targets/INTERMEDIATE: Rewrite for new test method 2021-12-29 15:27:04 -05:00
Paul Smith
6682fbc2cb Do not force targets to be SECONDARY
In SV 43677 we forced targets to be secondary if we found an
intermediate file that was listed as a prerequisite of another
target.  This overrides .INTERMEDIATE settings, so doesn't work.
Now that we have an is_explicit flag in targets, use that instead.

* src/implicit.c (pattern_search): Remove setting of secondary.
Preserve the value of the is_explicit flag when creating a new
file target, and consider it when setting the intermediate flag.
* tests/scripts/features/patternrules: Add a test w/out INTERMEDIATE
* tests/scripts/targets/INTERMEDIATE: Add a test with INTERMEDIATE
2021-12-29 15:26:56 -05:00
Dmitry Goncharov
f2b130bda8 [SV 48643] Preserve target-specific variables on intermediate files
Target-specific variables used to define the target as "ought to
exist" so they could never be intermediate.  Now they can be, so
merge the target-specific variables from the intermediate target
so they're not lost.

* src/implicit.c (pattern_search): Use merge_variable_set_lists
to merge target-specific variables.
* tests/scripts/features/implicit_search: Add tests of target-
specific variable assignments and implicit rules.
2021-12-29 15:26:56 -05:00
Paul Eggert
7192d0ec4a Remove arbitrary limits on intcmp integers
We don't need to parse strings into C integer values to compare them.

* src/function.c (parse_textint): Find boundaries of a numeric string.
(func_intcmp): Use parse_textint() to compare integers textually.
* tests/scripts/functions/intcmp: Test with extra-large numbers.
2021-12-19 16:34:19 -05:00
Paul Smith
9230bfb9ae Use a well-known error string for out-of-bound function arguments
* src/function.c (parse_numeric): Check for empty value and error.
If we find ERANGE just print our own error, not strerror.
(func_word): Use a generic "not good" error message.
(func_wordlist): Ditto
(func_intcmp): Ditto
* tests/run_make_tests.pl: Remove code to find strerror(ERANGE)
* tests/scrips/functions/intcmp: Update the error message.
* tests/scrips/functions/word: Ditto.
2021-12-19 16:34:19 -05:00
Paul Smith
e62f4cf9a2 Special-case Windows error results
* tests/scripts/features/errors: Match Windows-specific errors.
* tests/scripts/features/targetvars: Match Windows-specific errors.
* tests/scripts/misc/general4: Match Windows-specific errors.
2021-11-28 14:27:10 -05:00
Paul Smith
116767901f Convert word, wordlist, and intcmp functions to use long long
Modify make functions that parse integer values to use long long
values instead of long: on Windows long is the same as int (4 bytes)
and we don't want behavior to differ between different platforms.

* bootstrap.conf: Change strtol module to strtoll module.
* src/function.c (parse_numeric): Use strtoll() and return long long.
(func_word): Use long long.
(func_wordlist): Use long long.  Verify second argument is >= 0.
(func_intcmp): Use long long.
* src/config.ami.template: Don't define HAVE_STRTOLL.
* src/config-vms.template: Define HAVE_STRTOLL.
* src/config.W32.template: Define HAVE_STRTOLL.
* tests/run_make_tests.pl: Set $ERR_out_of_range to the proper string.
* tests/scripts/functions/word: Rework to use the new style and avoid
TAB characters.  Verify trailing whitespace is ignored.  Add a test
for a negative second argument to wordlist.  Add tests for max signed
integer values.  Use $ERR_out_of_range for the error string.
* tests/scripts/functions/intcmp: Add tests for min and max signed
integer values.  Use $ERR_out_of_range for the error string.
2021-11-28 14:27:10 -05:00
Jouke Witteveen
71eb0a8038 Introduce $(intcmp ...) for numerical comparison
Numbers can come from $(words ...), automatic variables such as
$(MAKELEVEL), from environment variables, or from shell output such as
through $(shell expr ...).  The $(intcmp ...) function allows
conditional evaluation controlled by numerical variables.

* NEWS: Announce this feature.
* doc/make.texi (Functions for Conditionals): Document 'intcmp'.
* src/function.c (func_intcmp): Create the 'intcmp' built-in function.
* tests/scripts/functions/intcmp: Test the 'intcmp' built-in function.
2021-11-28 14:27:10 -05:00
Jouke Witteveen
d9291d09b8 Use strtol() instead of atoi()
strtol() is part of C89 and a fallback is provided by gnulib.

* src/function.c (func_word, func_wordlist): Change atoi to strtol.
* test/scripts/functions/word: Add out-of-range verification testing.
2021-11-28 14:26:28 -05:00
Dmitry Goncharov
21d3865973 [SV 48643] Enhance "ought to exist" definition
The traditional definition of "ought to exist" in the user's manual can
lead to make choosing a poor series of chained implicit rules.  Modify
that rule so that we first attempt to resolve implicit rules by
considering targets which are only (a) targets or (b) explicit
prerequisites of the current target.

For backward-compatibility, if we don't find a solution using that
algorithm use the previous definition where "ought to exist" means
"mentioned as a prerequisite of any target".

* src/implicit.c (pattern_search): An extra argument controls whether
to perform the backward-compatible rule search or not.  If a prereq is
a target, or if it's a prerequisite of THIS target, then choose it.
If we get to the end and haven't found a match, but we have found a
potential compatibility rule, then retry with compat rules enabled.
If we're searching with compat rules enabled and we find a file
mentioned as a prerequisite of ANY target, then use it.
* tests/features/implicit_search: Provide a large suite of tests for
different steps of implicit rule search.
2021-11-27 22:00:05 -05:00
Paul Smith
29d92d4091 tests: Enhance output to contain filename/line number info
* tests/scripts/options/dash-I: Use string comparison operator.
* tests/test_driver.pl (cmd2str): New method to convert a
command line to a string with proper quoting.
* tests/run_make_tests.pl (create_command): Call cmd2str() to format
the command.  Add the filename/line number to the output.
2021-11-27 14:03:44 -05:00