Compare commits

...

365 Commits
4.2.91 ... 4.4

Author SHA1 Message Date
Paul Smith
ed493f6c91 Release GNU Make 4.4
* NEWS: Update the version and date.
* configure.ac: Update the version.
* doc/make.texi: Update the EDITION.
2022-10-31 02:23:04 -04:00
Paul Smith
7c3260bbdd * README.git: Update and clarify release operations 2022-10-31 02:23:04 -04:00
Paul Smith
38b19976f5 Fix issues found by ASAN and Coverity
* tests/test_driver.pl: Preserve the LSAN_OPTIONS variable.
* tests/scripts/targets/ONESHELL: Don't set a local variable.
* tests/scripts/functions/let: Test empty let variable.
* src/posixos.c (osync_parse_mutex): Free existing osync_tmpfile.
* src/misc.c (get_tmpfd): Set umask() before invoking mkstemp().
* src/ar.c (ar_parse_name): Check invalid name (shouldn't happen).
* src/function.c (define_new_function): Free previous function entry
when replacing it with a new one.
* src/job.c (child_execute_job): Initialize pid for safety.
(construct_command_argv_internal): In oneshell mode ensure that the
returned argv has the right format (0th element is a pointer to the
entire buffer).
2022-10-31 02:23:04 -04:00
Paul Smith
1dd52ab472 Avoid C99 constructs
Although gnulib requires C99, most of the code does compile with a
C90 compiler (perhaps with a lot of warnings).  Reinstate our C90
configuration test, and clean up a few C99 things that crept in.

* src/job.c (construct_command_argv_internal): Don't use loop-local
variables or C++ comments.
* src/read.c (eval_makefile): Don't use loop-local variables.
2022-10-29 13:36:21 -04:00
Paul Smith
92789aa2e7 * build.sh: Allow a "keep-going" mode during builds 2022-10-29 13:36:21 -04:00
Paul Smith
4e18732a1d tests: Avoid the use of File::Temp->newdir()
This was added in Perl 5.8 but some systems still only provide older
versions such as Perl 5.6.  We don't really need it anyway.
Paul Eggert <eggert@cs.ucla.edu> reported this issue.

* tests/README: Update this to be a bit more modern.
* tests/test_driver.pl: Delete the $TEMPDIR variable.
* tests/scripts/features/temp_stdin: Use $temppath not $TEMPDIR.
2022-10-29 13:36:21 -04:00
Paul Smith
11f9da227e * src/posixos.c (os_anontmp): [SV 63287] Only fail O_TMPFILE once
Reported by Dmitry Goncharov <dgoncharov@users.sf.net>.
2022-10-29 13:36:21 -04:00
Paul Smith
b92340a1ea [SV 62174] Force locale to be "C" before retrieving error messages
We attempt to do this with POSIX::setlocale() but apparently on some
systems (AIX) this isn't sufficient.  So, in addition force the LC
environment variables to use "C".
Reported by Dmitry Goncharov <dgoncharov@users.sf.net>.

* tests/run_make_tests.pl: Move the global setup into set_default().
Force the %ENV locale variables to use the ones we'll use when running
make, then reset them back again after we find error messages.
2022-10-28 17:39:06 -04:00
Paul Smith
8064aee4f9 * src/job.c: [SV 63185] Don't use ifdef with HAVE_DECL_* macros 2022-10-27 15:20:40 -04:00
Paul Smith
cf78e65fda * tests/scripts/features/exec: Don't test with C shells
Using C shells (csh, tcsh) with make is known to be problematic due
to incorrect ways it handles open file descriptors, at least.  If
the user's shell is *csh then don't try it during exec tests.
2022-10-25 14:49:10 -04:00
Paul Smith
04f0d8427f Increase the test framework timeout from 5s to 60s
It seems that some of the test environments hit the 5s timeout on
some tests.  Since it doesn't really matter, as long as we don't
hang forever, increase the timeout to 60s.

* tests/test_driver.pl: Increase $test_timout to 60.  We don't need
to handle VMS timeouts specially anymore.
* tests/scripts/features/parallelism: We don't need to override the
default timeout anymore.
* tests/scripts/features/patternrules: Remove confusing comment.
2022-10-25 14:44:26 -04:00
Paul Smith
f8401ad28b * Makefile.am (check-regression): Add a random suffix to results file
Put the results into a subdirectory for easy unpacking.
* .gitignore: Ignore it.
2022-10-25 14:42:52 -04:00
Paul Smith
e4b3bf7f97 Release GNU Make 4.3.92
* configure.ac: Modify the release version.
* NEWS: Update the version and date.
2022-10-24 02:14:42 -04:00
Paul Smith
d18a87d0a4 [SV 63260] Don't recurse forever if setup_tmpfile() fails
If we fail during setup_tmpfile() we'll try to write an error, which
will invoke setup_tmpfile() again, etc.  Avoid infinite recursion.
Original patch by Dmitry Goncharov <dgoncharov@users.sf.net>

* src/output.c (setup_tmpfile): Remember we're in this function and
return immediately if we enter it during recursion.
(message): Remember the starting location and use that instead of
fmtbuf.buffer.
(error): Ditto.
(fatal): Ditto.
2022-10-24 01:50:12 -04:00
Paul Smith
41c35f2ffe * src/output.c (_outputs): Don't use invalid output sync FDs
Just write to stdout/stderr in this situation.
2022-10-24 01:50:12 -04:00
Paul Smith
deb4a42c3e * src/misc.c (get_tmpdir): Report errors if tmpdirs are invalid
* src/main.c (main): Set up initial temporary directories.
2022-10-24 01:50:12 -04:00
Dmitry Goncharov
252c26bd20 * src/posixos.c (os_anontmp): If O_TMPFILE fails try dup() method. 2022-10-23 18:41:50 -04:00
Paul Smith
6f8da5f4b8 * src/rule.c (get_rule_defn): Don't use STRING_SIZE_TUPLE in mempcpy
If mempcpy() is a macro then STRING_SIZE_TUPLE won't compile.
2022-10-23 18:41:50 -04:00
Paul Smith
c46b5a9e0e Provide a maintainer-only debug method
Generating debug logs to stdout or stderr makes it impossible to
run tests etc. so create a dumb DBG facility to log to a temp file.
This exists only in maintainer mode and the DBG macro gives a
compile error if it's used in non-maintainer mode.

* src/makeint.h (DBG): Call dbg() in maintainer mode, else error.
(dbg): Define it in maintainer mode.
* src/misc.c (dbg): Open a log file for append, write, then close.
2022-10-23 18:41:50 -04:00
Paul Smith
b4157d2ff4 * configure.ac: Check that we can link with Guile
On multi-arch systems we may be able to find the header file but
not successfully link the library.
2022-10-22 22:40:26 -04:00
Paul Smith
f364e0d8d6 Set PATH_MAX on systems without a default value
Some systems (HURD) use fully-dynamic pathnames, with no limit.
We can't support this without significant effort so for now set
PATH_MAX to a large value.

* src/makeint.h: Set PATH_MAX to 4096 if not set and MAXPATHLEN
is also not set.  Remove MAXPATHLEN setting: we won't use it.
* src/misc.c (get_path_max): If we can't get the path max via
pathconf() use the default PATH_MAX.
* src/dir.c (find_directory) [W32]: Use MAX_PATH not MAXPATHLEN.
(local_stat) [W32]: Ditto.
* src/job.c (create_batch_file) [W32]: Ditto.
* src/remake.c (name_mtime) [W32]: Ditto.
* src/w32/w32os.c (os_anontmp) [W32]: Ditto.
2022-10-22 22:40:26 -04:00
Paul Smith
bb0c05a7f0 [SV 63098] Enhance detection of missing peer also-make targets
The previous attempt to detect missing peer targets for implicit
rules had some holes.  Move the detection to notice_finished_file().

* src/remake.c (check_also_make): If we don't have the current mtime
for the file, obtain it.
(update_goal_chain): Don't call check_also_make() here.
(check_dep): Ditto.
(notice_finished_file): If we finished running an implicit rule that
has also_make targets, invoke check_also_make().
2022-10-22 22:40:26 -04:00
Paul Smith
f987d181c4 Collect failure details when the regression tests fail
* README.in: Add a section on running regression tests.
* Makefile.am (check-regression): Capture the test run output, and
on failure collect configure and test results into a tar file.
2022-10-22 22:40:26 -04:00
Paul Smith
cad3ddd165 Enhance tests to work on different systems
The GNU platform testers reported a number of test errors on
different systems; try to address them.

* tests/thelp.pl: A number of tests timed out with a 4-second
timeout.  Increase the default timeout to 10 seconds.
* tests/run_make_tests.pl: Executing directories on cygwin behaves
differently in Perl than make so skip these tests there.
* tests/scripts/options/symlinks: Check for the symlink feature
in make, rather than whether the system supports them.
* tests/scripts/features/implicit_search: On some systems "false"
exits with a different exit code.  Use the helper instead.
* tests/scripts/features/loadapi: Ditto.
* tests/scripts/features/output-sync: Sleep before make -f bar in
the first test as well as the second one.
* tests/scripts/features/exec: Skip on cygwin, which seems to
be "UNIX" but where scripts don't run normally.
* tests/scripts/misc/fopen-fail: Skip on cygwin, where make
eventually exits with exit code 0 and no error messages.
2022-10-22 22:37:49 -04:00
Dmitry Goncharov
54214176b1 [SV 63243] tests: Avoid SIGTERM racing with make error messages
Original patch from Frank Heckenbach <f.heckenbach@fh-soft.de>.

* tests/scripts/features/output-sync: Introduce a sleep to let make
write its error message.  Some systems use different names for
SIGTERM so match with a regex.
* tests/scripts/features/temp_stdin: Ditto.
2022-10-22 10:02:41 -04:00
Dmitry Goncharov
c2f92c980f [SV 63236] Fix getloadavg related error message on AIX
On AIX getloadavg keeps errno intact when it fails, resulting in a
bogus error message from make.

* src/job.c (load_too_high): Reset errno before calling getloadavg.
2022-10-22 09:45:40 -04:00
Dmitry Goncharov
5b1ca277ca [SV 63248] Ignore SIGPIPE
Don't terminate when make's output is redirected to a pipe and the
reader exits early; e.g.:
  $ echo 'all:; sleep 2' | make -f- -j2 -O |:

This lets us unlink temporary files, and tell the user that make was
not able to write its output.
Reported by Frank Heckenbach <f.heckenbach@fh-soft.de>.

* src/main.c (main): Ignore SIGPIPE.
* src/posixos.c (osync_clear): Fix a memory leak.
2022-10-22 09:45:40 -04:00
Paul Smith
7c71df5695 * NEWS: Release GNU make 4.3.91 2022-10-18 14:37:47 -04:00
Paul Smith
a0956c1803 * AUTHORS: Update the authors list. 2022-10-18 14:37:47 -04:00
Paul Smith
4ec74e568d * NEWS: Use GNU Make instead of GNU make
* README.git: Ditto.
* README.Amiga: Ditto.
* README.DOS: Ditto.
* README.OS2: Ditto.
* README.VMS: Ditto.
* README.W32: Ditto.
* README.customs: Ditto.
* make-gdb.py: Ditto.
* tests/run_make_tests.pl: Ditto.
2022-10-18 14:37:47 -04:00
Paul Smith
d9fc1ac5d2 Update URLs to use https rather than http
* (all): Change http:// to https://
* README.W32: Remove invalid link to mingw.org.
2022-10-18 14:37:47 -04:00
Paul Smith
9f55e9fd13 Rework temp file handling to avoid GNU libc warnings
Original patch provided by Paul Eggert <eggert@cs.ucla.edu>.
GNU libc will generate a link-time warning if we use mktemp() even
though we are using it safely (we only use it with mkfifo()).
Avoid this and clean up some handling.

First, check all calls related to temporary files and exit with a
fatal error and a useful message if we can't obtain them.  In some
situations it might be possible to continue with reduced capability
but it's not worth the effort.

On POSIX systems we can create anonymous temp files using O_TMPFILE
if it's supported, else if we're using the default location and we
have dup(2), we can use standard tmpfile() and get an FD from it.

If we need a named temp file and FILE* and we have mkstemp() we can
use that, else if we have fdopen() we can get a temp FD and open it.
If none of those are available all we can do is generate a temp name
then open it with fopen() which is not secure.

* src/makeint.h (get_tmpdir): Declare it for use elsewhere.
* src/misc.c (get_tmpdir): Make it public not static.
(get_tmptemplate): Simplify the implementation.
(get_tmppath): Only define this if we have to have it to avoid
warnings from GNU libc.
(get_tmpfd): Generate fatal errors on error.
(get_tmpfile): Ditto.  Open files in "wb+" mode to match tmpfile().
Require a filename pointer (all callers want it).
* src/os.h (os_anontmp): Implement for posixos.c as well.
* src/posix.c (jobserver_setup): Don't use mktemp to avoid GNU libc
errors.  Instead construct the FIFO name based on the PID.
(osync_setup): get_tmpfd() can't fail so don't check it.
(os_anontmp): If the system supports O_TMPFILE use it.  If not, and
we want to create the temporary file in the default directory, we
can use tmpfile() then use dup() to copy the file descriptor.
* src/main.c (main): get_tmpfile() can't fail.
* src/vmsjobs.c (child_execute_job): get_tmpfile() can't fail.
2022-10-18 14:20:44 -04:00
Paul Smith
7bb7bb4ba4 Add ISDIRSEP() helper macro and use it
Create a ISDIRSEP() macro to check for directory separator chars
using the stopchar_map, and replace inline checks and explicit
STOP_SET calls with this macro.

* src/makeint.h (ISDIRSEP): Create the macro using MAP_DIRSEP.
* src/dir.c (find_directory): Replace inline checks with ISDIRSEP.
(file_exists_p): Ditto.
(file_impossible): Ditto.
(file_impossible_p): Ditto.
(local_stat): Ditto.
* src/file.c (lookup_file): Ditto.
* src/function.c (abspath): Ditto.
* src/job.c (_is_unixy_shell): Ditto.
(is_bourne_compatible_shell): Ditto.
(construct_command_argv): Ditto.
* src/main.c (find_and_set_default_shell): Ditto.
(main): Ditto.
* src/read.c (eval): Ditto.
(parse_file_seq): Ditto.
* src/remake.c (name_mtime): Ditto.
* src/vpath.c (construct_vpath_list): Ditto.
2022-10-18 14:20:44 -04:00
Paul Smith
b79791533b Add preprocessor macros for different platforms
* configure.ac: MK_CONFIGURE shows config.h was generated by configure.
* src/config.ami: Define MK_AMIGAOS.
* src/config.h-vms: Define MK_VMS.
* src/configh.dos: Define MK_DJGPP.
* src/config.h.W32: Define MK_W32 and WINDOWS32.
* src/build_w32.bat: Let WINDOWS32 be defined by config.h.  Remove
unused setting of WIN32.
* src/job.c: Clean up use of WIN32.
* src/main.c: Ditto.
* tests/scripts/features/default_names: Ditto.
2022-10-18 14:20:44 -04:00
Paul Smith
9d24d41801 Check for recipe line count overflow before it overflows
awk 'BEGIN {
       print "x:"
       for (i = 0; i < 65536; i++)
         printf "\techo %d\n", i}
    ' | make -f -

Outputs only "make: 'x' is up to date."  Larger values run only the
lines above 65536.  Reported by Paul Eggert <eggert@cs.ucla.edu>.

* src/commands.c (chop_commands): Check the line count before it has
a chance to overflow.  Use size_t for max count so it can't overflow.
Remove stray 'd' in diagnostic.
2022-10-18 14:20:44 -04:00
Paul Smith
2d943d3d2e Remove template files to simplify distribution creation
The README templates were not useful since the replacement step
didn't have anything to replace: rename them.

Rather than creating template files for the config variants, create
mkconfig.h.in containg PACKAGE_* variables to be replaced, and have
config variant header files include it.  Note on POSIX we don't use
this, and continue to generate a single config.h.in file.

Use config.status to convert the README.in and mkconfig.h.in files
during distribution creation.

Modify all users of VERSION to use PACKAGE_VERSION instead.

* configure.ac: Use GNU Make not GNU make as the package name.
* README.in: Use GNU Make not GNU make.
* README.git: Remove references to README.W32.template.
* .gitignore: Update for new behavior.
* Basic.mk.template: Remove unused posix_SOURCES and VERSION, and
references to unshipped mk/Posix.mk
* Makefile.am: Add src/mkconfig.h as an extra dist file.
* bootstrap.bat: Rewrite mkconfig.h.in to mkconfig.h
* maintMakefile: Remove obsolete template files; add mkconfig.h.in.
* prepare_vms.com: Rewrite mkconfig.h.in to mkconfig.h
* mk/VMS.mk: Fix incorrect header file prerequisite.
* src/mkconfig.h.in: New file containing PACKAGE variables.
* src/config.ami: Include mkconfig.h.
* src/config.h.W32: Ditto.
* src/configh.dos: Ditto.
* src/config.h-vms: Ditto.
* src/version.c: Use PACKAGE_VERSION not VERSION.
2022-10-18 14:20:44 -04:00
Juan M. Guerrero
b16913a67e Support building with DJGPP 2.05
* builddos.bat: Use env var settings for paths.  Fix a typo in
expand.o.  Add the missing load.o compilation and link.  Enable
Guile support.  Copy Basic.mk from the correct location.
* src/configh.dos.templage: DJGPP supports strtoll() and ssize_t
given new enough versions.  Set preprocessor variables to 1 not 0.
2022-10-16 16:19:42 -04:00
Paul Smith
72ee43c473 * src/job.c: [SV 63185] Include sys/loadavg.h if needed. 2022-10-16 16:19:42 -04:00
Paul Smith
e5e538fb7a [SV 63215] Remember the random seed for shuffle mode
Basic fix provided by James Hilliard <james.hilliard1@gmail.com>.
Ensure we remember and propagate the random seed we generate during
shuffle mode.  Also add a debug statement displaying the seed.

* src/shuffle.c (shuffle_set_mode): Init and save the randoms seed.
* src/misc.c (make_rand): Code cleanups.
* src/main.c (main): Show a debug message containing the seed.
2022-10-16 16:18:21 -04:00
Paul Smith
c453f898a0 Use (void) rather than () in function declarations
In C, a function declaration with () allows any set of arguments.
Use (void) to mean "no arguments".

* src/dep.h: Switch () to (void) for functions with no arguments.
* src/makeint.h: Ditto.
* src/os.h: Ditto.
* src/shuffle.h: Ditto.
* src/variable.h: Ditto.
2022-10-15 18:39:32 -04:00
Paul Smith
18c4b508ef [SV 63157] Ensure temporary files are removed when signaled
Original patch from Dmitry Goncharov <dgoncharov@users.sf.net>.
When handling a fatal signal ensure the temporary files for
stdin and the jobserver fifo (if in use) are deleted.

* src/makeint.h (temp_stdin_unlink): Declare a new method.
* src/main.c (temp_stdin_unlink): Delete the stdin temporary file
if it exists.  If the unlink fails and we're not handling a signal
then show an error.
(main): Call temp_stdin_unlink() instead of unlinking by hand.
* src/commands.c (fatal_error_signal): Invoke cleanup methods if
we're handling a fatal signal.
* tests/scripts/features/output-sync: Test signal handling during
output sync and jobserver with FIFO.
* tests/scripts/features/temp_stdin: Test signal handling when
makefiles are read from stdin.
2022-10-15 18:39:32 -04:00
Paul Smith
383eb3a923 * src/posixos.c (job_root): Remember root jobserver instances
(jobserver_setup): Set job_root to true.
(jobserver_clear): if we're the root instance and we're using a
FIFO, unlink it.  If we're not in a signal handler, free memory.
(jobserver_acquire_all): Call jobserver_clear().
(sync_root): Rename from sync_parent for consistency.
2022-10-15 18:39:32 -04:00
Paul Smith
01b1d4f401 Set the proper type for variables set in signal handlers
* bootstrap.conf: Get gnulib's sig_atomic_t type checking M4 macro.
* configure.ac: Invoke it.
* src/makeint.h (handling_fatal_signal): Set the type correctly.
* src/commands.c (handling_fatal_signal): Ditto.
2022-10-15 18:39:32 -04:00
Dmitry Goncharov
bf2d71498c * tests/test_driver.pl (toplevel): [SV 63156] Keep temp env vars 2022-10-08 11:53:19 -04:00
Paul Smith
3e20e376b7 Clean up some warnings on Windows builds
* src/arscan.c (parse_int): Avoid conversion from int to char and
check for overflow given a max value.
(ar_scan): Check intmax sizes then cast to the proper type.
(ar_member_touch): Get proper return type from ar_scan and cast it
to off_t.
* src/function.c (a_word_hash_cmp): Don't cast from size_t to int.
(func_filter_filterout): Count using unsigned long to avoid casts.
(construct_include_path): Explicitly cast to void*.
* src/shuffle.c (reverse_shuffle_array): Use size_t index.
* src/w32/subproc/sub_proc.c (process_wait_for_multiple_objects):
Initialize the return value in case the count is 0.
2022-10-03 16:08:14 -04:00
Paul Smith
7ddfc42ee3 * src/misc.c (make_lltoa): Use printf format macro from makeint.h
(make_ulltoa): Ditto.
2022-10-03 15:11:57 -04:00
Paul Smith
ca92d83cde * src/arscan.c (ar_scan): Avoid sign comparison warnings
Pacify 12.2.1 20220819 (Red Hat 12.2.1-2) -Wsign-compare by checking
the readbuf() return explicitly for errors then casting from ssize_t.
Initial patch provided by Paul Eggert <eggert@cs.ucla.edu>.
2022-10-03 15:11:57 -04:00
Paul Eggert
ae80eefe65 Support systems with 32-bit long and 64-bit time_t
Don't assume that time_t fits in long, as some hosts (e.g.,
glibc x86 -D_TIME_BITS=64) have 32-bit long and 64-bit time_t.

* bootstrap.conf (gnulib_modules): Add largefile, to support files
with timestamps after Y2038 on hosts with 32-bit long.
* configure.ac: Do not call AC_SYS_LARGEFILE, as the largefile module
does that for us.
* src/makeint.h (PRIdMAX, PRIuMAX, SCNdMAX): Define if not already
defined (taken from gnulib).
* src/ar.c: Include intprops.h, for TYPE_MAXIMUM, as
INTEGER_TYPE_MAXIMUM does not work on time_t without issuing a bunch
of warnings.
(ar_member_date): Check that result is in time_t range.
(ar_member_date_1): Use intmax_t to hold the date.
(ar_glob_match): Ditto.
* src/arscan.c (VMS_function, VMS_function_ret, ar_scan)
(parse_int, ar_scan, ar_member_pos, ar_member_touch)
(describe_member): Convert long int to intmax_t.
* src/file.c (file_timestamp_sprintf): Use intmax_t/uintmax_t instead
of long/unsigned long for values that might be time_t.
* src/arscan.c (ar_member_touch): Fix buffer overrun if the timestamp
is too large.
2022-10-03 15:11:57 -04:00
Paul Smith
01142a53c9 Add support for intmax_t
* configure.ac: Ask autoconf to detect it.
* src/config.ami.template: Add #define intmax_t for AmigaOS.
* src/config.h-vms.template: Add #define intmax_t for VMS.
* src/config.h.W32.template: Add #define intmax_t for Windows.
* src/configh.dos.template: Add #define intmax_t for MS-DOS/DJPP.
2022-10-03 15:11:57 -04:00
Paul Smith
dee6af912a * NEWS: Deprecate Xenix 2022-10-03 15:11:57 -04:00
Paul Smith
7296991d6c [SV 63098] Temporarily revert the change to pattern rule behavior
The fix for SV 12078 caused a backward-compatibility issue with some
makefiles.  In order to allow users to resolve this issue, revert
that change for this release cycle: it will be reinstated in the
next release cycle.  Introduce a warning if we detect that the recipe
of a multi-target pattern rule doesn't create all the targets.

* NEWS: Announce the future backward-incompatibility.
* doc/make.texi (Pattern Intro): Describe the behavior and that it
will change in the future.
* src/remake.c (check_also_make): Check for also_make targets that
were not created and generate a warning.
(update_goal_chain): Call the new function.
(check_dep): Ditto.
(update_file_1): Defer implicit rule detection until after we check
all the also_make files (as it used to be).
* tests/scripts/features/patternrules: Add tests of the new warning.
Skip the tests for SV 12078.
2022-10-02 10:18:21 -04:00
Paul Smith
d51ac70122 * doc/make.texi (Prerequisite Types): [SV 58056] Clarify ordering. 2022-10-02 09:30:20 -04:00
Paul Smith
3cb84fe933 * src/filedef.h (is_ordinary_mtime): Check for "ordinary" mod time.
* src/remake.c (update_file_1): Use the new macro.
2022-10-02 08:55:29 -04:00
Paul Smith
ad84ec2fdc * src/remake.c (update_file_1): Return valid enum element, not 0. 2022-10-02 08:55:29 -04:00
Paul Smith
26b9f30714 * NEWS: Announce deprecation of OS/2 and AmigaOS ports 2022-10-02 08:55:29 -04:00
Paul Smith
5ac80176a3 * src/main.c (main): Add debug output for jobserver and osync.
* src/posixos.c (jobserver_setup): Remove redundant debug output.
(jobserver_parse_auth): Ditto.
2022-10-02 08:46:00 -04:00
Andreas Schwab
c801a7fb67 [SV 63111] Ensure output-sync is cleaned on re-exec and recursion
Now that output-sync is using a separate file as a mutex rather than
stdout, ensure the new file descriptor is closed before re-exec and
not inherited by children.

* src/main.c (main): Call osync_clear() before re-exec.
* src/posixos.c (osync_setup): Reset output-sync handle inheritance.
(osync_parse_mutex): Ditto.

Copyright-paperwork-exempt: yes
2022-10-02 08:46:00 -04:00
Paul Smith
c2eddf9be2 * src/function.c: Change int to uint to align with gmk_func_ptr 2022-10-01 11:47:41 -04:00
Dmitry Goncharov
f8852311cc * doc/make.texi (Loaded Object API): [SV 63126] Fix typos and examples 2022-10-01 11:47:41 -04:00
Paul Smith
a99378ebe4 Implement a simple xorshift 32bit random number generator
Avoid relying on the system random number generator for our random
shuffle, so that the same seed gives the same results on all systems.
This generator doesn't need to be amazing, just pretty good, so don't
bother with xorshift* or xorshift+, etc.

* src/makeint.h: Declare make_seed() and make_rand().
* src/misc.c (make_seed): Set the seed value for the RNG.
(make_rand): Return the next random number.  If the seed was not set
initialize it first.
* src/shuffle.c (shuffle_set_mode): If we don't get a seed from the
user just leave it unset (0).
(shuffle_deps_recursive): Use make_seed() not srand().
(random_shuffle_array): Use make_rand() not rand().
2022-10-01 11:45:39 -04:00
Dmitry Goncharov
6c87f3fb85 [SV 63100] Set the floc of every created goal dep struct
* src/read.c (eval): Initialize the goaldep floc pointer.
* tests/scripts/features/loadapi: Verify that the floc is set after
unloading and reloading dynamic objects.
2022-09-25 17:09:08 -04:00
Paul Smith
38116baee9 * doc/make.texi: Update out of date behavior for grouped targets. 2022-09-25 16:58:36 -04:00
Paul Smith
614033f8c6 * README.git: Announce releases to the platform-testers list 2022-09-25 16:57:31 -04:00
Paul Smith
f3640ecf4f Provide new functions to convert long long to string
The previous attempt to use PRI* macros to avoid compiler-specific
printf format specifiers didn't work because we are using raw
long long type, not the uintX_t types.  On systems where long and
long long are the same size, uint64_t might be type "long" and PRId64
is just "ld".

Instead write new functions that convert [unsigned] long long to a
string and call those instead.

* src/makeint.h: Declare make_lltoa() and make_ulltoa().
* src/misc.c (make_lltoa): New function that writes a long long value
into a provided buffer.  Return the buffer for ease-of-use.
(make_ulltoa): Ditto, for unsigned long long.
* src/function.c (func_wordlist): Call these new methods.  Also
rework the error strings so we share the translated string.
* src/dir.c (print_dir_data_base): Call the new methods instead of
using MSVC macros.
2022-09-25 16:57:31 -04:00
Paul Smith
c4e232e44f Always restore global environ if we use vfork
We may change the global environ variable in the child; when using
vfork() this also sets it in the parent.  Preserve the parent's
environ in child_execute_job() so it takes effect for all callers.

Reported by Denis Excoffier <bug-tar@Denis-Excoffier.org>
Root cause found by Martin Dorey <Martin.Dorey@hitachivantara.com>

* src/job.c (start_job_command): Remove save/restore of the parent
environment.
(child_execute_job): Add save/restore of the parent environment,
if we use vfork().
* tests/scripts/functions/shell: Add a test the crashes if we don't
reset environ after we run $(shell ...).
2022-09-25 16:57:31 -04:00
Dmitry Goncharov
aa99e810a9 * configure.ac: [SV 63070] Clean up the test program for posix_spawn. 2022-09-25 16:57:13 -04:00
Paul Smith
8f49029561 * src/posixos.c (osync_clear): Don't close invalid FDs. 2022-09-25 13:37:12 -04:00
Paul Smith
f7ed583675 * maintMakefile: Use gnulib ncftpput-ftp if ncftpput is missing. 2022-09-25 13:37:12 -04:00
Paul Smith
cf7f7de7ae * src/misc.c (strncasecmp): Use size_t for length to match std.
* src/misc.h (strncasecmp): Fix the declaration.
2022-09-25 13:37:12 -04:00
Paul Smith
d4cb7ae6d4 * configure.ac: Update to GNU make 4.3.91
* NEWS: Update the version and clarify some backward-compat issues.
2022-09-25 13:37:12 -04:00
Eli Zaretskii
387d349dc8 Fix compiler warnings in the MS-Windows build.
* src/w32/w32os.c (osync_get_mutex, osync_parse_mutex): Cast to
DWORD_PTR when converting integers to HANDLEs and vice versa.

* src/w32/pathstuff.c (w32ify): Pacify compiler warnings about
'strncpy'.

* src/makeint.h (PRId64) [!HAVE_INTTYPES_H]: Define if undefined.
* src/function.c (func_wordlist): Use PRId64 instead of %lld.
2022-09-25 17:11:12 +03:00
Eli Zaretskii
caad0e2181 Avoid compilation warnings
* src/implicit.c: (pattern_search):
* src/main.c: (main): Avoid compilation warnings for variables
only used when compiling a debug version with assertions.
2022-09-24 21:15:41 +03:00
Paul Smith
990d6f9b9a Release GNU make 4.3.90
* NEWS: Update for the prerelease.
* bootstrap.conf: Choose the latest stable gnulib.
* README.git: Updates.
2022-09-20 13:23:44 -04:00
Paul Smith
134480787e * tests/script/parallelism: Force wait to remove races. 2022-09-20 13:23:44 -04:00
Dmitry Goncharov
a9a4919909 [SV 56301] Fail if an included makefile can't be built
Fail if a mandatory include file fails to be built even if it's
built as part of a grouped target where the other include file
is optional.

* src/main.c (main): If a makefile doesn't build set any_failed.
* tests/scripts/features/include: Add tests.
* tests/scripts/options/dash-k: Stop after include build failure.
2022-09-20 03:55:39 -04:00
Paul Smith
d12ff78cb2 * tests/scripts/features/statipattrules: [SV 17374] Add test
Verify that double-colon static pattern rules work.
2022-09-20 03:55:39 -04:00
Paul Smith
fabb03eac4 [SV 12078, SV 62809] Rebuild grouped targets if any is missing
If any of a set of grouped targets is missing or out of date, even
if make is not trying to build that target, rebuild them all.
Ensure this is true for explicit grouped targets as well as pattern
rule grouped targets.

Original patch by Jonathan Gravel <jo@stashed.dev>

* src/remake.c (update_file_1): After matching any pattern rules,
go through the also_make targets and set noexist as needed.  Also
compute the oldest this_mtime.
* tests/scripts/features/grouped_targets: Add regression tests.
* tests/scripts/features/patternrules: Ditto.
* tests/features/vpath: Rewrite to use modern run_make_test().
Add a test that we check for VPATH before implicit rule search.
Move the tests in vpath2 and vpath3 into this suite.
* tests/features/vpathplus: Rewrite to use modern run_make_test().
2022-09-20 03:55:39 -04:00
Dmitry Goncharov
618c53a225 * tests/scripts/targets/WAIT: [SV 63071] Remove possible test races. 2022-09-17 13:22:35 -04:00
Paul Smith
88d126d6c4 * doc/make.texi (Parallel Disable): Add clarifications.
* NEWS: Suggest how to change makefiles that use $(MAKEFLAGS).
2022-09-13 18:22:29 -04:00
Paul Smith
f6ea899d83 [SV 13862] Implement the .WAIT special target
The next version of the POSIX standard defines parallel execution
and requires the .WAIT special target as is implemented in some other
versions of make.

This implementation behaves similarly to others in that it does not
create a relationship between targets in the dependency graph, so
that the same two targets may be run in parallel if they appear as
prerequisites elsewhere without .WAIT between them.

Now that we support .WAIT it's trivial to also support prerequisites
of the .NOTPARALLEL special target, which forces the prerequisites of
those targets to be run serially (as if .WAIT was specified between
each one).

* NEWS: Announce the new .WAIT and .NOTPARALLEL support.
* doc/make.texi (Parallel Disable): A new section to discuss ways in
which parallel execution can be controlled.  Modify cross-refs to
refer to this section.
* src/dep.h (struct dep): Add a new wait_here boolean.
(parse_file_seq): Add PARSEFS_WAIT to check for .WAIT dependencies.
* src/file.c (split_prereqs): Use PARSEFS_WAIT.
(snap_deps): If .NOTPARALLEL has prerequisites, set .WAIT between
each of _their_ prerequisites.
(print_prereqs): Add back in .WAIT when printing prerequisites.
* src/implicit.c (struct patdeps): Preserve wait_here.
(pattern_search): Ditto.  Use PARSEFS_WAIT when parsing prereqs for
pattern rule expansion.
* src/read.c (check_specials): Don't give up early: remembering to
update these options is not worth the rare speedup.
(check_special_file): If .WAIT is given as a target show an error--
once--if it has prereqs or commands.
(record_files): Call check_special_file on each target.
(parse_file_seq): If PARSEFS_WAIT is given, look for .WAIT prereqs.
If we see one assume that we are building a struct dep chain and set
the wait_here option while not putting it into the list.
* src/remake.c (update_file_1): If wait_here is set and we are still
running, then stop trying to build this target's prerequisites.
* src/rule.c (get_rule_defn): Add .WAIT to the prerequisite list.
* src/shuffle.c (shuffle_deps): Don't shuffle the prerequisite list
if .WAIT appears anywhere in it.
* tests/scripts/targets/WAIT: Add a test suite for this feature.
2022-09-12 18:35:29 -04:00
Dmitry Goncharov
ee861a4e9f [SV 63045] Reload each intact unloaded shared object
If makefile rules do not update an unloaded shared object, load it
again.  Avoid double loading of the same object if the setup function
returns -1.

* src/filedef.h (struct file): Add "unloaded" flag.
* src/makeint.h (load_file): Take struct file *.
(unload_file): Return int.
* src/main.c (main): Reload unloaded shared objects if they weren't
updated.
* src/commands.c (execute_file_commands): Set "unloaded" and reset
"loaded" when a shared object is unloaded.
* src/read.c (eval): Set "loaded" and reset "unloaded" when a shared
object is loaded.  Add successfully loaded files to the db.
* src/load.c (load_file): Check "loaded" to avoid double loading the
same object.  Fix a memory leak of string loaded.  Return -1, rather
than 1, if the object is already loaded. This fixes double loading of
the same object when the setup routine returns -1.
(load_object): Add a log message.
(unload_file): Return an error on dlclose failure.  Log a message.
* tests/scripts/features/loadapi: Add new tests.
2022-09-12 02:05:18 -04:00
Sergei Trofimovich
ca4234c4b5 [SV 63047] Fix shuffle of SECONDEXPANSION prerequisites
Commit 07eea3aa4 `make --shuffle` prevented shuffling prerequisites
that use .SECONDEXPANSION, since shuffle happens before expansion.
This has two problems:
1. No shuffling happens for such prerequisites.
2. Use-after-free when outdated '->shuf' links are used.

Add a reshuffle into expansion phase right after dependency changes.

* src/file.c (expand_deps): Add reshuffle if dependencies change.
* src/shuffle.c (identity_shuffle_array): Fix comment typo.
* tests/scripts/options/shuffle: Add new SECONDEXPANSION test.
2022-09-12 01:05:31 -04:00
Paul Smith
257b82ac1f * doc/make.texi (How Make Works): Clarify default goal exceptions. 2022-09-11 15:09:13 -04:00
Paul Smith
aac4004444 * src/shuffle.c: Minor coding changes. 2022-09-11 14:04:58 -04:00
Paul Smith
86fc644dcc Support the MAKE_TMPDIR environment variable
Allow build systems to choose an alternative location for make to
store its temporary files.

* NEWS: Announce the new environment variable.
* doc/make.texi (Temporary Files): Provide documentation.
* src/misc.c (get_tmpdir): Split into a new function.  Compute the
temporary directory and store it in a static location.
* tests/scripts/features/jobserver: Add a test of MAKE_TMPDIR.
2022-09-11 10:56:08 -04:00
Paul Smith
02b3a6ad46 [SV 62898] Document ways to hide special chars from make functions
* doc/make.texi (Function Call Syntax): Add a subsubheading describing
which special characters may need to be hidden from make functions.
2022-09-10 23:14:02 -04:00
Dmitry Goncharov
77734be2af [SV 63044] load: Update .LOADED if the setup function returns -1
* src/load.c (load_file): Update .LOADED if setup returns non-0.
* tests/scripts/features/load: Change the return value based on an
environment variable.  Ensure that returning -1 still adds to
.LOADED.  Also add a test that verifies that make doesn't try to
rebuild the loaded file if -1 is returned.
2022-09-10 22:42:28 -04:00
Paul Smith
820210ab85 Enhance the make.texi formatting
Notes provided by Tzvetelin Katchov <katchov@gnu.org>.

* doc/make.texi: Remove obsolete @refill statements.  Add some breaks
to overfull lines.  Fix up some example text.
2022-09-10 18:35:47 -04:00
Paul Smith
77706874a7 Clean up maintMakefile
Notes provided by Tzvetelin Katchov <katchov@gnu.org>

* maintMakefile (git-very-clean): Add -x to git clean.
(GNULIBDIR): Use GNULIB_SRCDIR, or the local module if not set.
2022-09-10 18:35:41 -04:00
Paul Smith
a9548aeb8f [SV 63037] Fix tests for newer OS / compiler
* tests/scripts/features/load: Add function prototypes.
* tests/scripts/features/temp_stdin: Only set user execute bits.
Some configurations don't allow changing the group bits...??
2022-09-10 17:15:23 -04:00
Paul Smith
70ba0357a0 [SV 63040] shell: Fall back to the callers environment
If we detect a recursive variable reference when constructing the
environment for the shell function, return the original value from the
caller's environment.  Other options such as failing, returning the
empty string, or returning the unexpanded make variable value have
been shown to not behave well in real-world environments.  If the
variable doesn't exist in the caller's environment, return the empty
string.

Found by Sergei Trofimovich <slyich@gmail.com> when testing older
versions of autoconf.

* NEWS: Clarify this behavior.
* doc/make.texi (Shell Function): Ditto.  Also add info about !=.
* src/expand.c (recursively_expand_for_file): Search the caller's
environment if we detect a recursive variable expansion.
* tests/scripts/functions/shell: Add tests for this behavior.
2022-09-10 16:27:47 -04:00
Paul Smith
7d48401707 [SV 63016] Don't fail exporting to $(shell ...)
The fix for SV 10593 caused recursive expansion errors when exporting
a variable that contains a $(shell ...) invocation.  If we see this
type of recursion, ignore it and expand to the empty string rather
than failing.

* src/variable.h (env_recursion): New global variable.
* src/variable.c (target_environment): If creating the environment
for a $(shell ...) function increment env_recursion.  Remove the
check for expansion in a shell function context.
* src/expand.c (recursively_expand_for_file): Check for recursive
expansion in a $(shell ...) environment context and if present,
show the verbose message and return the empty string.
* tests/scripts/functions/shell: Add a test for this situation.
2022-09-08 03:04:15 -04:00
Paul Smith
1fc13bf576 Ensure debug output ends in newline
* src/load.c (load_object): Debug output strings must include \n.
* src/variable.c (target_environment): Ditto.
* src/posixos.c: Remove extra newlines.
2022-09-08 03:04:15 -04:00
Paul Smith
896908180e Sanitize tar file ownership, mode, and order
For reproducibility ensure all files in the dist tar file are owned by
root, and sorted by name.  Force the mode on all files to be writable
by the owner and not writable by group or user, by default.

Remove unnecessary execute permissions from build_w32.bat.

Recommended by Tzvetelin Katchov <katchov@gnu.org>.
2022-09-08 03:04:15 -04:00
Paul Smith
80e9a422e4 bootstrap: Update to the latest gnulib bootstrap model
* README.git: Document the changes.
* bootstrap.conf: Set GNULIB_REVISION to avoid random updates.
* configure.ac: Set the minimum autoconf version back to 2.69:
that's the most common version deployed today, and it still works.
* bootstrap: Copy the latest from gnulib.
* autogen.sh: Ditto.
* autopull.sh: Ditto.
* bootstrap-funclib.sh: Ditto.
2022-09-08 03:04:04 -04:00
Paul Smith
15a7e3830f Fix tests for MacOS and Windows
* maintMakefile: Remove the template headers as prerequisites.
* tests/scripts/features/jobserver: Only test fifo if enabled.
* tests/scripts/variables/INCLUDE_DIRS: On MacOS none of the default
directories exist so .INCLUDE_DIRS is empty by default.
* tests/scripts/features/se_explicit: Fail via exit.  cp will show
different error messages on different systems.
* tests/scripts/features/se_implicit: Ditto.
* tests/scripts/features/se_statpat: Ditto.
2022-08-30 21:05:34 -04:00
Paul Smith
26e359c71d [SV 62840] Don't change IO buffering before printing version
If users run 'make --version | head -n1' they expect make to exit
with a success (0) code.  This works because the pipe forces the
default buffering on stdout to be fully buffered so all the output
is printed to the pipe in a single write(2) and won't fail.  However
due to output sync we forcibly set stdout to line buffered, which
means if the reader closes the pipe fast enough make will exit with
an error code because the write to stdout failed.

Move the setup done in output_init() back into main() where it can
be done in a proper order.  Rework the order of operations during
startup so that we check for help and version flags before we change
the buffering.  Clean up the behavior of print_usage().

Original changes from Dmitry Goncharov <dgoncharov@users.sf.net>.

* src/main.c (switches): Don't send --version in the environment.
(print_usage): Add a blank line after the version before the usage.
Move the die() into this function since we always die() afterward.
Note the die will flush so no need to do it explicitly.
(print_version): The caller will fflush when appropriate.
(close_stdout): Move from output.c so it is installed early.
(decode_switches): Only call print_usage on error, not for --help.
(main): Install the close_stdout handler immediately after start.
Move the calls to print_usage() due to --help and --version to be
called immediately after we decode the switches.  Move the buffer set
here from output_init(), immediately after we know we'll be running.
* src/output.c (output_init): Move buffer setting to main().
(close_stdout): Move to main().
2022-08-30 21:04:48 -04:00
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
a2ba5ccbda Add get_tmpfd() and allow anonymous temp files
The output sync feature wants a file descriptor not a FILE*.  We were
using tmpfile() but this returns FILE* which means we needed to dup()
the descriptor then fclose() the original, which is just unnecessary
overhead for every command we run.

Create a get_tmpfd() method that returns a file descriptor directly
by using mkstemp() if available, else do the best we can.

Also allow anonymous temp files if the filename pointer is NULL.
This causes the file to be unlinked.  On Windows this requires a
special open so add an os_anontmp() method to handle this.

* src/makeint.h: Add prototype for get_tmpfd().
* src/misc.c (get_tmpfd): If we have mkstemp() use that, else just
open(2).  If we don't want to keep the filename, unlink the file.
(get_tmpfile): Use get_tmpfd() if we have fdopen(), else use fopen().
* src/output.c (output_tmpfd): Call get_tmpfd() with NULL.
* src/os.h (os_anontmp): On Windows make this a function, else fails.
* src/w32/compat/posixcfn.c (tmpfile): Move to w32os.c:os_anontmp().
* src/w32/w32os.c (os_anontmp): Create a temp file that will be deleted
when the process exits, and return a file descriptor to it.
2022-08-30 15:39:02 -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
ab31f0b594 * doc/make.texi (Variables/Recursion): [SV 56446] Clarify export docs 2022-08-14 14:06:31 -04:00
Paul Smith
8f1b6bca46 * doc/make.texi (Goals): [SV 51306] Improve MAKECMDGOALS example 2022-08-07 17:32:07 -04:00
Dmitry Goncharov
6faa02247e * doc/make.texi (Remaking Makefiles): [SV 61623] Add optimization 2022-08-07 17:31:50 -04:00
Paul Smith
c72e1ec446 * doc/make.texi (Chained Rules): [SV 61957] Clarify NOTINTERMEDIATE 2022-08-03 00:13:34 -04:00
Paul Smith
91d87ccf32 [SV 62496] Fix example of testing MAKEFLAGS
* doc/make.texi (Options/Recursion): Define the layout of MAKEFLAGS.
(Testing Flags): Fix the example to test the first word.
2022-08-03 00:05:39 -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
Paul Smith
09cce75c30 Enhance get_tmpfile() and add get_tmppath()
Move all the logic on creating temporary files into misc.c, and add
a new function get_tmppath() that returns the pathname to a temporary
file without creating or opening it.

* src/makeint.h: Add a declaration for get_tmppath().  Remove the
template argument from get_tmpfile(): it will compute its own.
* src/main.c (main): Remove the logic for computing templates.
* src/vmsjobs.c (child_execute_job): Ditto.
* src/misc.c (get_tmptemplate): New function to return an allocated
template string for use with various mktemp-style functions.
(get_tmppath): Return an allocated path to a temporary file, but do
not create it.  Generally this should be avoided due to TOCTOU issues.
(get_tmpfile): Use get_tmptemplate() to generate a template rather
than using one passed in.  If we don't have mkstemp() then use
get_tmppath() to compute the path of a temp file.
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
2fe96e4a41 Take advantage of mempcpy() and stpcpy()
* src/makeint.h (stpcpy): Add missing declaration.
* src/amiga.c (MyExecute): Avoid extra strlen using stpcpy.
* src/function.c (func_shell_base): Ditto.
(func_error): Use memcpy() not strcpy() when we know the length.
* src/job.c (construct_command_argv_internal): Use stpcpy().
* src/main.c (main): Ditto.
(define_makeflags): Ditto.
* src/variable.c (print_target_variables): Use memcpy() when we know
the length.
* src/commands.c (set_file_variables): Use mempcpy().
* src/expand.c (variable_buffer_output): Ditto.
* src/file.c (expand_deps): Ditto.
* src/function.c (abspath): Ditto.
(handle_function): Ditto.
* src/implicit.c (pattern_search): Ditto.
* src/job.c (construct_command_argv_internal): Use mempcpy() and
don't add multiple spaces when there are no shell flags.
* src/main.c (decode_env_switches): Use mempcpy() to simplify.
(define_makeflags): Ditto.
* src/variable.c (selective_vpath_search): Ditto.
2022-07-30 18:40:21 -04:00
Paul Smith
dd24a4c1cf Convert HAVE_GETLOADAVG to HAVE_DECL_GETLOADAVG
We want to know if getloadavg() is declared, not if we have it.

* configure.ac: Add it as a define (why is this not the default?)
* src/job.c: Conditionalize declaration on HAVE_DECL_GETLOADAVG.
* config.ami.template: Rename HAVE_GETLOADAVG to HAVE_DECL_GETLOADAVG.
* config.h-vms.template: Ditto.
* config.h.W32.template: Ditto.
Clean up and add new elements from latest config.h.
2022-07-09 11:09:17 -04:00
Paul Smith
f36c6c7347 Merge in the latest gnulib findprog-in module 2022-07-09 11:08:49 -04:00
Paul Smith
87d24154af Merge in the latest gnulib concat-filename module 2022-07-09 11:07:23 -04:00
Paul Smith
614557d04c Merge in the latest gnulib getloadavg module 2022-07-09 11:05:14 -04:00
Paul Smith
047544785b Initial merge of the gnulib-port branch 2022-07-09 10:56:05 -04:00
Paul Smith
73b08af181 Move our local m4 macros to gl/m4
The gl subdirectory contains our local versions of gnulib module
implementations, so move m4/acinclude.m4 and m4/dospaths.m4 there.

* gl/modules/make-macros: Create a new module to handle the macros.
* bootstrap.conf: Add the new module.
* configure.ac: Macro invocation is moved to make-macros.
* m4/.gitignore: Delete unnecessary ignore file: m4 is empty.
* .gitignore: Add m4/ as an ignored directory.
2022-07-09 10:47:13 -04:00
Paul Smith
5c1d9e54c7 Move our fnmatch/glob implementation into gl/lib
The gl subdirectory contains our local versions of gnulib module
implementations, so move fnmatch* and glob* from lib to gl/lib.

* gl/modules/make-glob: Add a proper Files: section.
* lib/.gitignore: Delete unnecessary ignore file: lib is empty.
* .gitignore: Add lib/ as an ignored directory.
2022-07-09 10:47:13 -04:00
Paul Smith
2d7b5d6d80 * tests/run_make_tests.pl: Exit 1 if we detect an error. 2022-07-09 10:47:13 -04:00
Paul Smith
5dc7358547 * configure.ac: Remove AC_FUNC_SETVBUF_REVERSED.
This macro is obsolete: no useful system has this problem anymore.
* src/output.c (output_init): Remove reference to SETVBUF_REVERSED.
* src/config.ami.template: Remove undef of SETVBUF_REVERSED.
* src/config.h-vms.template: Ditto.
* src/config.h.W32.template: Ditto.
2022-07-09 10:47:13 -04:00
Paul Smith
e33af0fb4a * configure.ac: Check for stpcpy() support.
* src/misc.c (stpcpy): Define it if not provided.
2022-07-09 10:47:13 -04:00
Paul Smith
6f7e06ec4e getloadavg: Remove support for privileged invocation
This was needed when getloadavg required privileged access; in this
case GNU make needed to be installed as a setgid program.  But this
hasn't been supported by gnulib getloadavg() since 2011 and systems
are no longer using it, so remove it.

* src/makeint.h (user_access): Remove unnecessary function.
(make_access): Ditto.
(child_access): Ditto.
* src/misc.c: Remove implementations of the *_access() functions.
* src/main.c (main): Remove unneeded call to user_access().
* src/job.c (load_too_high): Remove calls to {make,user}_access().
(exec_command): Remove call to child_access().
* src/remote-cstms.c: Remove calls to these methods.  I suppose it
might be possible this is needed and was piggy-backing on the
privileged setting but since that's been broken for a while I doubt
this is needed.  If so we can bring back the implementation into
this source file.
* src/config.h.W32.template: Remove GETLOADAVG_PRIVILEGED undef.
* src/config.h-vms.template: Ditto.
* src/config.ami.template: Ditto.
2022-07-09 10:47:13 -04:00
Paul Smith
3f3eecc115 * maintMakefile: Allow checkcfg rules to succeed.
We can no longer pass our mondo-warnings options to the builds,
as these will impact all the code including gnulib code, and this
won't work.  Also allow the caller to disable either the build.sh
or makefile invocation, for testing.
* Makefile.am: Allow the caller to reset the path to the make
binary to be tested.  Remove c90 test: gnulib doesn't support it.
2022-07-09 10:46:47 -04:00
Paul Smith
b09e9af0b8 * build.sh: Manage libgnu_a-prefixed source files 2022-07-09 10:46:47 -04:00
Paul Smith
9992cb0b83 bootstrap: Remove strerror()
* bootstrap.conf: Remove strerror module
* configure.ac: Add a check for strerror
* src/misc.c: Add a default strerror() if not found
2022-07-09 10:46:47 -04:00
Paul Smith
0cbee1b475 bootstrap: Remove strtoll()
This pulls in entirely too much stuff we don't need.  Instead grab
just the gnulib source file, then include it in src/misc.c.

* bootstrap.conf: Add just the lib/strtol.c source file.
* configure.ac: Check for strtoll.
* src/misc.c: Include strtol.c, with QUAD set, if needed.
2022-07-09 10:46:47 -04:00
Paul Smith
d63925d863 bootstrap: Remove gnulib version of mempcpy()
This pulls in a metric ton of stuff that we otherwise don't need, just
for a one-liner that we already have a replacement for in src/misc.c.

* bootstrap.conf: Remove mempcpy
* configure.ac: Add mempcpy to AC_CHECK_FUNCS
2022-07-09 10:46:47 -04:00
Paul Smith
0793658c09 Run autoupdate and clean up autoconf usage
We can assume that the return type of a signal handler is void.
We can assume that, if sys/time.h exists, it can be included
with time.h.

* bootstrap: Get the latest version
* configure.ac: Require a newer version of autoconf.
Remove unnecessary AC_PROG_CC_C99 (already have AC_PROC_CC).
Remove unnecessary AC_AIX, AC_ISC_POSIX, AC_MINIX.
Remove unnecessary AC_HEADER_STDC, AC_HEADER_TIME, AC_TYPE_SIGNAL.
Use strerror to search for the cposix library.
* src/commands.c (fatal_error_signal): Assume return type is void.
* src/commands.h: Ditto.
* src/job.c: Ditto.
* src/job.h: Ditto.
* src/main.c: Ditto.
* src/makeint.h: Ditto.
Don't bother with TIME_WITH_SYS_TIME.
* src/remote-cstms.c: Check HAVE_SYS_TIME_H.
* src/config.ami.template: Remove RETSIGTYPE.
* src/config.h-vms.template: Ditto.
* src/config.h.W32.template: Ditto.
Remove TIME_WITH_SYS_TIME.
2022-07-09 10:46:47 -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
fe55d6e1e3 Add gnulib findprog-in 2022-07-07 02:12:54 -04:00
Paul Smith
768f287a06 Add gnulib concat-filename 2022-07-07 02:12:54 -04:00
Paul Smith
8dd302cda6 Add gnulib getloadavg 2022-07-07 01:53:08 -04:00
Paul Smith
df75efb114 Initial gnulib-port branch commit 2022-07-07 01:53:08 -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
84ed34ba5a * tests/test_driver.pl: Don't freak if diff can't be found 2022-06-18 16:42:37 -04:00
Paul Smith
08c964b4ac * build_w32.bat [WIN]: Use call for all invocations 2022-06-18 16:42:11 -04:00
Paul Smith
97e51c0285 Avoid overwriting buffers with long pathnames
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.
2022-06-17 19:55:11 -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
Paul Smith
e4b7ac21dc * src/misc.c (make_toui): Parse a string into an unsigned int
* 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.
2022-06-04 18:34:15 -04:00
Paul Smith
d444b87173 * src/misc.c (make_pid): A function to return the PID
* src/makeint.h: Declare it.
* src/commands.c (fatal_error_signal): Call it.
2022-06-04 17:04:38 -04:00
Paul Smith
1c179f9636 * po/LINGUAS: Add a translation for Romanian 2022-06-04 17:04:38 -04:00
Noah Goldstein
5690084634 Replace strcmp() with memcmp() where possible
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().
2022-04-24 17:52:54 -04:00
Noah Goldstein
9fa63eb918 hash: Remove unnecessary isupper() check before tolower()
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.
2022-04-24 17:52:54 -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
5b1e871d2d * Makefile.am (check-regression): Rename jhelp to thelp 2022-04-24 13:48:03 -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
Paul Smith
51c1c07e7a * tests/test_driver.pl (run_all_tests): Keep one copy of STDIN 2022-04-24 13:48:03 -04:00
Paul Smith
700af780af * Makefile.am: Add INSTALL to the EXTRA_DIST files 2022-04-24 10:39:32 -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
93fd0c0c9a * src/commands.h: [SV 62213] Forward-declare struct file / child 2022-04-24 10:39:32 -04:00
Paul Smith
cf56036c60 * tests/test_driver.pl (toplevel): [SV 62174] Enforce the C locale 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
634ef057ad * src/read.c (check_specials): [SV 62171] Reset ARFLAGS under .POSIX 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
0de7b74896 * README.git: Fix compiler options for ASAN 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
Paul Smith
cb9ac2b0cc * src/main.c: Ensure the stdin temp file is deleted when dying. 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
8cdaabbf8e tests: Preserve Windows temp environment variables
* 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.
2022-02-27 17:47:19 -05:00
Paul Smith
2be8661433 * tests/test_driver.pl: Support STDIN redirection.
Before running tests, duplicate STDIN then reset it after the test
completes.  Also when -keep is provided, preserve the base and run
files.
2022-02-26 17:19:26 -05:00
Paul Smith
8b3e678ace Ensure buffers are large enough for integer values
Issue raised by Sergei Trofimovich <siarheit@google.com>

* src/makeint.h (INTSTR_LENGTH): Update for unsigned values.
* src/function.c (func_lastword): Use INTSTR_LENGTH as buffer size.
(shell_function_completed): Ditto.
(func_call): Ditto.
* src/remote-cstms.c (start_remote_job): Ditto.
2022-02-21 09:29:41 -05:00
Paul Smith
ec09ec775a * <all>: Update copyright notices. 2022-02-10 14:48:26 -05:00
Paul Smith
bdaeca49e9 * doc/make.1: Use "target" from the SYNOPSIS.
Reported by Helge Kreutzmann <debian@helgefjell.de>
2022-02-06 18:46:32 -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
Paul Smith
6761122be0 * Basic.mk.template: Allow arguments to the check target. 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
Dmitry Goncharov
d34f46c1f3 [SV 48643] Make prereqs mentioned in unrelated rules explicit
* src/implicit.c (pattern_search): Set is_explicit when a prereq
is mentioned in an unrelated rule.
2022-02-06 18:46:32 -05:00
Dmitry Goncharov
f0ab709640 * src/implicit.c (pattern_search): [SV 61864] Fix debug output. 2022-02-06 18:46:32 -05:00
Paul Smith
5f2d114c6d Avoid interleaved $(info ) output
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.
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
Paul Smith
f485881d4a * src/implicit.c (pattern_search): Use const ptrs when possible.
Change suggested by Joe Filion <joefilion4@gmail.com>
2022-02-06 18:46:32 -05:00
Paul Smith
15db387f18 * src/job.c (load_too_high): Re-enable Linux /proc/loadavg checks.
Further experimentation shows that my previous thinking that there
was a problem using this was woefully mistaken.  The value generated
by the kernel shows runn*ABLE* processes not runn*ING* processes.
* NEWS: Announce the change.
2022-02-06 18:46:32 -05:00
Paul Smith
aab51f7ef2 * doc/make.texi (Using One Shell): Correct example to use $<. 2022-02-06 18:46:29 -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
b6a779d262 Ensure that loaded functions increment the command count
Since we don't know what a loaded function (via Guile or load) may
do, increment the command count just in case.

* src/function.c (struct file_table_entry): New adds_command bool.
(FT_ENTRY): Initialize it to 0 for built-in functions.
(expand_builtin_function): If adds_command, increment the count.
(define_new_function): Set adds_command for loaded functions.
2022-01-17 18:45:47 -05:00
Paul Smith
26f4bb89bd * src/read.c (tilde_expand): Put back '/' before returning.
Joe Filion <joefilion4@gmail.com> noted that the string is modified,
and Henrik Carlqvist <hc94@poolhem.se> noticed that it wasn't put
back in all cases.
2022-01-17 18:38:32 -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 Smith
8aba33a8bd * README.template: Clean up patch submission information 2021-12-29 15:26:54 -05:00
Jouke Witteveen
d365bdfdbc * src/read.c (find_percent_cached): [SV 60798] Silence GCC11 warnings 2021-12-19 16:55:50 -05:00
Jouke Witteveen
f440c3ebe2 [SV 60798] Silence bogus GCC10 and GCC11 warnings
* src/main.c (main): Use a separate variable to track final character.
* src/read.c (eval): Track the semicolon position not one beyond it.
* src/variable.c (do_variable_definition): Include a default switch
case to ease the work of the exhaustiveness prover.
2021-12-19 16:55:50 -05:00
Paul Smith
3efba8a145 Update documentation with instructions for patch submission
* README.template: Add notes on how to submit patches.
* README.git: Point to the README.
* doc/make.texi: Ditto.
2021-12-19 16:55:50 -05:00
Paul Smith
e7b2f6818c Change HTTP URLs to use HTTPS instead
Also remove unnecessary tests/COPYING file.

* README.template: Change http: to https:
* README.git: Ditto
* doc/make.texi: Ditto
* doc/make.1: Ditto
* src/main.c: Ditto
* maintMakefile: Remove invalid URL
2021-12-19 16:55:50 -05:00
Paul Smith
c90db9276a * src/makeint.h: Compute INTSTR_LENGTH based on size of intmax_t
Math suggested by Edward Welbourne <edward.welbourne@qt.io>
2021-12-19 16:55:47 -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
55b993ae09 * doc/make.text (Wildcards): Document that glob results are sorted. 2021-12-19 16:34:19 -05:00
Paul Smith
1d20aa7247 [SV 61621] Don't use POSIX_SPAWN_RESETIDS with posix_spawn()
When make is invoked in a environment where the user namespace is
restricted, such as under unshare(1) (on GNU/Linux), it won't be able
to find its real UID so the effective UID can't be set to it and
posix_spawn() will fail with EINVAL.

It's not less safe to run recipe jobs using the same UID values that
make was invoked with, so don't worry about this flag.

* src/job.c (child_execute_job): Don't set POSIX_SPAWN_RESETIDS flag.
2021-12-19 16:34:10 -05:00
Paul Smith
21f7ac8f47 * .gitignore: Ignore patch files. 2021-12-05 14:22:37 -05:00
U2FsdGVkX1
aa376ad638 * src/commands.c (fatal_error_signal) [W32]: Use %lu for DWORD.
* src/function.c (windows32_openpipe) [W32]: Ditto.

Copyright-paperwork-exempt: yes
2021-11-28 15:51:37 -05:00
Paul Smith
35b51df110 * NEWS: Update with author details 2021-11-28 14:34:05 -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
Jouke Witteveen
f3ad572099 * src/makeint.h: Removed unused atol declaration 2021-11-27 22:05:29 -05:00
Paul Smith
cefe747e85 * src/implicit.c (pattern_search): Fix text for easier translation. 2021-11-27 22:00:12 -05:00
Paul Smith
3ecf97d3af [SV 48643] Update the implicit rule search docs
* NEWS: Announce the change.
* doc/make.texi (Implicit Rule Search): Update the definition of
"ought to exist" and add the extra step for compatibility mode.
2021-11-27 22:00:12 -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
Dmitry Goncharov
f8f9d371ff [SV 61042] Enhance logging of implicit rule search
Logging of implicit rule search gives limited information as to why a
given implicit rule was rejected, and if no implicit rule is found we
get the confusing "No rule to make target" result when the real issue
is that some prerequisite of some implicit rule could not be built.

Enhance logging around implicit rule search as follows:
1. The messages which refer to a rule print a description (the targets
   and prerequisites) of the rule.
2. A new message tells when a rule is rejected, along with the reason.
3. The 'Looking for an implicit rule...' message is printed for every
   prerequisite, not just the top-level target.
4. "Trying harder" message is printed, when intermediate prerequisites
   are going to be searched.
5. The 'No rule found...' and 'Found implicit rule...' messages are
   printed for every prerequisite, not just the top-level target.
6. "Ought to exist...", "Found..." or "Not found..." message is
   printed for each prerequisite.

* src/rule.h (struct rule): Remember the definition of the rule.
* src/rule.c (get_rule_defn): Compute the definition of a rule.
(install_pattern_rule): Initialize the definition to empty.
(create_pattern_rule): Ditto.
(freerule): Free the definition.
(print_rule): Use the definition when printing rules.
* src/remake.c (update_file_1): Push debug output down into
try_implicit_rule().
* src/implicit.c (try_implicit_rule): Add debugging
(pattern_search): Show the rule definition in various debug output.
Add new debug messages for implicit rule search.

Additional changes by Paul Smith <psmith@gnu.org>:

Since we usually don't need the rule definition, defer computing it
until we do.

* bootstrap.conf: Include the mempcpy Gnulib module.
* src/makeint.h (mempcpy): Declare mempcpy if not available.
* src/misc.c (mempcpy): Define mempcpy if not available.
* src/config.h-vms.template: Don't set HAVE_MEMPCPY.
* src/config.h.W32.template: Ditto.
* src/rule.h (get_rule_defn): Return the definition of a rule.
* src/rule.c (get_rule_defn): If we don't have a definition compute
it; either way return it.
* src/implicit.c (pattern_search): Rework the handling of explicit
prerequisites to pattern rules to be more clear.  There is no change
in behavior.
2021-10-18 23:00:21 -04:00
Dmitry Goncharov
f5af979357 * doc/make.texi (Special Targets): [SV 61122] Add .SECONDARY example 2021-10-17 19:08:16 -04:00
Paul Smith
76cb186732 * README.git: Update C version prerequisite 2021-10-17 19:08:16 -04:00
Paul Smith
6c06c547dc Add support for the POSIX :::= assignment operator.
POSIX Issue 8 will require a new assignment operator, :::=.
This operator behaves similarly to the BSD make := operator: the
right-hand side is expanded immediately, but then the value is
re-escaped (all '$' are converted to '$$') and the resulting variable
is considered a recursive variable: the value is re-expanded on use.

* src/variable.h (enum variable_flavor): Add f_expand flavor.
* src/variable.c (do_variable_definition): When defining f_expand,
post-process the result to re-escape '$' characters.
Remove default: to the compiler warns about un-handled enum values.
Set recursive values for both f_recursive and f_expand.
(parse_variable_definition): Rewrite this method.
The previous version was annoying to extend to ':::='.
(print_variable): Remove default: so the compiler warns us about
un-handled enum values.
* src/function.c (func_origin): Remove default: so the compiler warns
us about un-handled enum values.
* doc/make.texi: Add documentation for :::=.
* tests/scripts/variables/define: Add a test for define :::=.
* tests/scripts/variables/flavors: Add tests for :::=.
* tests/scripts/variables/negative: Add tests for :::=.
2021-09-20 00:29:31 -04:00
Paul Smith
c5d4b7b2f2 Clean up more Windows warnings.
* src/config.h.W32.template: Re-enable warnings that we don't violate.
Add a new disabled warning: 4130 (logical operation on address of
string constant).
* src/w32/compat/posixfcn.c: Make makeint.h the first included header.
* src/w32/subproc/sub_proc.c: Ditto.  It includes config.h already.
2021-09-07 01:14:33 -04:00
Dmitry Goncharov
9e4b3d3f4c [SV 60435] Ensure intermediate grouped files are removed
If multiple intermediate files are built together be sure all of them
are removed after make is finished.  Continue to ensure that targets
that exist before make starts are not removed even if they appear to be
intermediate.

Add a number of tests to pattern rules to verify this behavior.

* src/filedef.h (struct file): Add a new is_explicit bitfield.
* src/file.c (rehash_file): Merge the is_explicit bit.
(enter_prereqs): Set is_explicit if the file is explicitly mentioned.
* src/implicit.c (pattern_search): Set intermediate on the file if it's
not explicit.
(record_files): Set is_explicit if a file is mentioned as a target.
* src/remake.c (update_file_1): Set secondary on files that already
exist so they won't be removed.
* tests/scripts/features/double_colon: Add a test for double-colon
pattern rules.
* tests/scripts/features/patternrules: Update KGO for tests where more
files are removed.
Add new tests to verify handling removal of intermediate files in the
context of grouped pattern targets.
2021-09-07 01:14:20 -04:00
Paul Smith
5a96d5a066 * src/default.c (default_variables): Use CPP in PREPROCESS.S. 2021-09-06 20:42:34 -04:00
Dmitry Goncharov
4488592dda * src/main.c (decode_debug_flags): [SV 607777] Preserve -d options
* tests/scripts/options/dash-d: Test that -d --trace keeps -d.
2021-09-06 20:36:15 -04:00
Dmitry Goncharov
e7eb8b5962 [SV 57778] Don't ignore included makefiles that can't be read
If we find an included makefile but it's not readable, stop
immediately with an error rather than continuing to look in other
directories.

* src/read.c (eval_makefile): Only keep searching if the fopen error
is ENOENT, else stop and fail.
* tests/scripts/features/include: Add tests to verify this behavior.
2021-09-06 20:20:28 -04:00
Paul Smith
0c2fc00544 [SV 60795] Don't remake phony included makefiles and show errors
Change the handling of included makefiles which are phony targets to
be similar to double-colon rules with no prerequisites: simply don't
build them at all during the remake a makefile phase.

Ensure that any included makefile which is needed but not built
results in an error.

Update the documentation to make this clear.
Add tests to verify this behavior.

* doc/make.texi (Remaking Makefiles): Clarify double-colon exception.
Document that phony targets are handled the same way.
(Phony Targets): Ditto.
* src/main.c (main): Check for phony targets when skipping goals.
Rather than throwing out skipped but failed goals keep them
separately then report them as errors.
* src/read.c (eval): Set the file location on included makefiles even
when there's no error.
* tests/scripts/features/include: Add tests for handling included
makefiles with both phony and double-colon rules to rebuild them.
2021-09-06 18:49:08 -04:00
Paul Smith
214df0e92a * doc/make.texi (Environment): [SV 60841] Clarify variable exporting. 2021-09-06 10:57:43 -04:00
Paul Smith
b2e898d0bf * doc/make.texi (Chained Rules): [SV 60904] Clarify intermediate files. 2021-09-06 10:46:52 -04:00
Paul Smith
abb1e8d10b Remove UBSAN issues discovered via fuzzing tests.
The arithmetic conversions in C say that if a binary operator has an
unsigned and signed type as operands and the unsigned type has a greater
rank then the signed value is converted to unsigned.  This is bad if the
signed value is negative.

There are a few places in the code which have this situation; convert
the signed value to positive and add instead of subtracting.

Reported by He Jingxuan <jingxuan.he@inf.ethz.ch>

* src/read.c (find_map_unquote): Use a positive int in memmove().
(find_char_unquote): Ditto.
(find_percent_cached): Ditto.
2021-09-06 00:14:57 -04:00
Paul Smith
cc6dc70b16 * doc/make.texi (Prerequisite Types): [SV 61069] Mention PHONY prereqs 2021-09-05 23:29:33 -04:00
Paul Smith
2638552859 * doc/make.1: Clean up man page text. 2021-09-05 23:17:26 -04:00
Paul Smith
de48d6a4f7 * README.git: Add a section on ways to test. 2021-09-05 22:28:36 -04:00
Paul Smith
55f06bdc3f * src/main.c (decode_switches): Fix memory leak. 2021-09-05 22:28:10 -04:00
Paul Smith
0d367bbe6e Clean up a few Windows build warnings (not all!)
* build_w32.bat: Quote uses of %VSWHERE% so it can contain spaces
* src/hash.c (hash_init): Avoid use of an undefined struct.
(hash_rehash): Ditto.
* src/vpath.c (construct_vpath_list): Cast explicitly to void*.
2021-09-05 21:09:27 -04:00
Paul Smith
f4b8ddf260 [SV 45211] Parse MAKEFLAGS immediately when it's reset
When MAKEFLAGS is set in a makefile, reparse it immediately rather
than waiting until after all makefiles have been read and parsed.
This change doesn't actually fix the SV bug referenced because, even
though we do reparse MAKEFLAGS, we don't handle the -r or -R options
immediately.  Doing this will require more effort.

* NEWS: Announce the change.
* src/makeint.h: Publish reset_switches() and decode_env_switches()
from main.c
* src/main.c (main): Don't call construct_include_path(); it will be
invoked decode_switches().
Preserve the old values of builtin_rules, builtin_variables, and
job_slots before we read makefiles since they can be changed now.
(reset_switches): Publish (remove static).  Set the initial value of
the stringlist list to NULL.
(decode_switches): Call construct_include_path() after decoding.
(decode_env_switches): Publish (remove static).
(define_makeflags): Set the MAKEFLAGS variable for special handling.
* src/read.c (eval_makefile): Check for empty include_directories.
(construct_include_path): Clear any old value of .INCLUDE_DIRS before
appending new values.  Free the previous include_directories.
* src/variable.c (lookup_special_var): When MAKEFLAGS is set, first
reset the switches then re-parse the variable.
* tests/run_make_tests.pl: Memo-ize some default variable values.
* tests/scripts/options/dash-r: Create tests for setting -r and -R.
* tests/scripts/variables/MAKEFLAGS: Test that resetting -I from
within the makefile takes effect immediately.
2021-09-05 21:08:59 -04:00
Paul Smith
e13fd5c83d * make-gdb.py: Add pretty-printers and clean up.
Create a pretty-printer for next-pointer lists.
Create a pretty-printer for stringlists.
Change showargv from a function to a command (easier to use).

Clean up some Python PEP violations.  Add support for testing null
pointers and caching gdb.Types.
2021-09-05 20:05:02 -04:00
Paul Smith
7c4e6b0299 [SV 60595] Restart whenever any makefile is rebuilt
Previously if an included makefile was rebuilt as a prerequisite of
another included makefile which didn't need to be rebuilt, make would
not realize that it needed to re-exec itself.

Ensure that if any included makefile target is rebuilt we re-exec.
Also ensure that if an included makefile is not readable, and our rule
for rebuilding it doesn't actually change it, we will still fail.

* src/remake.c (update_goal_chain): If a goal's update was successful
then check its status, even if no actual commands were run because it
was already up to date.
(show_goal_error): Remove superfluous cast.
* src/main.c (main): If the makefile remake did nothing, check that we
were able to successfully include all the makefiles we care about; if
not fail.  When generating error messages about included makefiles be
sure to show the filename/linenumber information.
* test/scripts/features/reinvoke: Add tests for this behavior.
* test/scripts/options/dash-k: Update error messages.
2021-09-03 12:08:11 -04:00
Paul Smith
b9c4fc441b [SV 60412] Allow -I- to throw out the current directory path
Accept a "-" directory value to the -I option to clear the set of
directories to be searched up to that point, including the default
directories.

* NEWS: Announce the change.
* doc/make.texi (Summary of Options): Add documentation.
* src/read.c (construct_include_path): Check for '-' and if found,
clear the list of directories to be searched.
* tests/scripts/options/dash-I: Add tests for -I-.
* tests/scripts/variables/INCLUDE_DIRS: Add tests for -I-.
2021-09-03 12:08:11 -04:00
Dmitry Goncharov
65b73ce434 [SV 60699] Avoid calling strlen() repeatedly in a loop
* src/variable.c (lookup_pattern_var): Accept target length parameter.
(initialize_file_variables): Pass computed target length to lookup.
2021-07-25 17:15:38 -04:00
Paul Smith
2d73c9bf25 * NEWS: Add a few missing attributions
* AUTHORS: Add some missing attributions
2021-07-25 17:15:38 -04:00
Dmitry Goncharov
33468b3f31 [SV 60297] Add .NOTINTERMEDIATE special target
Support a new special target, .NOTINTERMEDIATE.  Any file or pattern
prerequisite of this target will never be considered intermediate.
This differs from .SECONDARY in that .SECONDARY files won't be deleted
but they will still not be built if they are missing.

.NOTINTERMEDIATE files are treated the same way as a target which is
explicitly mentioned in the makefile.  This is mostly useful with
patterns; obviously mentioning a target explicitly here is enough in
and of itself to make something not intermediate.

Some adjustments made by psmith@gnu.org

* NEWS: Announce the new feature.
* doc/make.texi (Special Targets): Document .NOTINTERMEDIATE.
(Chained Rules): Describe how to use .NOTINTERMEDIATE.
* src/main.c (main): Add "notintermediate" to the .FEATURES variable.
* src/filedef.h (struct file): Add "notintermediate" flag.
* src/file.c (no_intermediates): Mark global .NOTINTERMEDIATE.
(snap_file): Support .NOTINTERMEDIATE special target.  Throw an error
if the same target is marked both .NOTINTERMEDIATE and .SECONDARY or
.INTERMEDIATE.
(rehash_file): Merge intermediate, notintermediate, secondary flags.
(remove_intermediates): Check notintermediate flag before removing.
(print_file):
* src/implicit.c (pattern_search): Set notintermediate based on the
pattern.
* tests/scripts/targets/NOTINTERMEDIATE: Add a new test suite.
2021-07-25 17:15:38 -04:00
Paul Smith
1cffd0a203 * make.texi (Reading Makefiles): != creates recursive variables.
Reported by Ronald Hoogenboom <RHoogenboom@irdeto.com>.
2021-05-30 15:53:51 -04:00
Dmitry Goncharov
b580949ae0 [SV 60659] Set $$< properly in second expansion
Set the $$< automatic variable as best we can during secondary
expansion of prerequisites.

* src/commands.c (set_file_variables): Don't break without setting
'less' if secondary expansion is enabled.
* tests/scripts/features/se_explicit: Test secondary expansion results.
* tests/scripts/features/se_implicit: Test secondary expansion results.
2021-05-30 15:53:41 -04:00
Paul Smith
f2771aa614 [SV 58341] Add non-trivial options to $(MAKEFLAGS)
Previously only trivial (single-letter) options were available in
$(MAKEFLAGS) when it is examined from inside a makefile (the full
value was set before expanding recipes).

Ensure that all options (but, not command line variable overrides!)
are visible in the $(MAKEFLAGS) variable.  In order to do this
reset the default values of options, particularly options which are
lists, before re-reading MAKEFLAGS after makefiles have been read.
Otherwise we'll get duplicate values for options such as -I.

Unfortunately there are complications here as well: sometimes (for
jobserver options in particular) we modify the values of these
options while running: we must not reset these modifications.

* NEWS: Announce this change
* src/main.c (main): Call new reset_switches() before re-parsing
MAKEFLAGS.
(reset_switches): Reset the value of non-special options to their
defaults.
(define_makeflags): Add non-special options into MAKEFLAGS even
if 'all' is not set.
2021-05-30 15:11:30 -04:00
Dmitry Goncharov
5e829188d3 [SV 60378] Don't add duplicate default search directories
Depending on how make was configured it may add duplicate
directories in the default include search path: avoid this.

(Tweaked by psmith@gnu.org)

* configure.ac: Set AM variable KNOWN_PREFIX if --prefix is known
* Makefile.am: Only set INCLUDEDIR if prefix is not known
* read.c [default_include_directories]: Only add INCLUDEDIR if set
2021-05-30 15:11:30 -04:00
Dmitry Goncharov
297cb5adb7 * tests/scripts/targets/INTERMEDIATE: [SV 60188] Add one more test 2021-05-30 15:11:14 -04:00
Eli Zaretskii
012918bf11 [SV 58656] Fix mtime for large files on MS-Windows
In MSVC builds, 'stat' fails when called on files larger than
2GB.  Call '_stat64' instead to work around this.

* src/remake.c (STAT): Define to '_stat64' for MSVC builds.
(name_mtime) [WINDOWS32]: Use STAT instead of 'stat'.
Suggested by Makoto Kato <m_kato@ga2.so-net.ne.jp>.
2021-05-29 11:37:09 +03:00
Paul Smith
1ae90c030d Fix build and test issues on Windows
* src/dep.h (DEP): Remove extraneous semicolon.
* src/dir.c (find_directory) [W32]: Replace removed variable.
* tests/scripts/features/include: Allow the extra default makefile
searched for on Windows.
* tests/scripts/functions/file: Use $(info ...) to avoid "command
too long" errors on Windows.
2021-03-28 16:25:52 -04:00
Tobias Stoeckmann
0fb6f2d985 * src/remake.c (name_mtime): Reserve space for nul in readlink result
Copyright-paperwork-exempt: yes
2021-03-28 14:45:16 -04:00
Cao jin
97a8d9b45a * doc/make.texi (Call Function): Apply consistent formatting
Copyright-paperwork-exempt: yes
2021-03-25 14:38:58 -04:00
Pete Dietl
c5c02accb7 * src/job.c (child_execute_job): Update gnulib find_in_given_path()
Copyright-paperwork-exempt: yes
2021-03-25 14:25:26 -04:00
Mike Frysinger
76a099997b * doc/make.texi (Automatic Variables): Relocate the $? example
Copyright-paperwork-exempt: yes
2021-03-25 13:10:29 -04:00
Paul Smith
c5319e75f5 [SV 58497] Ensure $(file <) newline removal succeeds
Keep a count of bytes read rather than comparing pointers since the
variable_buffer might get reallocated.

Bug and patch by Ken Tossell <ken@tossell.net>
Regression tests by Dmitry Goncharov <dgoncharov@users.sf.net>
Tweaked by Paul Smith <psmith@gnu.org>

* src/function.c (func_file): Use bytes read rather than a pointer.
* tests/scripts/functions/file: Provide various tests for reading
empty files, files with/without newlines, and large files.
2021-03-15 03:28:11 -04:00
Dmitry Goncharov
510e5ce801 [SV 60188] Explicit prereqs cannot be intermediate files
If a prereq of a pattern is an explicit target, it should not be
considered an intermediate file.

(Minor tweaks by Paul Smith <psmith@gnu.org>)

* src/dep.h (struct nameseq): Add is_explicit flag.
* src/implicit.c (struct patdeps): Ditto.
(pattern_search): Set the is_explicit flag appropriately for each
prerequisite, based on whether it contained a pattern or not.
Update the help output to note implicit vs. explicit prereqs.
* tests/scripts/features/double_colon: Add tests.
* tests/scripts/features/grouped_targets: Ditto.
* tests/scripts/features/patternrules: Ditto.
* tests/scripts/features/se_implicit: Ditto.
* tests/scripts/features/statipattrules: Ditto.
2021-03-15 02:10:49 -04:00
Paul Smith
144f436c4b * tests/scripts/features/exec: Small cleanup 2021-03-15 01:17:06 -04:00
Paul Smith
52056d7b2c Ensure variable_buffer is always set.
Initialize the global variable_buffer in main() so that it is never
a null pointer.  Then invoking variable_expand("") is never needed:
simply use the variable_buffer pointer when we want to restart the
variable buffer.  The main point of this simplification is not to
keep a separate pointer to the beginning of the buffer: this is
dangerous because the buffer may be re-allocated.  Instead always
use the variable_buffer pointer itself.

* src/variable.h (initialize_variable_output): Publish.
* src/expand.c (initialize_variable_output): Remove static.
* src/main.c (main): Initialize variable_buffer.
* src/file.c (enter_prereqs): Don't call variable_expand("") and
don't save a separate buffer pointer than might be outdated.
(expand_deps): Ditto.
* src/read.c (record_files): Ditto.
* src/remake.c (library_search): Ditto.
2021-03-15 01:17:06 -04:00
Paul Smith
c66ec5fa20 [SV 59881] Handle vertical TAB consistently
While parsing makefiles get_next_mword() was treating VTAB as a word
character rather than a word separator.  However, when using
find_next_token(), for example in patsubst_expand_pat(), we treated
VTAB as a word separator causing multiple words to appear where we
didn't expect them.

* src/makeint.h (END_OF_TOKEN): Change from a loop to a boolean check.
* src/misc.c (end_of_token): Move the loop here.
* src/read.c (get_next_mword): Skip whitespace, not just blank, to
find the start of the word and use END_OF_TOKEN() to decide when the
current word is finished.
2021-03-15 01:16:32 -04:00
Paul Smith
da6fc6aae2 [SV 59870] define/undefine prerequisites are not target-specific vars
* src/read.c (parse_var_assignment): If called in a target-specific
variable context don't allow define/undefine as variable assignments.
* test/scripts/variables/define: Add a test.
* test/scripts/variables/undefine: Add a test.
2021-03-14 16:35:38 -04:00
Paul Smith
d9aff6b817 * maintMakefile: Don't make .check-git-HEAD .PHONY 2021-03-14 15:53:45 -04:00
Jouke Witteveen
e5f6dc54b9 More correctly describe the scope of variables
* NEWS: Use "local" instead of the incorrect "lexically-scoped".
* doc/make.texi: Refer to let/foreach variables as local variables.
2021-03-07 19:06:59 -05:00
Paul Smith
88732a29f2 * doc/make.text: Clarify that patsubst doesn't touch unmatched words 2021-03-07 19:05:20 -05:00
Paul Smith
7b0a741857 * .dir-locals.el: Update for newer LSP config 2021-03-07 19:04:48 -05:00
Paul Smith
74bd8b3aa5 * file.c (remove_intermediates): Restart "rm ..." on error 2021-03-07 19:04:22 -05:00
Paul Smith
9043b28250 * doc/make.texi (How Patterns Match): [SV 58639] Fix chaining info. 2020-12-07 01:03:11 -05:00
Jouke Witteveen
fcc11d05a6 Create $(let ...) providing lexically scoped variables
Add a new function $(let ...) which allows lexically scoped variables.

* NEWS: Add information on this feature.
* doc/make.texi (Let Function): Document the 'let' function.
* src/function.c (func_let): Create the 'let' built-in function.
* tests/scripts/functions/let: Test the 'let' built-in function.
2020-12-06 18:30:58 -05:00
Paul Smith
a8f4669b23 * doc/make.texi (Phony Targets): [SV 58961] Clarify pattern handling 2020-12-06 15:21:23 -05:00
Paul Smith
bd4829096c * doc/make.texi (Synchronized Terminal Output): [SV 58960] Fix link 2020-12-06 10:14:15 -05:00
Paul Smith
7044e0c93c [SV 59169] Add --debug=why and --debug=print options
Add debug options to print recipes even if they would otherwise be
silent, and to print the reason that a target was considered out of
date.

Modify --trace to simply be a shorthand for --debug=print,why.

* NEWS: Announce changes.
* doc/make.texi (Summary of Options): Document the new options.
* doc/make.1: Ditto.
* src/debug.h: Add new flags DB_PRINT and DB_WHY.
* src/makeint.h: Remove the trace_flag variable.
* src/job.c (start_job_command): Check debug flags not trace_flag.
(new_job): Ditto.
* src/main.c (trace_flag): Make a static variable for switches.
(decode_debug_flags): Set DB_PRINT and DB_WHY if trace_flag is set.
* tests/scripts/variables/GNUMAKEFLAGS: Update known-good messages.
* tests/scripts/variables/MAKEFLAGS: Ditto.
2020-12-05 16:25:12 -05:00
Paul Smith
94d9077691 * configure.ac: [SV 58836] Copy build.sh to the build directory 2020-12-05 15:11:52 -05:00
Paul Smith
c4cc2e9595 [SV 57676] Support included files being built after failing
If a -include file does not exist, then some subsequent operation
creates it, then allow it to be successfully included.

* src/read.c (eval_makefile): If our last mtime was NONEXISTENT then
reset it to 0 so we'll check it again.
* tests/scripts/features/include: Add a test for this behavior.
2020-12-05 15:06:25 -05:00
Paul Smith
5e234e4048 * src/makeint.h (free_alloca): Check for builtin alloca 2020-12-02 17:29:16 -05:00
Paul Smith
950f3d305f * src/main.c (main): [SV 59601] Check for malformed env. variables 2020-12-02 17:27:55 -05:00
Paul Smith
58a37927e6 * maintMakefile: [SV 58794] Check for file existence in the release 2020-11-29 17:59:40 -05:00
Paul Smith
ec272f3a9c * Makefile.am (HAVE_GUILE): Only use Guile options if HAVE_GUILE. 2020-11-29 17:59:40 -05:00
Paul Smith
ef6aca5a38 * tests/scripts/features/vpathgpath: Avoid duplicate function name. 2020-11-29 17:59:40 -05:00
Paul Smith
b262ea5d8f Resolve unused-result warnings for alloca(0)
* src/makeint.h (free_alloca): New macro to defeat warn_unused_result.
* src/read.c (eval_makefile): Call it.
(eval_buffer): Ditto.
* src/remake.c (update_file): Ditto.
2020-11-29 17:59:40 -05:00
Paul Smith
cc20f90507 Avoid some valgrind warnings
Using sscanf() to parse archive header values (struct ar_hdr) can lead
to valgrind warnings which are probably bogus but are annoying.
To be safer, create a local method to convert the ASCII integer
strings into integers.

* src/arscan.c (parse_int): Turn integer strings into integers.
(ar_scan): Initialize struct ar_hdr memory.
Call parse_int() rather than sscanf/atol.
2020-11-29 17:59:40 -05:00
Paul Smith
9e2fa24649 [SV 41273] Allow the directory cache to be invalidated
Each time we invoke a command it's possible that it will change the
filesystem in ways that were not described by the target.  If that
happens but we have cached previous directory contents then we may
make decisions or report results based on obsolete information.

Keep a count of how many commands we've invoked, and remember the
current command count every time we load the contents of a directory.
If we request the directory and the current command count has changed
we know the cache is outdated so reload from scratch.

* NEWS: Announce the change.
* src/makeint.h (command_count): Create a global counter.
* src/main.c (command_count): Ditto.
* src/job.c (reap_children): Increment the counter on job completion.
* src/function.c (func_file): Increment if we write a file.
* src/dir.c (clear_directory_contents): Clear the current contents of
a cached directory.
(struct directory_contents): Remember the counter value.
(struct directory): Remember the counter value for non-existing dirs.
(find_directory): If we have a cached directory and the count hasn't
changed then return it.  Else, clear the previous contents and re-read
from scratch.
* tests/scripts/features/dircache: Add tests of the directory cache.
2020-11-29 17:59:16 -05:00
Paul Smith
2dc0280d82 Support "unexport" in target-specific variables.
Rewrite the environment variable algorithm to correctly inherit
export settings from parent variable sets.  The new algorithm
for computing the table of environment variables is:

- Start with the most local variable set and proceed to global.
- If the variable already exists in the table and we don't know
  its export status, update it with the current variable's status.
- If the variable is not in the table and it's not global, add it
  regardless of its status so if it's unexported we remember that.
- If the variable is not in the table and is global, check its
  export status and don't add it if we won't export it.

Then when generating the environment variables, check the export
status of each variable in case it was a target-specific variable
and we have determined it should not be exported.

Rework SHELL handling to check at the end whether we added it or
not and if we didn't, add the value from the environment.

* NEWS: Announce support for target-specific "unexport"."
* doc/make.texi (Target-specific): Document the support.
* src/variable.h (enum variable_export): Make into a global type.
* src/read.c (struct vmodifiers): Use enum variable_export rather
than individual booleans.
(parse_var_assignment): Parse the "unexport" keyword.
(eval): Remember the vmodifier value in the variable.
(record_target_var): Ditto.
* src/variable.c (should_export): Check if the variable should be
exported.
(target_environment): Implement the above algorithm.
* tests/scripts/features/export: Test export/unexport with variable
assignments on the same line.
* tests/scripts/features/targetvars: Add a comprehensive suite of
tests for different types of target-specific export / unexport.
* tests/scripts/variables/SHELL: Update the comment.
2020-11-29 17:57:33 -05:00
Dmitry Goncharov
90959b8b70 [SV 59230] Preserve export settings for target-specific vars
* src/read.c (record_target_var): Don't overwrite pre-existing export
flag unless we're changing it.
* tests/scripts/features/targetvars: Add a test.
2020-11-29 17:55:32 -05:00
Paul Smith
19ae6fe72a [SV 59230] Ensure environment variables are exportable
When checking for invalid environment variable names we searched the
entire name string instead of just the first LENGTH chars; this could
cause us to incorrectly decide the variable was not exportable.

Dmitry Goncharov <dgoncharov@users.sf.net> found this bug and
provided a test case and sample fix: I used the test but chose a
slightly different fix.

* src/variable.c (define_variable_in_set): check the variable name
not the input string.
* tests/scripts/features/targetvars: Ensure environment variable
values are exported.
2020-11-29 17:55:32 -05:00
Paul Smith
0e020bbc24 * src/default.c (default_variables) [AIX]: [SV 59096] Fix ARFLAGS
Reported by Dmitry Goncharov <dgoncharov@users.sf.net>, with a patch
changing the pattern rule for building archives.  I decided to
change the default value of ARFLAGS on AIX instead.
2020-11-29 17:55:32 -05:00
Paul Smith
c01222c018 [SV 35711] Check for special targets earlier
GNU make must recognize some special targets as they are defined.
Because of the way targets are defined, we were not recognizing these
special targets until we were handling the NEXT statement.  However
that's too late for some special targets such as .POSIX etc. which can
change the behavior of make during parsing.

Check for special targets earlier, as soon as we've finished parsing
the target introduction line (before we've even parsed the recipe).

* NEWS: Mention the change.
* src/read.c (check_specials): New function to look for special
targets.  Move checks from eval() and record_files() to this new
function.
(eval): Call check_specials() after we've completed parsing the target
introduction line.  Move default goal detection to check_specials().
(record_files): Move handling of .POSIX, .SECONDEXPANSION, and
.ONESHELL to check_specials().
* tests/scripts/misc/bs-nl: Remove workaround for late .POSIX issue.
* tests/scripts/targets/POSIX: Add a comment.
2020-11-29 17:55:02 -05:00
Paul Smith
957aa450a0 * .ccls: Disable clang compare against static string warning 2020-11-29 10:02:45 -05:00
Paul Smith
e49e11e069 [SV 59093] Rewrite filter/filter-out to avoid large stack usage
* src/function.c (func_filter_filterout): Allocate arrays to hold
pattern and word information rather than creating linked lists on
the stack.
* tests/scripts/functions/filter-out: Test large filters.
2020-11-13 00:44:24 -05:00
Paul Smith
f4f353bb54 * doc/make.texi (Include): Update behavior for missing included files 2020-10-28 11:10:52 -04:00
Paul Smith
a80b0096f5 * NEWS: [SV 58435] Document minimum C compiler version requirement
* configure.ac: Require c99 via AC_PROG_CC_C99
2020-07-19 18:59:06 -04:00
Paul Smith
62e8f029e9 [SV 58735] Define the order that makefiles are rebuilt.
Ensure that makefiles are rebuilt in the order in which make first
considered them, and document this behavior in the manual.

* NEWS: Add a note about the new behavior
* doc/make.text (How make Processes a Makefile): Document it.
* main.c (main): Inverse the list of makefile goals.
* read.c (read_all_makefiles): Add default makefiles to the list at
the front in reverse order, the same way other makefiles are added.
* tests/scripts/features/include: Add tests to verify rebuild order.
2020-07-19 13:56:23 -04:00
Paul Smith
db7658e042 * src/makeint.h: [ARM] [SV 58347] Don't assume ARM is not POSIX 2020-07-10 11:59:40 -04:00
Paul Smith
fa7f95c66c * src/job.c (unblock_sigs): [!POSIX] [SV 58743] Fix syntax errors 2020-07-10 11:59:38 -04:00
Paul Smith
df5f30a76a * NEWS: Fix some tortured grammar. 2020-05-14 01:00:28 -04:00
Paul Smith
1770540217 [SV 57930] Cast char to unsigned char to call ctype functions
This cast was already done almost everywhere: fix some stragglers.

* src/load.c (load_file): Cast char to unsigned char.
* src/misc.c (strcasecmp, strncasecmp): [!POSIX] Ditto.
* src/dir.c (vms_hash): [VMS] Ditto.
* src/vms_progname.c (set_program_name): [VMS] Ditto.
* src/vms_jobs.c (posix_parse_dq): [VMS] Ditto.
(posix_parse_dollar): [VMS] Ditto.
(build_vms_cmd): [VMS] Ditto.
(child_execute_job): [VMS] Ditto.
2020-05-03 14:54:56 -04:00
Paul Smith
c8a6263eb5 Convert [ ... ] to test ... in scripting.
The "[" link may be missing during OS boostrapping.

* build.sh: Convert "[ ... ]" to "test ..."
* maintMakefile: Ditto.
* scripts/copyright-update: Ditto
* tests/scripts/features/reinvoke: Ditto
* tests/scripts/features/targetvars: Ditto
2020-05-03 14:23:56 -04:00
Paul Smith
a015d1f822 * maintMakefile: Clean up output 2020-05-03 14:23:56 -04:00
Paul Smith
c604e53a45 * mainMakefile: Check that INSTALL exists in the dist file
For some reason the INSTALL file symlinked to gnulib was omitted from
the 4.3 release package: I can't reproduce this but check for it.
2020-05-03 14:23:40 -04:00
Kevin Buettner
d79fe162c0 [SV 58232] Disable inheritance of jobserver FDs for recursive make
A parent make will invoke a sub-make with close-on-exec disabled for
the jobserver pipe FDs.  Force close-on-exec to be to be enabled in
the sub-make so the pipe is not always passed to child jobs.

I have a test case which, when invoked with a suitable -j switch,
will hang if the recipe inherits the jobserver pipe.  This test case
was inspired by a real world case in which testing GDB on Fedora
would hang due to some poorly written test GDB cases having been
passed the jobserver file descriptors.

* src/posixos.c (jobserver_parse_auth): Call fd_noinherit() for
jobserver pipe descriptors.

Copyright-paperwork-exempt: yes
2020-05-02 20:09:29 -04:00
Paul Smith
0c326a66c9 [SV 57674] Use the system default PATH if $PATH is not set
When using execvp() if $PATH is not present in the environment
it will automatically search the system default PATH string.  Emulate
this by passing the system default PATH to find_in_given_path() if
we don't find PATH in the environment.

* src/job.c (child_execute_job): Use confstr(_CS_PATH) if PATH is not
found.
2020-04-01 02:02:57 -04:00
Paul Smith
f79bde1a6d tests: Simplify customization of %ENV
Rather than having an %extraENV that is added to the default %ENV
and resetting %ENV _before_ each test, allow the test setup to
modify %ENV directly as needed then reset %ENV _after_ each test.

* tests/test_driver.pl: Remove unused %extraENV.
(resetENV): Don't add in %extraENV.
(_run_command): Reset after we run the command rather than before.
* tests/scripts/features/export: Convert %extraENV to %ENV
* tests/scripts/features/jobserver: Ditto
* tests/scripts/features/parallelism: Ditto
* tests/scripts/features/targetvars: Ditto
* tests/scripts/functions/eval: Ditto
* tests/scripts/functions/foreach: Ditto
* tests/scripts/functions/origin: Ditto
* tests/scripts/misc/general4: Ditto
* tests/scripts/options/dash-e: Ditto
* tests/scripts/targets/POSIX: Ditto
* tests/scripts/variables/GNUMAKEFLAGS: Ditto
* tests/scripts/variables/SHELL: Ditto
2020-04-01 02:02:57 -04:00
Jens Rehsack
289108cc9b * src/output.h: [WINDOWS32] [SV 57888] Use gnulib fcntl if available
If gnulib fcntl is available (for MinGW32) use it rather than our
homegrown version.

Signed-off-by: Jens Rehsack <sno@netbsd.org>
Copyright-paperwork-exempt: yes
2020-03-31 01:07:43 -04:00
Jens Rehsack
61c413d5ea * src/w32/compat/dirent.c: [SV 57888] Use gnulib opendir on MinGW32
Signed-off-by: Jens Rehsack <sno@netbsd.org>
Copyright-paperwork-exempt: yes
2020-03-31 00:50:21 -04:00
Jens Rehsack
d3a53d5d16 * src/dir.c (local_stat): [WINDOWS32] Fix buffer-overflow warning.
[SV 57888] Provide space for the path to use MAXPATHLEN plus nul.

Signed-off-by: Jens Rehsack <sno@netbsd.org>
Copyright-paperwork-exempt: yes
2020-03-31 00:48:57 -04:00
Paul Smith
1306023a4f [SV 57896] Change directories before checking jobserver auth
We want to process -C options as early as possible, before we might
write informational messages, so that Entering/Leaving messages have
the correct directory.

* src/main.c (main): Move code dealing with changing directories
before parsing of the jobserver auth flag.
* tests/scripts/features/jobserver: Test the order of enter/leave.
2020-03-31 00:33:13 -04:00
Paul Smith
80b90b7866 [SV 57967] Only set APPEND mode for regular files
APPEND is a permanent mode shared by all users of a file.  If we
set it on a tty, pipe, etc. it will stay in effect even after make
exits, which can cause problems.

Patch provided by 0xef967c36@gmail.com

* src/output.c (set_append_mode): Check for a regular file.

Copyright-paperwork-exempt: yes
2020-03-31 00:19:20 -04:00
Paul Smith
8e024a2532 Obey order of multiple print/no-print directory options
Previously if --no-print-directory was seen anywhere even once
(environment, command line, etc.) it would always take precedence
over any --print-directory option.  Change this so that the last
seen option (which will be the command line, if present there) takes
precedence.

* NEWS: Mark this change in behavior.
* src/makeint.h (print_directory): A new variable to control printing.
* src/output.c (output_dump): Use the new variable.
(output_start): Ditto.
* src/main.c: Add a new variable print_directory.  Use -1 for
print_directory_flag so we know of the option was seen or not.  Add a
new default_print_directory_flag set to -1 to keep options from being
added.
(switches): Use flag_off for --no-print-directory, rather than a
separate inhibit_print_directory_flag.
(main): If print_directory_flag was set by the user, use that for
print_directory.  If not, compute the print_directory value based on
-s, -C, and sub-makes as before.
* tests/scripts/variables/GNUMAKEFLAGS: -w is not added automatically
* tests/scripts/options/print-directory: Add tests for overriding
print-directory options.
2020-03-31 00:17:49 -04:00
Paul Smith
660a2eafe5 * NEWS: Update 4.3 with information on .SILENT / -s 2020-03-29 17:50:34 -04:00
Eli Zaretskii
8277806db6 * NEWS: Mention the new tcc support. 2020-02-29 11:16:19 +02:00
Christian Jullien
6ba5ea022a Add support for building with Tiny C for MS-Windows
* src/config.h.W32.template (HAVE_DIRECT_H, HAVE_STRCASECMP)
(HAVE_STRNCASECMP, HAVE_UMASK): Add __TINYC__ to MinGW condition.
(BATCH_MODE_ONLY_SHELL): Make this the default for Tiny C.

* build_w32.bat: Support building with Tiny C's tcc compiler.
2020-02-29 11:14:46 +02:00
Paul Smith
4533348826 Apply spelling corrections from Fossies spellcheck
See https://fossies.org/features.html#codespell
Spelling issues in Git commit messages or lib/* source are not applied.

* README.OS2.template: Apply spelling corrections.
* README.VMS: Ditto.
* src/commands.c: Ditto.
* src/config.ami.template: Ditto.
* src/configh.dos.template: Ditto.
* src/job.c: Ditto.
* src/job.h: Ditto.
* src/read.c: Ditto.
* src/variable.c: Ditto.
* src/vms_exit.c: Ditto.
* src/vms_export_symbol.c: Ditto.
* src/vms_progname.c: Ditto.
* src/vmsfunctions.c: Ditto.
* src/vmsjobs.c: Ditto.
* src/w32/pathstuff.c: Ditto.
* tests/scripts/variables/automatic: Ditto.
* tests/test_driver.pl: Ditto.
2020-01-20 19:25:54 -05:00
Paul Smith
68fbad6667 Update to GNU make 4.3.90
* NEWS: Add a 4.3.90 section and update Savannah bug URL
* configure.ac (AC_INIT): Change release to 4.3.90
2020-01-20 19:25:54 -05:00
Paul Smith
f430a65ccb GNU Make release 4.3
* NEWS: Update for the release
* configure.ac: New release number
* doc/make.texi: New edition number
2020-01-19 17:04:52 -05:00
Paul Smith
c30da63fd2 * configure.ac (guile): Check for Guile 3.0 installations 2020-01-19 17:04:52 -05:00
Paul Smith
3fb7312e9f * src/job.c (sh_cmds): [SV 57625] Update builtin shell command list 2020-01-19 17:04:52 -05:00
Paul Smith
dd6adfa454 Resolve some documentation issues
* doc/make.texi (Interrupts): [SV 46193] Recommend defensive recipes
* doc/make.texi: [SV 49262] Clarify interaction of prerequisites and
non-terminal match-anything rules.
2020-01-19 17:04:52 -05:00
Paul Smith
3b5e47b2e2 [SV 40657] Reinstate old behavior for suffix rules with prereqs
POSIX says that suffix rules cannot have prerequisites, but after
making this change we observed a number of makefiles "in the wild"
that were relying on this behavior and failed.

For .POSIX: makefiles, obey POSIX.  Otherwise preserve the old
behavior.  However, generate a warning so users know this is a
problem.  In a future version we will change all behavior to be
POSIX-conforming.

* NEWS: describe the change
* src/rule.c (convert_to_pattern): If posix_pedantic don't make a
pattern rule if prereqs exist.  Otherwise show a warning.
* tests/scripts/features/suffixrules: Add tests for the new behavior
including .POSIX vs. non-.POSIX.
2020-01-19 17:04:52 -05:00
Dmitry Goncharov
4e277f6fbd * tests/test_driver.pl: Enhance error messages 2020-01-05 10:46:58 -05:00
Paul Smith
ec946d7e21 * doc/make.texi: Change the GFDL to an Appendix 2020-01-04 13:24:39 -05:00
Paul Smith
16d06006a4 * NEWS: Clarify authorship of new features. 2020-01-04 13:24:39 -05:00
Paul Smith
b774aebffa Enable compilation with C90 compilers
* configure.ac: Try compiling Guile headers: they don't work with C90.
* maintMakefile: Simplify config checks via target-specific variables.
* src/makeint.h: Use ATTRIBUTE rather than defining __attribute__,
as that causes compile issues with system headers.
(ENUM_BITFIELD): Don't use enum bitfields in ANSI mode.
* src/main.c: Use ATTRIBUTE instead of __attribute__.
* src/job.h: Ditto.
* src/file.c: Don't define variables inside for loops.
* src/rule.c: Ditto.
* src/dep.h (SI): Only use static inline in non-ANSI mode.
2020-01-04 13:23:23 -05:00
Paul Smith
06de697268 * bootstrap: Update to the latest gnulib version 2020-01-03 15:44:13 -05:00
Paul Smith
fdfe0446b6 Release GNU make 4.2.93
* NEWS: Update the release and date
* configure.ac: Update the release number
2020-01-03 02:08:59 -05:00
Paul Smith
12b14f0484 Update copyright statements for 2020 2020-01-03 02:08:59 -05:00
Paul Smith
4e12a5fa45 Support the .EXTRA_PREREQS special variable
Initial implementation by Christof Warlich <cwarlich@gmx.de>

* NEWS: Announce the new feature.
* doc/make.texi (Other Special Variables): Document .EXTRA_PREREQS.
* src/dep.h (struct dep): New flag to note extra prereq deps.
* src/filedef.h (expand_extra_prereqs): Declare a function to expand
the value of .EXTRA_PREREQS.
* src/file.c (expand_extra_prereqs): Given a struct variable lookup
of .EXTRA_PREREQS, convert it into a list of deps and for each one
make sure it has a struct file and has the new flag set.
(snap_file): A new function invoked by hash_map that will perform
per-file operations: set up second expansion, intermediate, and also
.EXTRA_PREREQS.  Manage circular dependencies by ignoring them.
(snap_deps): Defer per-file operations until the end.  Look up the
global .EXTRA_PREREQS and pass it along to snap_file for each file.
* src/implicit.c (struct patdeps): Remember the extra prereqs flag.
(pattern_search): Transfer extra prereqs flag settings into the
matched pattern rule.
* src/rule.h (snap_implicit_rules): Rename count_implicit_rules to
snap_implicit_rules since we now do more than count.
* src/rule.c (snap_implicit_rules): As we walk through all the pattern
rules, add in any global .EXTRA_PREREQS to the dep list.  Ensure we
take them into account for the max number of prereqs and name length.
* src/main.c (main): Add extra-prereqs to .FEATURES.
Call the renamed snap_implicit_rules.
* tests/scripts/variables/EXTRA_PREREQS: Add tests.
2020-01-03 02:08:59 -05:00
Paul Smith
e56243fe57 * tests/scripts/features/patternrules: Use Windows-compatible quoting 2020-01-03 02:08:59 -05:00
Paul Smith
7449abfe1b * tests/test_driver.pl: Compute full path to Perl interpreter 2020-01-03 02:08:59 -05:00
Paul Smith
53b9770b40 * tests/scripts/features/exec: Don't use $ENV in the description 2020-01-03 02:08:59 -05:00
Paul Smith
766baeef0a * src/makeint.h: Add a declaration for memrchr() 2020-01-03 02:08:59 -05:00
Paul Smith
ee204c78f2 * NEWS: Remove info about disabled /proc/loadavg usage. 2019-12-27 01:42:25 -05:00
Paul Smith
e64674b718 [SV 57022] Avoid posix_spawn which fails asynchronously
Avoid using posix_spawn implementations that fail asynchronously when
the spawned program can't be invoked: this means instead of getting
an error such as "No such file or directory" we get just "Exit 127".

Original implementation of the configure.ac macro provided by
Martin Dorey <martin.dorey@hds.com>

Original implementation of the regression tests provided by
Dmitry Goncharov <dgoncharov@users.sf.net>

* configure.ac: Test whether posix_spawn fails asynchronously.  In a
cross-compilation environment, assume that it does not.  If we detect
that it does, fall back to fork/exec.
* tests/scripts/features/exec: Add regression tests for different
shebang invocation methods.
2019-12-27 01:37:17 -05:00
Paul Smith
564fb212a7 [SV 56655] Allow pattern expansion to contain spaces
* src/dep.h: Add a new flag PARSEFS_ONEWORD
* src/read.c (parse_file_seq): If PARSEFS_ONEWORD is given, treat the
entire incoming string as a single pattern.
* src/implicit.c (pattern_search): Pass PARSEFS_ONEWORD when parsing
patterns for wildcards.
* tests/scripts/features/patternrules: Add a new test.
2019-12-26 18:39:56 -05:00
Ben Wijen
30cc10093b * src/misc.c (spin): On WINDOWS32 use Sleep() instead of sleep() 2019-12-18 09:05:40 -05:00
Ben Wijen
69c5a2128b * bootstrap.bat: Fix typo in batch file name 2019-12-18 09:05:40 -05:00
Paul Smith
577dd1ff6d * src/config.h.W32.template: [SV 57152] MinGW32 doesn't support d_type 2019-12-18 09:05:40 -05:00
Jouke Witteveen
86f2f8bcb5 [SV 54161] Fix second expansion of $* for paths
If the stem matches a path containing a directory not just a
filename, make sure the second expansion of $* in the
prerequisites matches $* in the recipe.  This requires using
$(*F) when replacing % in the first expansion to preserve the
simple filename.

* src/implicit.c (pattern_search): If lastslash is set prepend
the directory onto the stem.  Then use $(*F) when expanding %.
* tests/scripts/features/se_implicit: Add a test case
2019-12-18 09:05:17 -05:00
Jouke Witteveen
c72205b28b * src/implicit.c (pattern_search): Set lastslash correctly
If filename contained multiple slashes lastslash is wrongly set to 0.
* configure.ac: Check for the GNU memrchr() extension function.
* src/misc.c (memrchr): Supply memrchr() if not available.
2019-12-17 15:06:28 -05:00
Jouke Witteveen
057e33d6b5 * src/implicit.c (pattern-search): Remove unneeded 'dir' variable 2019-12-17 15:06:28 -05:00
Paul Smith
e4499a1fb5 * Makefile.am: Build lzip package instead of bzip2
* README.git: Mention changed requirements.
2019-12-17 15:06:28 -05:00
Paul Smith
57b043c7fb * src/job.c (load_too_high): Disable Linux /proc/loadavg for now
This new feature has a problem: if you provide a load which is
larger than the number of cores then it will always run every job.
Before we can enable it we need to at the least learn how to clamp
this value to the number of cores.  To experiment with it, set
PROC_FD_INIT to -2 in job.c to re-enable the feature.
2019-12-17 15:06:28 -05:00
Paul Smith
f389aabde6 * tests/run_make_tests.pl (set_more_defaults): Fix typo 2019-12-17 15:06:28 -05:00
Paul Smith
acbef3f612 * tests/run_make_tests.pl (subst_make_string): Force use of /
On Windows the path to the helper tool will contain '\': this will
fail if recipes are run with a POSIX shell.  Convert '\' to '/'
on Windows.  While here, escape any spaces in the path as well.
2019-12-16 16:18:58 -05:00
Paul Smith
3822f77c1d Rename jhelp.pl to thelp.pl and make it a generic test helper.
* tests/thelp.pl: Rename from tests/jhelp.pl.
(op): Use names instead of options for the operations.
(op): Add new operations for sleep, mkdir, and rm.
(op): Enhance wait to time out
* tests/run_make_tests.pl: Add a new #HELPER# replacement
(subst_make_string): Use fully-qualified path to thelp.pl
* tests/scripts/features/parallelism: Update to use thelp.pl
and the new named operations.  Use thelp.pl sleep instead of
system-specific sleep commands.
* tests/scripts/features/output-sync: Update to use thelp.pl
instead of complex shell scripts.
* Makefile.am: Distribute tests/thelp.pl instead of tests/jhelp.pl
2019-12-16 09:31:31 -05:00
Paul Eggert
1cf3932a39 Port functions/shell test to Solaris 10
* tests/scripts/functions/shell: Port exit-status calculation
to Solaris 10 with Perl 5.8.4.
2019-10-10 18:31:50 -04:00
Paul Smith
33bda40086 Release GNU make 4.2.92
* NEWS: Update the release and date
* configure.ac: Update the release number
2019-10-08 08:35:39 -04:00
Paul Smith
e666a6a021 * doc/make.text (Reading Makefiles): Rewrite to be more clear. 2019-10-06 15:48:53 -04:00
Paul Smith
5920d6d2b3 * Makefile.am (check-regression): Use PERLFLAGS when running Perl
* maintMakefile: Set PERLFLAGS to enable warnings.
* tests/run_make_tests.pl: Clean up issues pointed out by perl -w.
2019-10-05 17:48:19 -04:00
Paul Smith
2e6468c811 * tests/scripts/functions/wildcard: Skip slash tests for local glob. 2019-10-05 17:48:19 -04:00
Paul Smith
393d2a2d4a tests: Convert %CONFIG_FLAGS to get_config()
* tests/config-flags.pm.W32: Create a predefined Windows file.
* Makefile.am (test_FILES): Add it to the distribution.
* build_w32.bat: Install tests/config-flags.pm if not existing.
* tests/run_make_tests.pl (get_config): Create new function.
* tests/scripts/features/archives: Call get_config() rather than
using %CONFIG_FLAGS directly.
* tests/scripts/features/load: Ditto.
* tests/scripts/features/loadapi: Ditto.
* tests/scripts/functions/wildcard: Ditto.
2019-10-05 17:47:52 -04:00
Paul Smith
bd7d03f8cd * src/hash.c (jhash_string): Don't read past end of string.
Original patch from Dmitry Goncharov <dgoncharov@users.sf.net>.
2019-10-05 11:23:31 -04:00
Paul Smith
a4a173928f * tests/run_make_tests.pl (valid_option): Add missing File::Spec 2019-10-05 07:43:52 -04:00
Paul Smith
0e113897f7 * src/function.c (func_realpath) [AIX]: Remove trailing slashes. 2019-09-23 00:34:12 -04:00
Paul Smith
b0eab8ecb9 * tests/scripts/features/vpathplus: Fix output for big-endian systems.
Our hashing algorithm gives different ordering on LE vs BE systems.
Patch from Dmitry Goncharov <dgoncharov@users.sf.net>.
2019-09-22 17:35:51 -04:00
Florian Weimer
f84821b249 * configure.ac (HAVE_GETTIMEOFDAY): Avoid undeclared exit function.
Copyright-paperwork-exempt: yes
2019-09-22 17:32:29 -04:00
Paul Smith
99d1423059 * test/test_driver.el (_run_with_timeout): Show error message. 2019-09-22 17:03:05 -04:00
Paul Smith
7fbd58cd6b * job.c (child_error): Modify error message string.
This reverts commit 6264deece3.
Further investigation discovers that the real issue is that
GNU Emacs compile mode doesn't have a matching regex for GNU
make error messages generated when targets fail.  I submitted
a patch to GNU Emacs adding a matcher for compile mode.
2019-09-22 17:02:57 -04:00
Paul Smith
3ede0b96ac * tests: Convert from File::Spec::Functions to File::Spec.
Users report the Functions version doesn't work correctly for some
older versions of Perl.
2019-09-21 16:37:56 -04:00
Paul Smith
1d289b424a * tests/scripts/function/guile: Valgrind doesn't work with Guile. 2019-09-21 15:38:52 -04:00
Paul Smith
96285f875b * src/job.c (child_execute_job): Allocate space for argv NULL. 2019-09-21 15:38:52 -04:00
Paul Smith
bd4ce86785 [SV 56918] Compute job slots properly on failing command
Ensure we properly reduce job_slots_used if a command fails because
it doesn't exist/can't be started.

* src/job.h (struct child): Add a field jobslot to be set when using
a job slot.
* src/job.c (start_waiting_job): Remember if we are using a job slot.
(reap_children): Reduce number of job slots used by jobslot.
2019-09-21 15:38:48 -04:00
Paul Smith
e1c072aa7e * src/arscan.c (ar_scan): Restrict length for sscanf of ar_mode. 2019-09-21 15:13:32 -04:00
Paul Smith
af0074547d * tests/scripts/functions/shell: Detect correct SHELLSTATUS code. 2019-09-21 15:13:32 -04:00
Paul Smith
4a7a8278e8 * tests/run_make_test.pl: Fix support for valgrind.
Change the variable holding the make command to be a list that can
hold extra commands and options, not just a string.
2019-09-21 15:13:24 -04:00
Paul Smith
00fa3ca3a5 * tests/run_make_tests.pl (find_prog): Fix syntax error. 2019-09-21 12:39:07 -04:00
225 changed files with 16111 additions and 7738 deletions

1
.ccls
View File

@@ -13,6 +13,7 @@ clang
-Wall
-Wextra
-Werror
-Wno-address
-Wwrite-strings
-Wshadow
-Wdeclaration-after-statement

View File

@@ -1,18 +1,21 @@
(
(nil . ((bug-reference-bug-regexp . "\\(\\)\\bSV[- ]\\([0-9]+\\)")
(bug-reference-url-format . "https://savannah.gnu.org/bugs/?%s")
(ccls-initialization-options . (:index (:threads 6
:initialBlacklist ("/make-[0-9]" "tests/work/" "/\\.deps" "/\\..*cache" "/\\.git"))))
(lsp-file-watch-ignored . ("/\\.git$"
"/\\..*cache$"
;; autotools content
"/\\.deps$"
"/autom4te\\.cache$"
"/build-aux$"
;; make-specific content
"/doc/manual$"
"/tests/work$"
"/make-[0-9]"))
(ccls-initialization-options
. (:index (:threads 6
:initialBlacklist ["/make-[0-9]" "tests/work/" "/\\.deps"
"/\\..*cache" "/\\.git"])))
(lsp-file-watch-ignored-directories
. ("[/\\\\]\\.git$"
"[/\\\\]\\..*cache$"
;; autotools content
"[/\\\\]\\.deps$"
"[/\\\\]autom4te\\.cache$"
"[/\\\\]build-aux$"
;; make-specific content
"[/\\\\]doc[/\\\\]manual$"
"[/\\\\]tests[/\\\\]work$"
"[/\\\\]make-[0-9]"))
))
(c-mode . ((c-file-style . "gnu")))
)

22
.gitignore vendored
View File

@@ -11,8 +11,14 @@ GTAGS
*~
#*
.#*
*.diff
*.patch
*.orig
*.rej
# Configure artifacts
/lib/
/m4/
ABOUT-NLS
INSTALL
Makefile
@@ -28,8 +34,10 @@ config.log
config.status
configure
/mk/Posix.mk
stamp-h1
stamp-*
.dirstamp
gnulib
convert.sed
# Build artifacts
.deps/
@@ -52,19 +60,17 @@ WinRel/
GccDebug/
GccRel/
# Test artifacts
makeerror-*
test-suite.log
# Distribution artifacts
.dep_segment
.check-git-HEAD
ChangeLog
README
README.DOS
README.OS2
README.W32
build.cfg
config.ami
config.h-vms
config.h.W32
configh.dos
mkconfig.h
make-[0-9]*/
make-[0-9]*.tar.*
checkcfg.*.log

61
AUTHORS
View File

@@ -1,15 +1,16 @@
-----------------------------------
GNU make development up to version 3.75 by:
Roland McGrath <roland@gnu.org>
Development starting with GNU make 3.76 by:
GNU Make development starting with GNU Make 3.76 by:
Paul D. Smith <psmith@gnu.org>
Additional development starting with GNU make 3.81 by:
Additional development starting with GNU Make 4.3 by:
Dmitry Goncharov <dgoncharov@users.sf.net>
Additional development starting with GNU Make 3.81 by:
Boris Kolpackov <boris@kolpackov.net>
GNU Make development up to version 3.75 by:
Roland McGrath <roland@gnu.org>
GNU Make User's Manual
Written by:
@@ -22,7 +23,7 @@ GNU Make User's Manual
Paul D. Smith <psmith@gnu.org>
-----------------------------------
GNU make porting efforts:
GNU Make porting efforts:
Port to VMS by:
Klaus Kaempf <kkaempf@progis.de>
@@ -34,6 +35,9 @@ GNU make porting efforts:
Port to Amiga by:
Aaron Digulla <digulla@fh-konstanz.de>
Port to MS-Windows (native/MinGW) maintained by:
Eli Zaretskii <eliz@gnu.org>
Port to MS-DOS (DJGPP), OS/2, and MS-Windows (native/MinGW) by:
DJ Delorie <dj@delorie.com>
Rob Tulloh <rob_tulloh@tivoli.com>
@@ -42,38 +46,67 @@ GNU make porting efforts:
Andreas Beuning <andreas.buening@nexgo.de>
Earnie Boyd <earnie@uses.sf.net>
Troy Runkel <Troy.Runkel@mathworks.com>
Juan M. Guerrero <juan.guerrero@gmx.de>
-----------------------------------
Other contributors:
Luke Allardyce <lukeallardyce@gmail.com>
Aron Barath <baratharon@caesar.elte.hu>
David Boyce <dsb@boyski.com>
Kevin Buettner <kevinb@redhat.com>
Janet Carson <janet_carson@tivoli.com>
Howard Chu <hyc@highlandsun.com>
Ludovic Courtès <ludo@gnu.org>
Joe Crayne <oh.hello.joe@gmail.com>
Jeremy Devenport <jeremy.devenport@gmail.com>
Pete Dietl <petedietl@gmail.com>
Martin Dorey <martin.dorey@hds.com>
Christian Eggers <ceggers@arri.de>
Paul Eggert <eggert@twinsun.com>
Mike Frysinger <vapier@gentoo.org>
Ramon Garcia Fernandez <ramon.garcia.f@gmail.com>
Noah Goldstein <goldstein.w.n@gmail.com>
Mike Haboustak <haboustak@gmail.com>
Frank Heckenbach <f.heckenbach@fh-soft.de>
Klaus Heinz <kamar@ease.rhein-main.de>
Ben Hutchings <ben@decadent.org.uk>
Cao jin <caoj.fnst@cn.fujitsu.com>
Michael Joosten
Christian Jullien <eligis@orange.fr>
Jim Kelton <jim_kelton@tivoli.com>
Kaz Kylheku <kaz@kylheku.com>
David Lubbren <uhay@rz.uni-karlsruhe.de>
Tim Magill <tim.magill@telops.gte.com>
Markus Mauhart <qwe123@chello.at>
Greg McGary <greg@mcgary.org>
Thien-Thi Nguyen <ttn@gnuvola.org>
Thomas Riedl <thomas.riedl@siemens.com>
Han-Wen Nienhuys <hanwen@cs.uu.nl>
Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
Enrique Olaizola <enrique_olaizola16@hotmail.com>
Ola Olsson <ola1olsson@gmail.com>
Jens Rehsack <sno@netbsd.org>
Thomas Riedl <thomas.riedl@siemens.com>
Jaak Ristioja <jaak@ristioja.ee>
Christoph Schulz <develop@kristov.de>
Andreas Schwab <schwab@suse.de>
spagoveanu <spagoveanu@gmail.com>
Carl Staelin (Princeton University)
Ian Stewartson (Data Logic Limited)
Tobias Stoeckmann <tobias@stoeckmann.org>
Sergei Trofimovich <siarheit@google.com>
Marc Ullman <marc@mathworks.com>
Christof Warlich <cwarlich@gmx.de>
Florian Weimer <fweimer@redhat.com>
David A. Wheeler <dwheeler@dwheeler.com>
David Boyce <dsb@boyski.com>
Frank Heckenbach <f.heckenbach@fh-soft.de>
Kaz Kylheku <kaz@kylheku.com>
Bernhard M. Wiedemann <bwiedemann@suse.de>
Ben Wijen <ben@wijen.net>
Jouke Witteveen <j.witteveen@gmail.com>
With suggestions/comments/bug reports from a cast of ... well ...
hundreds, anyway :)
-------------------------------------------------------------------------------
Copyright (C) 1997-2019 Free Software Foundation, Inc.
Copyright (C) 1997-2022 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -86,4 +119,4 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>.
this program. If not, see <https://www.gnu.org/licenses/>.

View File

@@ -10,7 +10,7 @@
#
# make.exe -f Basic.mk
#
# Copyright (C) 2017-2019 Free Software Foundation, Inc.
# Copyright (C) 2017-2022 Free Software Foundation, Inc.
# This file is part of GNU Make.
#
# GNU Make is free software; you can redistribute it and/or modify it under
@@ -24,7 +24,7 @@
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>.
# this program. If not, see <https://www.gnu.org/licenses/>.
all:
@@ -39,7 +39,6 @@ w32_SOURCES = %w32_SOURCES%
vms_SOURCES = %vms_SOURCES%
amiga_SOURCES = %amiga_SOURCES%
posix_SOURCES = $(src)posixos.c
remote_SOURCES = $(src)remote-stub.c
OUTDIR =
@@ -88,8 +87,9 @@ COMPILE.cmd = $(CC) $(extra_CFLAGS) $(CFLAGS) $(extra_CPPFLAGS) $(CPPFLAGS) $(TA
# $(call LINK.cmd,<objectlist>)
LINK.cmd = $(LD) $(extra_LDFLAGS) $(LDFLAGS) $(TARGET_ARCH) $1 $(LDLIBS) $(LINK_OUTPUT)
# $(CHECK.cmd)
# $(CHECK.cmd) $(CHECK.args)
CHECK.cmd = cd $(SRCDIR)/tests && ./run_make_tests -make $(shell cd $(<D) && pwd)/$(<F)
CHECK.args ?=
# $(call MKDIR.cmd,<dirlist>)
MKDIR.cmd = mkdir -p $1
@@ -103,9 +103,7 @@ CP.cmd = cp $1 $2
CLEANSPACE = $(call RM.cmd,$(OBJECTS) $(PROG) $(BUILT_SOURCES))
# Load overrides for the above variables.
include $(firstword $(wildcard $(SRCDIR)/mk/$(lastword $(subst -, ,$(MAKE_HOST)).mk) $(OUTDIR)mk/Posix.mk $(SRCDIR)/mk/Posix.mk))
VERSION = %VERSION%
include $(firstword $(wildcard $(SRCDIR)/mk/$(lastword $(subst -, ,$(MAKE_HOST)).mk)))
VPATH = $(SRCDIR)
@@ -123,7 +121,7 @@ $(OBJDIRS):
$(call MKDIR.cmd,$@)
check:
$(CHECK.cmd)
$(CHECK.cmd) $(CHECK.args)
clean:
$(CLEANSPACE)

View File

@@ -1,7 +1,7 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@@ -645,7 +645,7 @@ the "copyright" line and a pointer to where the full notice is found.
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
@@ -664,11 +664,11 @@ might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
<https://www.gnu.org/philosophy/why-not-lgpl.html>.

View File

@@ -4994,4 +4994,4 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>.
this program. If not, see <https://www.gnu.org/licenses/>.

View File

@@ -1322,7 +1322,7 @@
non-standard versions of free() don't like it.
* configure.in (--enable-dmalloc): Install some support for using
dmalloc (http://www.dmalloc.com/) with make. Use --enable-dmalloc
dmalloc (https://www.dmalloc.com/) with make. Use --enable-dmalloc
with configure to enable it.
* function.c (function_table_entry): Whoops! The function.c
@@ -6632,7 +6632,7 @@ Fri Nov 1 19:34:28 1991 Roland McGrath (roland@churchy.gnu.ai.mit.edu)
See ChangeLog.1, available in the Git repository at:
http://git.savannah.gnu.org/cgit/make.git/tree/
https://git.savannah.gnu.org/cgit/make.git/tree/
for earlier changes.
@@ -6650,4 +6650,4 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>.
this program. If not, see <https://www.gnu.org/licenses/>.

View File

@@ -664,7 +664,7 @@
characters in its name, pass NULL as the first argument to
CreateProcess. This avoids weird failures due to buggy quoting by
CreateProcess. For the details, see the discussion starting at
http://lists.gnu.org/archive/html/make-w32/2013-04/msg00008.html.
https://lists.gnu.org/archive/html/make-w32/2013-04/msg00008.html.
* load.c (load_object, load_file): Accept an additional argument
DLP and return in it a pointer that can be used to unload the
@@ -706,7 +706,7 @@
(construct_command_argv_internal): Don't treat a backslash as an
escape character before whitespace, if the shell is not a Posix
shell. For the description of the problem, see
http://lists.gnu.org/archive/html/make-w32/2013-04/msg00014.html.
https://lists.gnu.org/archive/html/make-w32/2013-04/msg00014.html.
2013-05-01 Paul Smith <psmith@gnu.org>
@@ -1392,7 +1392,7 @@
2011-09-16 Paul Smith <psmith@gnu.org>
* maintMakefile (do-po-update): Apparently we have to avoid
certificate checks on the http://translationproject.org site now.
certificate checks on the https://translationproject.org site now.
2011-09-12 Paul Smith <psmith@gnu.org>
@@ -5612,7 +5612,7 @@
See ChangeLog.2, available in the Git repository at:
http://git.savannah.gnu.org/cgit/make.git/tree/
https://git.savannah.gnu.org/cgit/make.git/tree/
for earlier changes.
@@ -5630,4 +5630,4 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>.
this program. If not, see <https://www.gnu.org/licenses/>.

View File

@@ -1,6 +1,6 @@
# This is a -*-Makefile-*-, or close enough
#
# Copyright (C) 1997-2019 Free Software Foundation, Inc.
# Copyright (C) 1997-2022 Free Software Foundation, Inc.
# This file is part of GNU Make.
#
# GNU Make is free software; you can redistribute it and/or modify it under
@@ -14,9 +14,9 @@
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>.
# this program. If not, see <https://www.gnu.org/licenses/>.
AUTOMAKE_OPTIONS = dist-bzip2 silent-rules std-options subdir-objects nostdinc
AUTOMAKE_OPTIONS = dist-lzip silent-rules std-options subdir-objects nostdinc
ACLOCAL_AMFLAGS = -I m4
MAKE_HOST = @MAKE_HOST@
@@ -35,8 +35,9 @@ make_SRCS = src/ar.c src/arscan.c src/commands.c src/commands.h \
src/hash.c src/hash.h src/implicit.c src/job.c src/job.h \
src/load.c src/loadapi.c src/main.c src/makeint.h src/misc.c \
src/os.h src/output.c src/output.h src/read.c src/remake.c \
src/rule.c src/rule.h src/signame.c src/strcache.c \
src/variable.c src/variable.h src/version.c src/vpath.c
src/rule.c src/rule.h src/shuffle.h src/shuffle.c \
src/signame.c src/strcache.c src/variable.c src/variable.h \
src/version.c src/vpath.c
w32_SRCS = src/w32/pathstuff.c src/w32/w32os.c src/w32/compat/dirent.c \
src/w32/compat/posixfcn.c src/w32/include/dirent.h \
@@ -59,16 +60,28 @@ loadavg_SRCS = lib/getloadavg.c
make_SOURCES = $(make_SRCS)
EXTRA_make_SOURCES = $(amiga_SRCS) $(vms_SRCS)
make_LDADD = $(LIBOBJS) $(GUILE_LIBS) lib/libgnu.a $(GETLOADAVG_LIBS) \
if HAVE_GUILE
_GUILE_CFLAGS = $(GUILE_CFLAGS)
_GUILE_LIBS = $(GUILE_LIBS)
else
_GUILE_CFLAGS =
_GUILE_LIBS =
endif
make_LDADD = $(LIBOBJS) $(_GUILE_LIBS) lib/libgnu.a $(GETLOADAVG_LIBS) \
@LIBINTL@
localedir = $(datadir)/locale
AM_CPPFLAGS = -Isrc -I$(top_srcdir)/src -Ilib -I$(top_srcdir)/lib \
-DLIBDIR=\"$(libdir)\" -DINCLUDEDIR=\"$(includedir)\" \
-DLOCALEDIR=\"$(localedir)\"
-DLIBDIR=\"$(libdir)\" -DLOCALEDIR=\"$(localedir)\"
AM_CFLAGS = $(GUILE_CFLAGS)
# If prefix is not a standard location, look in prefix as well
if !KNOWN_PREFIX
AM_CPPFLAGS += -DINCLUDEDIR=\"$(includedir)\"
endif
AM_CFLAGS = $(_GUILE_CFLAGS)
if WINDOWSENV
make_SOURCES += $(w32_SRCS)
@@ -94,11 +107,12 @@ m4_FILES = m4/gnulib-cache.m4
test_FILES = tests/run_make_tests tests/run_make_tests.bat \
tests/run_make_tests.pl tests/test_driver.pl \
tests/config-flags.pm.in tests/config_flags_pm.com \
tests/mkshadow tests/jhelp.pl tests/guile.supp tests/README
tests/config-flags.pm.W32 \
tests/mkshadow tests/thelp.pl tests/guile.supp tests/README
# test/scripts are added via dist-hook below.
EXTRA_DIST = ChangeLog README build.sh build.cfg.in $(man_MANS) \
README.customs README.OS2 \
EXTRA_DIST = ChangeLog INSTALL README build.sh build.cfg.in $(man_MANS) \
src/mkconfig.h README.customs README.OS2 \
README.Amiga SCOPTIONS src/config.ami \
README.DOS builddos.bat src/configh.dos \
README.W32 build_w32.bat src/config.h.W32 \
@@ -123,14 +137,14 @@ src/gmk-default.h: $(top_srcdir)/src/gmk-default.scm
dist-hook:
(cd $(top_srcdir); \
sub=`find tests/scripts -follow \( -name .git -o -name .deps -o -name work -o -name .gitignore -o -name \*.orig -o -name \*.rej -o -name \*~ -o -name \*.out -o -name Makefile \) -prune -o -type f -print`; \
tar chf - $$sub) \
| (cd $(distdir); tar xfBp -)
$(AMTAR) chf - $$sub) \
| (cd $(distdir); $(AMTAR) xfBp -)
# --------------- Local CHECK Section
check-local: check-regression
@banner=" Regression PASSED: GNU Make $(VERSION) ($(MAKE_HOST)) built with $(CC) "; \
@banner=" Regression PASSED: $(PACKAGE_STRING) ($(MAKE_HOST)) built with $(CC) "; \
dashes=`echo "$$banner" | sed s/./=/g`; \
echo; \
echo "$$dashes"; \
@@ -148,7 +162,24 @@ MAKETESTFLAGS =
.PHONY: check-regression
GMK_OUTDIR = ..
testlog = test-suite.log
testresult = tests/.test-result
errorpre = makeerror-$(PACKAGE_VERSION)-$(host_triplet)
testfiles = $(testlog) $(testresult) $(errorfile)
MOSTLYCLEANFILES = $(testfiles)
errordetails = config.status config.log src/config.h $(testlog) tests/work
# Create a 4-letter random sequence
rand_value = c = "abcdefghijklmnopqrstuvwxyz0123456789"
rand_char = substr(c,int(rand()*36),1)
rand_string = $(AWK) 'BEGIN{srand(); $(rand_value); print $(rand_char) "" $(rand_char) "" $(rand_char) "" $(rand_char);}'
check-regression: tests/config-flags.pm
@rm -f $(testfiles)
@if test -f '$(top_srcdir)/tests/run_make_tests'; then \
ulimit -n 128; \
if $(PERL) -v >/dev/null 2>&1; then \
@@ -156,17 +187,26 @@ check-regression: tests/config-flags.pm
*) test -d tests || mkdir tests; \
rm -f srctests; \
if ln -s '$(top_srcdir)/tests' srctests; then \
for f in run_make_tests run_make_tests.pl test_driver.pl scripts jhelp.pl; do \
for f in run_make_tests run_make_tests.pl test_driver.pl scripts thelp.pl; do \
rm -f tests/$$f; ln -s ../srctests/$$f tests; \
done; fi ;; \
esac; \
echo "cd tests && $(PERL) ./run_make_tests.pl -srcdir $(abs_top_srcdir) -make ../make$(EXEEXT) $(MAKETESTFLAGS)"; \
cd tests && $(PERL) ./run_make_tests.pl -srcdir '$(abs_top_srcdir)' -make '../make$(EXEEXT)' $(MAKETESTFLAGS); \
echo "cd tests && $(PERL) $(PERLFLAGS) ./run_make_tests.pl -srcdir $(abs_top_srcdir) -make $(GMK_OUTDIR)/make$(EXEEXT) $(MAKETESTFLAGS)"; \
(cd tests && $(PERL) $(PERLFLAGS) ./run_make_tests.pl -srcdir '$(abs_top_srcdir)' -make '$(GMK_OUTDIR)/make$(EXEEXT)' $(MAKETESTFLAGS); echo $$? >.test-result) 2>&1 | tee $(testlog); \
er=$$(cat $(testresult)); if test "$$er" -ne 0; then \
dirnm="$(errorpre)-$$($(rand_string))"; fnm="$$dirnm.tar.gz"; \
rm -rf "$$dirnm"; mkdir "$$dirnm"; \
$(AMTAR) chf - $(errordetails) | (cd "$$dirnm"; $(AMTAR) xf -); \
$(AMTAR) chf - "$$dirnm" | eval GZIP= gzip $(GZIP_ENV) -c >"$$fnm"; \
echo "*** Testing FAILED! Details: $$fnm"; \
echo '*** Please report to <$(PACKAGE_BUGREPORT)>'; echo; \
exit $$er; \
fi; \
else \
echo "Can't find a working Perl ($(PERL)); the test suite requires Perl."; \
fi; \
else \
echo "Can't find the GNU Make test suite ($(top_srcdir)/tests)."; \
echo "Can't find the $(PACKAGE_NAME) test suite ($(top_srcdir)/tests)."; \
fi

267
NEWS
View File

@@ -1,19 +1,211 @@
GNU make NEWS -*-indented-text-*-
GNU Make NEWS -*-indented-text-*-
History of user-visible changes.
16 September 2019
31 October 2022
See the end of this file for copyrights and conditions.
All user-visible changes are more fully described in the GNU make manual,
All user-visible changes are more fully described in the GNU Make manual,
which is contained in this distribution as the file doc/make.texi.
See the README file and the GNU make manual for instructions for
See the README file and the GNU Make manual for instructions for
reporting bugs.
Version 4.2.91 (16 Sep 2019)
Version 4.4 (31 Oct 2022)
A complete list of bugs fixed in this version is available here:
http://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=108&set=custom
https://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=109&set=custom
* WARNING: Deprecation!
The following systems are deprecated in this release:
- OS/2 (EMX)
- AmigaOS
- Xenix
- Cray
In the NEXT release of GNU Make, support for these systems will be removed.
If you want to see them continue to be supported, contact <bug-make@gnu.org>.
* WARNING: Future backward-incompatibility!
In the NEXT release of GNU Make, pattern rules will implement the same
behavior change for multiple targets as explicit grouped targets, below: if
any target of the rule is needed by the build, the recipe will be invoked if
any target of the rule is missing or out of date. During testing some
makefiles were found to contain pattern rules that do not build all targets;
this can cause issues so we are delaying this change for one release cycle
to allow these makefiles to be updated. GNU Make shows a warning if it
detects this situation: "pattern recipe did not update peer target".
* WARNING: Backward-incompatibility!
GNU Make now uses temporary files in more situations than previous releases.
If your build system sets TMPDIR (or TMP or TEMP on Windows) and deletes the
contents during the build, or uses restrictive permissions, this may cause
problems. You can choose an alternative temporary directory only for use by
GNU Make by setting the new MAKE_TMPDIR environment variable before invoking
make. Note that this value CANNOT be set inside the makefile, since make
needs to find its temporary directory before the makefiles are parsed.
* WARNING: Backward-incompatibility!
Previously each target in a explicit grouped target rule was considered
individually: if the targets needed by the build were not out of date the
recipe was not run even if other targets in the group were out of date. Now
if any of the grouped targets are needed by the build, then if any of the
grouped targets are out of date the recipe is run and all targets in the
group are considered updated.
* WARNING: Backward-incompatibility!
Previously if --no-print-directory was seen anywhere in the environment or
command line it would take precedence over any --print-directory. Now, the
last setting of directory printing options seen will be used, so a command
line such as "--no-print-directory -w" _will_ show directory entry/exits.
* WARNING: Backward-incompatibility!
Previously the order in which makefiles were remade was not explicitly
stated, but it was (roughly) the inverse of the order in which they were
processed by make. In this release, the order in which makefiles are
rebuilt is the same order in which make processed them, and this is defined
to be true in the GNU Make manual.
* WARNING: Backward-incompatibility!
Previously only simple (one-letter) options were added to the MAKEFLAGS
variable that was visible while parsing makefiles. Now, all options are
available in MAKEFLAGS. If you want to check MAKEFLAGS for a one-letter
option, expanding "$(firstword -$(MAKEFLAGS))" is a reliable way to return
the set of one-letter options which can be examined via findstring, etc.
* WARNING: Backward-incompatibility!
Previously makefile variables marked as export were not exported to commands
started by the $(shell ...) function. Now, all exported variables are
exported to $(shell ...). If this leads to recursion during expansion, then
for backward-compatibility the value from the original environment is used.
To detect this change search for 'shell-export' in the .FEATURES variable.
* WARNING: New build requirement
GNU Make utilizes facilities from GNU Gnulib: Gnulib requires certain C99
features in the C compiler and so these features are required by GNU Make:
https://www.gnu.org/software/gnulib/manual/html_node/C99-features-assumed.html
The configure script should verify the compiler has these features.
* New feature: The .WAIT special target
If the .WAIT target appears between two prerequisites of a target, then
GNU Make will wait for all of the targets to the left of .WAIT in the list
to complete before starting any of the targets to the right of .WAIT.
This feature is available in some other versions of make, and it will be
required by an upcoming version of the POSIX standard for make.
Different patches were made by Alexey Neyman <alex.neyman@auriga.ru> (2005)
and Steffen Nurpmeso <steffen@sdaoden.eu> (2020) that were useful but the
result is a different implementation (closer to Alexey's idea).
* New feature: .NOTPARALLEL accepts prerequisites
If the .NOTPARALLEL special target has prerequisites then all prerequisites
of those targets will be run serially (as if .WAIT was specified between
each prerequisite).
* New feature: The .NOTINTERMEDIATE special target
.NOTINTERMEDIATE disables intermediate behavior for specific files, for all
files built using a pattern, or for the entire makefile.
Implementation provided by Dmitry Goncharov <dgoncharov@users.sf.net>
* New feature: The $(let ...) function
This function allows user-defined functions to define a set of local
variables: values can be assigned to these variables from within the
user-defined function and they will not impact global variable assignments.
Implementation provided by Jouke Witteveen <j.witteveen@gmail.com>
* New feature: The $(intcmp ...) function
This function allows conditional evaluation controlled by a numerical
comparison.
Implementation provided by Jouke Witteveen <j.witteveen@gmail.com>
* New feature: Improved support for -l / --load-average
On systems that provide /proc/loadavg (Linux), GNU Make will use it to
determine the number of runnable jobs and use this as the current load,
avoiding the need for heuristics.
Implementation provided by Sven C. Dack <sdack@gmx.com>
* New feature: The --shuffle command line option
This option reorders goals and prerequisites to simulate non-determinism
that may be seen using parallel build. Shuffle mode allows a form of "fuzz
testing" of parallel builds to verify that all prerequisites are correctly
described in the makefile.
Implementation provided by Sergei Trofimovich <siarheit@google.com>
* New feature: The --jobserver-style command line option and named pipes
A new jobserver method is used on systems where mkfifo(3) is supported.
This solves a number of obscure issues related to using the jobserver
and recursive invocations of GNU Make. This change means that sub-makes
will connect to the jobserver even if they are not marked as recursive.
It also means that other tools that want to participate in the jobserver
will need to be enhanced as described in the GNU Make manual.
You can force GNU Make to use the simple pipe-based jobserver (perhaps if
you are integrating with other tools or older versions of GNU Make) by
adding the '--jobserver-style=pipe' option to the command line of the
top-level invocation of GNU Make, or via MAKEFLAGS or GNUMAKEFLAGS.
To detect this change search for 'jobserver-fifo' in the .FEATURES variable.
* Some POSIX systems (*BSD) do not allow locks to be taken on pipes, which
caused the output sync feature to not work properly there. Also multiple
invocations of make redirecting to the same output file (e.g., /dev/null)
would cause hangs. Instead of locking stdout (which does have some useful
performance characteristics, but is not portable) create a temporary file
and lock that. Windows continues to use a mutex as before.
* GNU Make has sometimes chosen unexpected, and sub-optimal, chains of
implicit rules due to the definition of "ought to exist" in the implicit
rule search algorithm, which considered any prerequisite mentioned in the
makefile as "ought to exist". This algorithm has been modified to prefer
prerequisites mentioned explicitly in the target being built and only if
that results in no matching rule, will GNU Make consider prerequisites
mentioned in other targets as "ought to exist".
Implementation provided by Dmitry Goncharov <dgoncharov@users.sf.net>
* GNU Make was performing secondary expansion of all targets, even targets
which didn't need to be considered during the build. In this release
only targets which are considered will be secondarily expanded.
Implementation provided by Dmitry Goncharov <dgoncharov@users.sf.net>
* If the MAKEFLAGS variable is modified in a makefile, it will be re-parsed
immediately rather than after all makefiles have been read. Note that
although all options are parsed immediately, some special effects won't
appear until after all makefiles are read.
* The -I option accepts an argument "-" (e.g., "-I-") which means "reset the
list of search directories to empty". Among other things this can be used
to prevent GNU Make from searching in its default list of directories.
* New debug option "print" will show the recipe to be run, even when silent
mode is set, and new debug option "why" will show why a target is rebuilt
(which prerequisites caused the target to be considered out of date).
Implementation provided by David Boyce <David.S.Boyce@gmail.com>
* The existing --trace option is made equivalent to --debug=print,why
* Target-specific variables can now be marked "unexport".
* Exporting / unexporting target-specific variables is handled correctly, so
that the attribute of the most specific variable setting is used.
* Special targets like .POSIX are detected upon definition, ensuring that any
change in behavior takes effect immediately, before the next line is parsed.
* When the pipe-based jobserver is enabled and GNU Make decides it is invoking
a non-make sub-process and closes the jobserver pipes, it will now add a new
option to the MAKEFLAGS environment variable that disables the jobserver.
This prevents sub-processes that invoke make from accidentally using other
open file descriptors as jobserver pipes. For more information see
https://savannah.gnu.org/bugs/?57242 and https://savannah.gnu.org/bugs/?62397
* A long-standing issue with the directory cache has been resolved: changes
made as a side-effect of some other target's recipe are now noticed as
expected.
* GNU Make can now be built for MS-Windows using the Tiny C tcc compiler.
Port provided by Christian Jullien <eligis@orange.fr>
Version 4.3 (19 Jan 2020)
A complete list of bugs fixed in this version is available here:
https://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=108&set=custom
* WARNING: Backward-incompatibility!
Number signs (#) appearing inside a macro reference or function invocation
@@ -36,17 +228,24 @@ http://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=108&set
add a trailing space.
* WARNING: Backward-incompatibility!
On Linux, and any other systems that provide a /proc/loadavg with similar
syntax, the -l/--load-average option will consult that file to determine how
many CPUs are busy at that moment and compare that value to the load value
requested. This allows usage such as "-j -lN" for N-processor systems
without fear of overload during initial startup.
Patch provided by Sven C. Dack <sven.c.dack@sky.com>
Previously using the .SILENT pseudo-target in a makefile would force all
sub-makes to be invoked with the '-s' option, effectively making all
sub-makes silent as well. In this release .SILENT only affects the current
invocation of make. A side-effect of this is that .SILENT will no longer
enable the --no-print-directory option, which using -s will do.
* WARNING: Backward-incompatibility!
Contrary to the documentation, suffix rules with prerequisites were being
treated BOTH as simple targets AND as pattern rules. Behavior now matches
the documentation, and pattern rules are no longer created in this case.
* NOTE: Deprecated behavior.
Contrary to the documentation, suffix rules with prerequisites are being
treated BOTH as simple targets AND as pattern rules. Further, the
prerequisites are ignored by the pattern rules. POSIX specifies that in
order to be a suffix rule there can be no prerequisites defined. In this
release if POSIX mode is enabled then rules with prerequisites cannot be
suffix rules. If POSIX mode is not enabled then the previous behavior is
preserved (a pattern rule with no extra prerequisites is created) AND a
warning about this behavior is generated:
warning: ignoring prerequisites on suffix rule definition
The POSIX behavior will be adopted as the only behavior in a future release
of GNU make so please resolve any warnings.
* New feature: Grouped explicit targets
Pattern rules have always had the ability to generate multiple targets with
@@ -56,13 +255,21 @@ http://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=108&set
search for 'grouped-target' in the .FEATURES special variable.
Implementation contributed by Kaz Kylheku <kaz@kylheku.com>
* New feature: .EXTRA_PREREQS variable
Words in this variable are considered prerequisites of targets but they are
not added to any of the automatic variable values when expanding the
recipe. This variable can either be global (applies to all targets) or
a target-specific variable. To detect this feature search for 'extra-prereqs'
in the .FEATURES special variable.
Implementation contributed by Christof Warlich <cwarlich@gmx.de>
* Makefiles can now specify the '-j' option in their MAKEFLAGS variable and
this will cause make to enable that parallelism mode.
* GNU make will now use posix_spawn() on systems where it is available.
If you prefer to use fork/exec even on systems where posix_spawn() is
present, you can use the --disable-posix-spawn option to configure. Aron
Barath <baratharon@caesar.elte.hu> provided the basic implementation.
present, you can use the --disable-posix-spawn option to configure.
Implementation contributed by Aron Barath <baratharon@caesar.elte.hu>
* Error messages printed when invoking non-existent commands have been cleaned
up and made consistent.
@@ -100,7 +307,7 @@ Version 4.2.1 (10 Jun 2016)
A complete list of bugs fixed in this version is available here:
http://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=107&set=custom
https://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=107&set=custom
This release is a bug-fix release.
@@ -109,7 +316,7 @@ Version 4.2 (22 May 2016)
A complete list of bugs fixed in this version is available here:
http://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=106&set=custom
https://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=106&set=custom
* New variable: $(.SHELLSTATUS) is set to the exit status of the last != or
$(shell ...) function invoked in this instance of make. This will be "0" if
@@ -148,7 +355,7 @@ Version 4.1 (05 Oct 2014)
A complete list of bugs fixed in this version is available here:
http://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=105&set=custom
https://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=105&set=custom
* New variables: $(MAKE_TERMOUT) and $(MAKE_TERMERR) are set to non-empty
values if stdout or stderr, respectively, are believed to be writing to a
@@ -196,7 +403,7 @@ Version 4.0 (09 Oct 2013)
A complete list of bugs fixed in this version is available here:
http://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=101&set=custom
https://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=101&set=custom
* WARNING: Backward-incompatibility!
If .POSIX is specified, then make adheres to the POSIX backslash/newline
@@ -248,7 +455,7 @@ http://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=101&set
* New feature: "::=" simple assignment operator as defined by POSIX in 2012.
This operator has identical functionality to ":=" in GNU make, but will be
portable to any implementation of make conforming to a sufficiently new
version of POSIX (see http://austingroupbugs.net/view.php?id=330). It is
version of POSIX (see https://austingroupbugs.net/view.php?id=330). It is
not necessary to define the .POSIX target to access this operator.
* New feature: Loadable objects
@@ -300,7 +507,7 @@ Version 3.82 (28 Jul 2010)
A complete list of bugs fixed in this version is available here:
http://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=104&set=custom
https://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=104&set=custom
* Compiling GNU make now requires a conforming ISO C 1989 compiler and
standard runtime library.
@@ -465,7 +672,7 @@ Version 3.81 (01 Apr 2006)
might have caused the target to rebuild. Starting with the _next_
release of GNU make, '$?' will contain all prerequisites that caused
the target to be considered out of date.
See http://savannah.gnu.org/bugs/?16051
See https://savannah.gnu.org/bugs/?16051
* WARNING: Backward-incompatibility!
GNU make now implements a generic "second expansion" feature on the
@@ -589,7 +796,7 @@ Version 3.81 (01 Apr 2006)
A complete list of bugs fixed in this version is available here:
http://savannah.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=103
https://savannah.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=103
Version 3.80 (03 Oct 2002)
@@ -707,7 +914,7 @@ Version 3.80 (03 Oct 2002)
A complete list of bugs fixed in this version is available here:
http://savannah.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=102
https://savannah.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=102
Version 3.79.1 (23 Jun 2000)
@@ -921,7 +1128,7 @@ Version 3.77 (28 Jul 1998)
This port was done by Klaus Kämpf <kkaempf@rmi.de>
* There is first-level support available from proGIS Software, Germany.
Visit their web-site at http://www.progis.de to get information
Visit their web-site at https://www.progis.de to get information
about other vms software and forthcoming updates to gnu make.
* /bin/sh style I/O redirection is supported. You can now write lines like
@@ -1611,7 +1818,7 @@ Version 3.05
(Changes from versions 1 through 3.05 were never recorded. Sorry.)
-------------------------------------------------------------------------------
Copyright (C) 1988-2019 Free Software Foundation, Inc.
Copyright (C) 1988-2022 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -1624,4 +1831,4 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>.
this program. If not, see <https://www.gnu.org/licenses/>.

View File

@@ -1,11 +1,11 @@
Short: Port of GNU make with SAS/C (no ixemul.library required)
Short: Port of GNU Make with SAS/C (no ixemul.library required)
Author: GNU, Amiga port by Aaron "Optimizer" Digulla
Uploader: Aaron "Optimizer" Digulla (digulla@fh-konstanz.de)
Type: dev/c
This is a pure Amiga port of GNU make. It needs no extra libraries or
This is a pure Amiga port of GNU Make. It needs no extra libraries or
anything. It has the following features (in addition to any features of
GNU make):
GNU Make):
- Runs Amiga-Commands with SystemTags() (Execute)
- Can run multi-line statements
@@ -44,9 +44,9 @@ COMPILING FROM SCRATCH
To recompile, you need SAS/C 6.51.
As of GNU make 4.3, the build environment has been cleaned up and alternate
As of GNU Make 4.3, the build environment has been cleaned up and alternate
make files (including smakefiles) have been removed. If you have an existing
version of GNU make available you _should_ be able to run:
version of GNU Make available you _should_ be able to run:
make -f Basic.mk
@@ -64,7 +64,7 @@ If you plan to use recursive makes, install make resident:
-------------------------------------------------------------------------------
Copyright (C) 1995-2019 Free Software Foundation, Inc.
Copyright (C) 1995-2022 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -77,4 +77,4 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>.
this program. If not, see <https://www.gnu.org/licenses/>.

View File

@@ -79,7 +79,7 @@ To build from sources:
6. To install copy make.exe to the preferred location.
Since GNU make 4.3, support for customized platform installations
Since GNU Make 4.3, support for customized platform installations
has been removed. If you'd like to collaborate on reinstating
these capabilities, contact bug-make@gnu.org.
@@ -280,7 +280,7 @@ Bug reports:
-------------------------------------------------------------------------------
Copyright (C) 1996-2019 Free Software Foundation, Inc.
Copyright (C) 1996-2022 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -293,4 +293,4 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>.
this program. If not, see <https://www.gnu.org/licenses/>.

View File

@@ -1,6 +1,6 @@
Port of GNU make to OS/2.
Port of GNU Make to OS/2.
Features of GNU make that do not work under OS/2:
Features of GNU Make that do not work under OS/2:
- remote job execution
- dynamic load balancing
@@ -9,7 +9,7 @@ Special features of the OS/2 version:
Due to the fact that some people might want to use sh syntax in
Makefiles while others might want to use OS/2's native shell cmd.exe,
GNU make supports both shell types. The following list defines the order
GNU Make supports both shell types. The following list defines the order
that is used to determine the shell:
1. The shell specified by the environment variable MAKESHELL.
@@ -37,7 +37,7 @@ I. ***** SPECIAL OPTIONS *****
cmd or by specifying SHELL=cmd in your Makefile.
- At compile time you can set CPPFLAGS="-DNO_CHDIR2" to turn off that
GNU make prints drive letters. This is necessary if you want to run
GNU Make prints drive letters. This is necessary if you want to run
the testsuite.
@@ -49,7 +49,7 @@ A standard Unix like build environment:
release 2)
If you use pdksh it is recommended to update to 5.2.14 release 2. Older
versions may not work! You can get this version at
http://www.math.ohio-state.edu/~ilya/software/os2/pdksh-5.2.14-bin-2.zip
https://www.math.ohio-state.edu/~ilya/software/os2/pdksh-5.2.14-bin-2.zip
- GNU file utilities (make sure that install.exe from the file utilities
is in front of your PATH before X:\OS2\INSTALL\INSTALL.EXE. I recommend
also to change the filename to ginstall.exe instead of install.exe
@@ -59,7 +59,7 @@ A standard Unix like build environment:
- gawk
- grep
- sed
- GNU make 3.79.1 (special OS/2 patched version) or higher
- GNU Make 3.79.1 (special OS/2 patched version) or higher
- perl 5.005 or higher
- GNU texinfo (you can use 3.1 (gnuinfo.zip), but I recommend 4.0)
@@ -105,15 +105,15 @@ Note: You can add -DNO_CMD_DEFAULT and -DNO_CHDIR2 to CPPFLAGS.
IV. ***** NLS support *****
GNU make has NLS (National Language Support), with the following
GNU Make has NLS (National Language Support), with the following
caveats:
a) It will only work with GNU gettext, and
b) GNU gettext support is not included in the GNU make package.
b) GNU gettext support is not included in the GNU Make package.
Therefore, if you wish to enable the internationalization features of
GNU make you must install GNU gettext on your system before configuring
GNU make.
GNU Make you must install GNU gettext on your system before configuring
GNU Make.
You can choose the languages to be installed. To install support for
English, German and French only enter:
@@ -138,7 +138,7 @@ testsuite itself. -DNO_CMD_DEFAULT causes make to use /bin/sh as default
shell in every case. Normally you could simply set MAKESHELL="/bin/sh"
to do this but the testsuite ignores the environment. -DNO_CHDIR2 causes
make not to use drive letters for directory names (i.e. _chdir2() and
_getcwd2() are NOT used). The testsuite interpretes the whole output of
_getcwd2() are NOT used). The testsuite interprets the whole output of
make, especially statements like make[1]: Entering directory
'C:/somewhere/make-3.79.1/tests' where the testsuite does not expect the
drive letter. This would be interpreted as an error even if there is
@@ -160,7 +160,7 @@ from the make source tree.
-------------------------------------------------------------------------------
Copyright (C) 2003-2019 Free Software Foundation, Inc.
Copyright (C) 2003-2022 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -173,4 +173,4 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>.
this program. If not, see <https://www.gnu.org/licenses/>.

View File

@@ -1,7 +1,7 @@
Overview: -*-text-mode-*-
---------
This version of GNU make has been tested on:
This version of GNU Make has been tested on:
OpenVMS V8.3/V8.4 (Alpha) and V8.4 (Integrity) AND V7.3 (VAX)
This version of GNU Make is intended to be run from DCL to run
@@ -11,10 +11,10 @@ Overview: -*-text-mode-*-
There is an older implementation of GNU Make that was ported to GNV.
Work is now in progress to merge that port to get a single version
of GNU Make available. When that merge is done, GNU Make will auto
detect that it is running under a Posix shell and then operate as close to
detect that it is running under a POSIX shell and then operate as close to
GNU Make on Unix as possible.
The descriptions below are for running GNU make from DCL or equivalent.
The descriptions below are for running GNU Make from DCL or equivalent.
Recipe differences:
-------------------
@@ -62,15 +62,15 @@ Recipe differences:
enabled if the GNU Make is set to the older behavior.
The name GNV$MAKE_SHELL_SIM when enabled will cause GNU Make to try to
simulate a Posix shell more closely. The following behaviors occur:
simulate a POSIX shell more closely. The following behaviors occur:
* Single quotes are converted to double quotes and any double
quotes inside of them are doubled. No environment variable expansion
is simulated.
* A exit command status will be converted to a Posix Exit
* A exit command status will be converted to a POSIX Exit
where 0 is success and non-zero is failure.
* The $ character will cause environment variable expansion.
* Environent variables can be set on the command line before a command.
* Environment variables can be set on the command line before a command.
VMS generally uses logical name search lists instead of path variables
where the resolution is handled by VMS independent of the program. Which
@@ -84,11 +84,11 @@ Recipe differences:
The format for recipes are a combination of Unix macros, a subset of
simulated UNIX commands, some shell emulation, and OpenVMS commands.
This makes the resulting makefiles unique to the OpenVMS port of GNU make.
This makes the resulting makefiles unique to the OpenVMS port of GNU Make.
If you are creating a OpenVMS specific makefile from scratch, you should also
look at MMK (Madgoat Make) available at https://github.com/endlesssoftware/mmk
MMK uses full OpenVMS syntax and a persistent subprocess is used for the
MMK uses full OpenVMS syntax and a persistent sub-process is used for the
recipe lines, allowing multiple line rules.
The default makefile search order is "makefile.vms", "gnumakefile",
@@ -177,7 +177,7 @@ Recipe differences:
Since the OpenVMS utilities generally expect OpenVMS format paths, you will
usually have to use OpenVMS format paths for rules and targets.
BUG: Relative OpenVMS paths may not work in targets, especially combined
with vpaths. This is because GNU make will just concatenate the directories
with vpaths. This is because GNU Make will just concatenate the directories
as it does on Unix.
The variables $^ and $@ separate files with commas instead of spaces.
@@ -207,15 +207,15 @@ foo: $(addsuffix .3,$(subs $(comma),$(space),$^)
override OpenVMS symbols/logicals.
OpenVMS logical and symbols names show up as "environment" using the
origin function. when the "-e" option is specified, the origion function
shows them as "environment override". On Posix the test scripts indicate
origin function. when the "-e" option is specified, the origin function
shows them as "environment override". On POSIX the test scripts indicate
that they should show up just as "environment".
When GNU make reads in a symbol or logical name into the environment, it
When GNU Make reads in a symbol or logical name into the environment, it
converts any dollar signs found to double dollar signs for convenience in
using DCL symbols and logical names in recipes. When GNU make exports a
using DCL symbols and logical names in recipes. When GNU Make exports a
DCL symbol for a child process, if the first dollar sign found is followed
by second dollar sign, then all double dollar signs will be convirted to
by second dollar sign, then all double dollar signs will be converted to
single dollar signs.
The variable $(ARCH) is predefined as IA64, ALPHA or VAX respectively.
@@ -233,17 +233,17 @@ endif
Empty commands are handled correctly and don't end in a new DCL process.
The exit command needs to have OpenVMS exit codes. To pass a Posix code
The exit command needs to have OpenVMS exit codes. To pass a POSIX code
back to the make script, you need to encode it by multiplying it by 8
and then adding %x1035a002 for a failure code and %x1035a001 for a
success. Make will interpret any posix code other than 0 as a failure.
TODO: Add an option have simulate Posix exit commands in recipes.
success. Make will interpret any POSIX code other than 0 as a failure.
TODO: Add an option have simulate POSIX exit commands in recipes.
Lexical functions can be used in pipes to simulate shell file test rules.
Example:
Posix:
POSIX:
b : c ; [ -f $@ ] || echo >> $@
OpenVMS:
@@ -261,16 +261,16 @@ x = %x1035a00a
Runtime issues:
The OpenVMS C Runtime has a convention for encoding a Posix exit status into
The OpenVMS C Runtime has a convention for encoding a POSIX exit status into
to OpenVMS exit codes. These status codes will have the hex value of
0x35a000. OpenVMS exit code may also have a hex value of %x10000000 set on
them. This is a flag to tell DCL not to write out the exit code.
To convert an OpenVMS encoded Posix exit status code to the original code
To convert an OpenVMS encoded POSIX exit status code to the original code
You subtract %x35a000 and any flags from the OpenVMS code and divide it by 8.
WARNING: Backward-incompatibility!
The make program exit now returns the same encoded Posix exit code as on
The make program exit now returns the same encoded POSIX exit code as on
Unix. Previous versions returned the OpenVMS exit status code if that is what
caused the recipe to fail.
TODO: Provide a way for scripts calling make to obtain that OpenVMS status
@@ -280,11 +280,11 @@ Runtime issues:
will have the error "-E-" severity set on exit.
MAKE_TROUBLE is returned only if the option "-q" or "--question" is used and
has a Posix value of 1 and an OpenVMS status of %x1035a00a.
has a POSIX value of 1 and an OpenVMS status of %x1035a00a.
MAKE_FAILURE has a Posix value of 2 and an OpenVMS status of %x1035a012.
MAKE_FAILURE has a POSIX value of 2 and an OpenVMS status of %x1035a012.
Output from GNU make may have single quotes around some values where on
Output from GNU Make may have single quotes around some values where on
other platforms it does not. Also output that would be in double quotes
on some platforms may show up as single quotes on VMS.
@@ -294,10 +294,10 @@ Runtime issues:
There may be a "Waiting for unfinished jobs..." show up in the output.
Error messages generated by Make or Unix utilities may slightly vary from
Posix platforms. Typically the case may be different.
POSIX platforms. Typically the case may be different.
When make deletes files, on posix platforms it writes out 'rm' and the list
of files. On VMS, only the files are writen out, one per line.
When make deletes files, on POSIX platforms it writes out 'rm' and the list
of files. On VMS, only the files are written out, one per line.
TODO: VMS
There may be extra leading white space or additional or missing whitespace
@@ -323,15 +323,15 @@ Runtime issues:
to override this in your makefile, or whatever).
Unix compatibilty features:
---------------------------
Unix compatibility features:
----------------------------
If the command 'echo' is seen, any single quotes on the line will be
converted to double quotes.
The variable $(CD) is implemented as a built in Change Directory
command. This invokes the 'builtin_cd' Executing a 'set default'
recipe doesn't do the trick, since it only affects the subprocess
recipe doesn't do the trick, since it only affects the sub-process
spawned for that command.
The 'builtin_cd' is generally expected to be on its own line.
@@ -347,13 +347,13 @@ Unix compatibilty features:
Unix shell style I/O redirection is supported. You can now write lines like:
"<tab>mcr sys$disk:[]program.exe < input.txt > output.txt &> error.txt"
Posix shells have ":" as a null command. These are now handled.
POSIX shells have ":" as a null command. These are now handled.
https://savannah.gnu.org/bugs/index.php?41761
A note on appending the redirected output. A simple mechanism is
implemented to make ">>" work in action lines. In OpenVMS there is no simple
feature like ">>" to have DCL command or program output redirected and
appended to a file. GNU make for OpenVMS implements the redirection
appended to a file. GNU Make for OpenVMS implements the redirection
of ">>" by using a command procedure.
The current algorithm creates the output file if it does not exist and
@@ -367,10 +367,10 @@ Unix compatibilty features:
The older implementation wrote the output to a temporary file in
in sys$scratch: and then attempted to append the file to the existing file.
The temporary file names looked like "CMDxxxxx.". Any time the created
command procedure can not complete, this happens. Pressing Ctrl+Y to
command procedure can not complete, this happens. Pressing CTRL+Y to
abort make is one case.
In case of Ctrl+Y the associated command procedure is left in SYS$SCRATCH:.
In case of CTRL+Y the associated command procedure is left in SYS$SCRATCH:.
The command procedures will be named gnv$make_cmd*.com.
The CtrlY handler now uses $delprc to delete all children. This way also
@@ -378,12 +378,12 @@ Unix compatibilty features:
then sends SIGQUIT to itself, which is handled in common code.
Temporary command files are now deleted in the OpenVMS child termination
handler. That deletes them even if a Ctrl+C was pressed.
handler. That deletes them even if a CTRL+C was pressed.
TODO: Does the previous section about >> leaving files still apply?
The behavior of pressing Ctrl+C is not changed. It still has only an effect,
The behavior of pressing CTRL+C is not changed. It still has only an effect,
after the current action is terminated. If that doesn't happen or takes too
long, Ctrl+Y should be used instead.
long, CTRL+Y should be used instead.
Build Options:
@@ -409,7 +409,7 @@ Unimplemented functionality:
The new feature "Loadable objects" is not yet supported. If you need it,
please send a change request or submit a bug report.
The new option --output-sync (-O) is accepted but has no effect: GNU make
The new option --output-sync (-O) is accepted but has no effect: GNU Make
for OpenVMS does not support running multiple commands simultaneously.
@@ -421,8 +421,8 @@ Self test failures and todos:
Need to find a way to set the VMS features before running make as a
child.
GNU make was not currently translating the OpenVMS encoded POSIX values
returned to it back to the Posix values. I have temporarily modified the
GNU Make was not currently translating the OpenVMS encoded POSIX values
returned to it back to the POSIX values. I have temporarily modified the
Perl test script to compensate for it. This should be being handled
internally to Make.
TODO: Verify and update the Perl test script.
@@ -435,7 +435,7 @@ Self test failures and todos:
Symlink support is not present. Symlinks are supported by OpenVMS 8.3 and
later.
Error messages should be supressed with the "-" at the beginning of a line.
Error messages should be suppressed with the "-" at the beginning of a line.
On openVMS they were showing up. TODO: Is this still an issue?
The internal vmsify and unixify OpenVMS to/from UNIX are not handling logical
@@ -443,7 +443,7 @@ Self test failures and todos:
Build instructions:
------------------
-------------------
Don't use the HP C V7.2-001 compiler, which has an incompatible change
how __STDC__ is defined. This results at least in compile time warnings.
@@ -478,7 +478,7 @@ Running the tests:
https://sourceforge.net/projects/gnv/files/
As the test scripts need to create some foreign commands that persist
after the test is run, it is recommend that either you use a subprocess or
after the test is run, it is recommend that either you use a sub-process or
a dedicated login to run the tests.
To get detailed information for running the tests:
@@ -499,12 +499,12 @@ Running the tests:
$ perl run_make_tests.pl
Acknowlegements:
Acknowledgments:
----------------
See NEWS. for details of past changes.
These are the currently known contributers to this port.
These are the currently known contributors to this port.
Hartmut Becker
John Malmberg

View File

@@ -1,4 +1,4 @@
This version of GNU make has been tested on:
This version of GNU Make has been tested on:
Microsoft Windows 2000/XP/2003/Vista/7/8/10
It has also been used on Windows 95/98/NT, and on OS/2.
@@ -15,7 +15,7 @@ which compilation and link switches and libraries need to be mentioned
on the compiler command lines to correctly link with Guile. A Windows
port of pkg-config can be found on ezwinports site:
http://sourceforge.net/projects/ezwinports/
https://sourceforge.net/projects/ezwinports/
The libraries on which Guile depends can vary depending on your
version and build of Guile. At the very least, the Boehm's GC library
@@ -25,7 +25,7 @@ also provide you with these dependencies or a URL where to download
them. A precompiled 32-bit Windows build of Guile is available from
the ezwinports site mentioned above.
The Windows port of GNU make is maintained jointly by various people.
The Windows port of GNU Make is maintained jointly by various people.
It was originally made by Rob Tulloh.
It is currently maintained by Eli Zaretskii.
@@ -33,12 +33,14 @@ It is currently maintained by Eli Zaretskii.
Do this first, regardless of the build method you choose:
---------------------------------------------------------
1. Edit config.h.W32 to your liking (especially the few shell-related
defines near the end, or HAVE_CASE_INSENSITIVE_FS which corresponds
to './configure --enable-case-insensitive-file-system'). (We don't
recommend to define HAVE_CASE_INSENSITIVE_FS, but you may wish to
consider that if you have a lot of files whose names are in upper
case, while Makefile rules are written for lower-case versions.)
1. If you have special requirements, edit config.h.W32 to your liking
(especially the shell-related defines, or HAVE_CASE_INSENSITIVE_FS which
corresponds to './configure --enable-case-insensitive-file-system'). We
don't recommend to define HAVE_CASE_INSENSITIVE_FS, but you may wish to
consider that if you have a lot of files whose names are in upper case,
while Makefile rules are written for lower-case versions.
If you don't have special requirements no changes are needed.
Building with (MinGW-)GCC using build_w32.bat
@@ -51,7 +53,7 @@ Building with (MinGW-)GCC using build_w32.bat
This produces gnumake.exe in the GccRel directory.
If you want a version of GNU make built with debugging enabled,
If you want a version of GNU Make built with debugging enabled,
add the --debug option. Output goes into the GccDebug directory.
The batch file will probe for Guile installation, and will build
@@ -73,21 +75,21 @@ Building with (MSVC++-)cl using build_w32.bat
file will probe your system and choose the newest MSVC version it can
find.
If you want a 32bit version of GNU make, add the --x86 option.
If you want a 32bit version of GNU Make, add the --x86 option.
If you want a Debug build of GNU make, add the --debug option. Output
If you want a Debug build of GNU Make, add the --debug option. Output
will go into the .\WinDebug directory.
The batch file will probe for Guile installation, and will build
gnumake.exe with Guile if it finds it. If Guile is installed,
but you prefer to build GNU make without Guile support, add the
but you prefer to build GNU Make without Guile support, add the
--without-guile option.
Building with (MinGW-)GCC using GNU make
Building with (MinGW-)GCC using GNU Make
----------------------------------------
2. If you already have a version of GNU make available you can use it
2. If you already have a version of GNU Make available you can use it
to build this version. Open a W32 command prompt for your installed
(MinGW-)GCC, setup a correct PATH and other environment variables
for it, then execute ...
@@ -95,7 +97,7 @@ Building with (MinGW-)GCC using GNU make
make -f Basic.mk TOOLCHAIN=gcc
This produces GccRel\gnumake.exe.
If you want a version of GNU make built with debugging enabled,
If you want a version of GNU Make built with debugging enabled,
add the TARGET_TYPE=debug option:
make -f Basic.mk TOOLCHAIN=gcc TARGET_TYPE=debug
@@ -104,10 +106,10 @@ Building with (MinGW-)GCC using GNU make
if you want to build with Guile support.
Building with (MSVC++-)cl using GNU make
Building with (MSVC++-)cl using GNU Make
----------------------------------------
2. If you already have a version of GNU make available you can use it
2. If you already have a version of GNU Make available you can use it
to build this version. Open a W32 command prompt for your installed
(MSVC++-)cl, setup a correct PATH and other environment variables
for it (usually via executing vcvars32.bat or vsvars32.bat from the
@@ -117,7 +119,7 @@ Building with (MSVC++-)cl using GNU make
make -f Basic.mk
This produces an optimized WinRel/gnumake.exe.
If you want a version of GNU make built with debugging enabled,
If you want a version of GNU Make built with debugging enabled,
add the TARGET_TYPE=debug option:
make -f Basic.mk TARGET_TYPE=debug
@@ -132,7 +134,7 @@ Running the test suite
3. You will need an installation of Perl. Be sure to use a relatively
modern version: older versions will sometimes throw spurious errors.
To run the suite after building using GNU make, use:
To run the suite after building using GNU Make, use:
make -f Basic.mk check
@@ -156,7 +158,7 @@ Running the test suite
-- Notes/Caveats --
-------------------
GNU make on Windows 32-bit platforms:
GNU Make on Windows 32-bit platforms:
This version of make is ported natively to Windows32 platforms
(Windows NT 3.51, Windows NT 4.0, Windows 2000, Windows XP,
@@ -166,11 +168,11 @@ GNU make on Windows 32-bit platforms:
officially are the MinGW port of GNU GCC, and the various
versions of the Microsoft C compiler.
Do not confuse this port of GNU make with other Windows32 projects
which provide a GNU make binary. These are separate projects
Do not confuse this port of GNU Make with other Windows32 projects
which provide a GNU Make binary. These are separate projects
and are not connected to this port effort.
GNU make and sh.exe:
GNU Make and sh.exe:
This port prefers if you have a working sh.exe somewhere on
your system. If you don't have sh.exe, the port falls back to
@@ -180,12 +182,12 @@ GNU make and sh.exe:
There are very few true ports of Bourne shell for NT right now.
There is a version of GNU bash available from Cygnus "Cygwin"
porting effort (http://www.cygwin.com/).
porting effort (https://www.cygwin.com/).
Other possibilities are the MKS version of sh.exe, or building
your own with a package like NutCracker (DataFocus) or Portage
(Consensys). Also MinGW includes sh (http://mingw.org/).
(Consensys). Also MinGW includes sh.
GNU make and brain-dead shells (BATCH_MODE_ONLY_SHELL):
GNU Make and brain-dead shells (BATCH_MODE_ONLY_SHELL):
Some versions of Bourne shell do not behave well when invoked
as 'sh -c' from CreateProcess(). The main problem is they seem
@@ -211,21 +213,21 @@ Support for parallel builds
Parallel builds (-jN) are supported in this port. The number of
concurrent processes has a hard limit of 4095.
GNU make and Cygnus GNU Windows32 tools:
GNU Make and Cygnus GNU Windows32 tools:
Good news! Make now has native support for Cygwin sh. To enable,
define the HAVE_CYGWIN_SHELL in config.h and rebuild make
from scratch. This version of make tested with B20.1 of Cygwin.
Do not define BATCH_MODE_ONLY_SHELL if you use HAVE_CYGWIN_SHELL.
GNU make and the MKS shell:
GNU Make and the MKS shell:
There is now semi-official support for the MKS shell. To turn this
support on, define HAVE_MKS_SHELL in the config.h.W32 before you
build make. Do not define BATCH_MODE_ONLY_SHELL if you turn
on HAVE_MKS_SHELL.
GNU make handling of drive letters in pathnames (PATH, vpath, VPATH):
GNU Make handling of drive letters in pathnames (PATH, vpath, VPATH):
There is a caveat that should be noted with respect to handling
single character pathnames on Windows systems. When colon is
@@ -291,7 +293,7 @@ Pathnames and Case insensitivity:
the file with other case permutations will succeed (i.e. opening a
file named "target" or "TARGET" will open the file "Target").
By default, GNU make retains its case sensitivity when comparing
By default, GNU Make retains its case sensitivity when comparing
target names and existing files or directories. It can be
configured, however, into a case preserving and case insensitive
mode by adding a define for HAVE_CASE_INSENSITIVE_FS to
@@ -309,10 +311,10 @@ Pathnames and Case insensitivity:
SUBDIR/DepTarget: SubDir/TARGET
cp $^ $@
Reliance on this behavior also eliminates the ability of GNU make
Reliance on this behavior also eliminates the ability of GNU Make
to use case in comparison of matching rules. For example, it is
not possible to set up a C++ rule using %.C that is different
than a C rule using %.c. GNU make will consider these to be the
than a C rule using %.c. GNU Make will consider these to be the
same rule and will issue a warning.
SAMBA/NTFS/VFAT:
@@ -342,10 +344,10 @@ FAT:
Bug reports:
Please submit bugs via the normal bug reporting mechanism which
is described in the GNU make manual and the base README.
is described in the GNU Make manual and the base README.
-------------------------------------------------------------------------------
Copyright (C) 1996-2019 Free Software Foundation, Inc.
Copyright (C) 1996-2022 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -358,4 +360,4 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>.
this program. If not, see <https://www.gnu.org/licenses/>.

View File

@@ -1,6 +1,6 @@
-*-indented-text-*-
GNU make can utilize the Customs library, distributed with Pmake, to
GNU Make can utilize the Customs library, distributed with Pmake, to
provide builds distributed across multiple hosts.
In order to utilize this capability, you must first download and build
@@ -21,11 +21,11 @@ please see the pmake and Customs documentation for details. The best
place to look for instructions is in the pmake-2.1.33/INSTALL file.
Note that the 2.1.33 Pmake distribution comes with a set of patches to
GNU make, distributed in the pmake-2.1.33/etc/gnumake/ directory. These
patches are based on GNU make 3.75 (there are patches for earlier
versions of GNU make, also). The parts of this patchfile which relate
GNU Make, distributed in the pmake-2.1.33/etc/gnumake/ directory. These
patches are based on GNU Make 3.75 (there are patches for earlier
versions of GNU Make, also). The parts of this patchfile which relate
directly to Customs support have already been incorporated into this
version of GNU make, so you should _NOT_ apply the patch file.
version of GNU Make, so you should _NOT_ apply the patch file.
However, there are a few non-Customs specific (as far as I could tell)
changes here which are not incorporated (for example, the modification
@@ -42,14 +42,14 @@ install' there directly).
BUILDING GNU MAKE
-----------------
Once you've installed Customs, you can build GNU make to use it. When
configuring GNU make, merely use the '--with-customs=DIR' option.
Once you've installed Customs, you can build GNU Make to use it. When
configuring GNU Make, merely use the '--with-customs=DIR' option.
Provide the directory containing the 'lib' and 'include/customs'
subdirectories as DIR. For example, if you installed the customs
library in /usr/local/lib and the headers in /usr/local/include/customs,
then you'd pass '--with-customs=/usr/local' as an option to configure.
Run make (or use build.sh) normally to build GNU make as described in
Run make (or use build.sh) normally to build GNU Make as described in
the INSTALL file.
See the documentation for Customs for information on starting and
@@ -83,7 +83,7 @@ PROBLEMS
SunOS 4.1.x:
The customs/sprite.h header file #includes the <malloc.h> header
files; this conflicts with GNU make's configuration so you'll get a
files; this conflicts with GNU Make's configuration so you'll get a
compile error if you use GCC (or any other ANSI-capable C compiler).
I commented out the #include in sprite.h:107:
@@ -96,7 +96,7 @@ SunOS 4.1.x:
-------------------------------------------------------------------------------
Copyright (C) 1998-2019 Free Software Foundation, Inc.
Copyright (C) 1998-2022 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -109,4 +109,4 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>.
this program. If not, see <https://www.gnu.org/licenses/>.

View File

@@ -1,7 +1,7 @@
-*-text-*-
-------------------------------------------------------------------------------
Copyright (C) 2002-2019 Free Software Foundation, Inc.
Copyright (C) 2002-2022 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -14,7 +14,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>.
this program. If not, see <https://www.gnu.org/licenses/>.
-------------------------------------------------------------------------------
Obtaining Git Code
@@ -23,7 +23,7 @@ Obtaining Git Code
This seems redundant, since if you're reading this you most likely have
already performed this step; however, for completeness, you can obtain the GNU
make source code via Git from the FSF's Savannah project
<http://savannah.gnu.org/projects/make/>:
<https://savannah.gnu.org/projects/make/>:
$ git clone git://git.savannah.gnu.org/make.git
@@ -31,10 +31,13 @@ make source code via Git from the FSF's Savannah project
Changes using Git
-----------------
For non-developers, you can continue to provide patches as before, or if you
make a public repository I can pull from that if you prefer.
If you do not have push privileges to the GNU Make Git repository, see the
README file section "Submitting Patches" for information.
Starting with GNU make 4.0 we no longer keep a separate ChangeLog file in
If you have push privileges to the GNU Make Git repository keep this
information in mind:
Starting with GNU Make 4.0 we no longer keep a separate ChangeLog file in
source control. We use the Gnulib git-to-changelog conversion script to
convert the Git comments into ChangeLog-style entries for release. As a
result, please format your Git comments carefully so they will look clean
@@ -43,61 +46,69 @@ added before it so be sure your comment lines are not longer than 72
characters; prefer 70 or less. Please use standard ChangeLog formats for
your commit messages (sans the leading TAB of course).
Rule #1: Don't rewrite pushed history (don't use "git push --force").
Rule #1: Don't rewrite pushed history on master (no "git push --force").
Rule #2: Feel free to rewrite pushed history on personal branches.
Rule #3: Squash-merge or rebase + merge --ff-only, rather than merging from
personal branches into master.
Typical simple workflow might be:
* Edit files
* Edit files / make / make check
* Use "git status" and "git diff" to verify your changes
* Use "git add" to stage the changes you want to make
* Use "git commit" to commit the staged changes to your local repository
* Use "git pull" to accept & merge new changes from the Savannah repository
* Use "git push" to push your commits back to the Savannah repository
* Use "git pull -r" to accept new changes from the upstream repository
* Use "git push" to push your commits back to the upstream repository
For Emacs users, there are many options for Git integration but I strongly
recommend the Magit package: http://www.emacswiki.org/emacs/Magit
It makes the workflow much clearer, and has advanced features such as
constructing multiple commits from various files and even from different
diff chunks in the same file. There is a video available which helps a lot.
recommend Magit: https://magit.vc/ It makes the workflow much clearer, and
has advanced features such as constructing multiple commits from various files
and even from different diff chunks in the same file. There is a video
available which helps a lot.
Coding Standards
----------------
GNU make code adheres to the GNU Coding Standards. Please use only spaces and
GNU Make code adheres to the GNU Coding Standards. Please use only spaces and
no TAB characters in source code.
Additionally, GNU make is a foundational bootstrap package for the GNU
project; as such it is very conservative about language features it expects.
It should build with any C compiler conforming to the ANSI C89 / ISO C90
standard.
Additionally, GNU Make is a foundational bootstrap package for the GNU
project; as such it is conservative about language features it expects.
However, GNU Make does rely on the Gnulib portability library, and Gnulib
currently requires a ISO C99 compiler. So features in ISO C99 can be
assumed.
Building From Git for POSIX
---------------------------
To build GNU make from Git on POSIX systems such as GNU/Linux, you will
To build GNU Make from Git on POSIX systems such as GNU/Linux, you will
need to install the following extra software:
* autoconf
* autoconf >= 2.69
* automake >= 1.16.1
* gettext
* autopoint
* pkg-config
* texinfo (for makeinfo)
* GCC (Clang's GCC emulation is not sufficient)
* GNU make (POSIX make is not sufficient)
* GCC
* GNU Make (POSIX make is not sufficient)
And any tools that those utilities require (GNU m4, Perl, etc.)
And any tools that those utilities require (GNU m4, etc.)
GNU make requires gnulib to provide some facilities. If you want to maintain
To run the tests you must install Perl.
To build a release you'll need to install lzip.
GNU Make requires Gnulib to provide some facilities. If you want to maintain
a local installation of gnulib you can set GNULIB_SRCDIR to point to it.
Otherwise, ./bootstrap will obtain a clone for you.
Unfortunately due to issues with gnulib's getloadavg, you must have automake
1.16.1 or above. This version may not yet be available through GNU/Linux
package managers. If you need to install from source be sure to set
ACLOCAL_PATH to point to the pkg-config location (e.g., /usr/share/aclocal).
Due to issues with gnulib's getloadavg, you must have automake 1.16.1 or
above. This version may not yet be available through GNU/Linux package
managers. If you need to install from source be sure to set ACLOCAL_PATH to
point to the pkg-config location (e.g., /usr/share/aclocal).
If you want to build from Git with a non-GCC compiler, add "MAKE_CFLAGS=" to
your make command line (or at least remove any flags your compiler does not
@@ -112,6 +123,16 @@ After checking out the code, you will need to run the bootstrap script:
$ ./bootstrap
Alternatively you can just pull content from remote locations with:
$ ./autopull.sh
And/or just re-generate auto-generatable files with:
$ ./autogen.sh
(Running ./bootstrap does both in one step.)
At this point you have successfully brought your Git copy of the GNU
make source directory up to the point where it can be treated
more-or-less like the official package you would get from ftp.gnu.org.
@@ -120,9 +141,9 @@ That is, you can just run:
$ ./configure
$ make check
to build and test GNU make.
to build and test GNU Make.
NOTE! This method builds GNU make in "maintainer mode". Make programs built
NOTE! This method builds GNU Make in "maintainer mode". Make programs built
in this mode it will be slower, possibly MUCH slower: there are various
sanity checks enabled. Further this mode assumes a modern GCC, GNU
libc, and well-formed system headers and enables a high level of
@@ -142,40 +163,76 @@ NOTE! This method builds GNU make in "maintainer mode". Make programs built
Building From Git for Windows
-----------------------------
If you have a UNIX emulation like CYGWIN you can opt to run the general
build procedure above; it will work. Consult README.W32.template for
information on options you might want to use when running ./configure.
If you have a UNIX emulation like CYGWIN you can opt to run the general build
procedure above; it will work. Consult README.W32 for information on options
you might want to use when running ./configure.
If you can't or don't want to do that, then first run the .\bootstrap.bat
script to prime your Git workspace:
script to "prime" your Git workspace:
> .\bootstrap.bat
Next, rename the file README.W32.template to README.W32 and follow those
instructions.
Next, follow the instructions in the README.W32 file.
Note, neither of these methods are tested regularly by the GNU Make
maintainers. Building for Windows from a distribution tarball IS tested
regularly.
NOTE! "Maintainer mode" (see above) IS ENABLED when building from Git using
the build_w32.bat file.
Debugging and Testing
---------------------
These instructions have been tested on GNU systems. I have no idea if they
work on non-GNU systems (Windows, MacOS, etc.)
* Alternate Configurations:
The maintMakefile has a rule for running configure with various different
options, with and without packages. Run:
make check-alt-config
* Valgrind:
You can run all tests under valgrind by passing the -memcheck option:
(cd tests && ./run_make_tests -make ../make -memcheck)
Note, this is slow! Also some tests will fail because of invoking valgrind.
* ASAN:
You can build with ASAN and run tests, like this:
make clean
make -j8 CFLAGS='-ggdb3 -fsanitize=address' LDFLAGS='-ggdb3 -fsanitize=address'
make check
Note that ASAN is reporting many more errors than valgrind. I don't know
which one is wrong: I haven't looked at them closely.
Creating a Package
------------------
Once you have performed the above steps (including the configuration and
build) you can create a GNU make package. This is very simple, just
build) you can create a GNU Make package. This is very simple, just
run:
$ make dist-gzip
and, if you like:
$ make dist-bzip2
$ make dist-lzip
Even better, you should run this:
$ make distcheck
Which will build both .gz and .bz2 package files, then unpack them into
a temporary location, try to build them, and repack them, verifying that
everything works, you get the same results, _and_ no extraneous files
are left over after the "distclean" rule.
Which will build both .gz and .lz package files, then unpack one into a
temporary location, try to build it and repack it, then verifying that
everything works, you get the same results, _and_ no extraneous files are
left over after the "distclean" rule.
This package can be unpacked and built to give a "normal" (non-maintainer
mode) result.
@@ -196,33 +253,117 @@ consistent (that's why we don't finalize the Git tag, etc. until the end).
"Fixed Release" ID number.
* Run "make distcheck" to be sure it all works.
* Run "make check-alt-config" to be sure alternative configurations work
* Run "make update-makeweb" to get a copy of the GNU make web pages
* Run "make update-gnuweb" to get a copy of the GNU website boilerplate pages
* Update the web page boilerplate if necessary:
../gnu-www/www/server/standards/patch-from-parent ../make-web/make.html \
../gnu-www/www/server/standards/boilerplate.html
* Run "make gendocs" (requires gnulib) to generate the manual files for
the GNU make web pages.
* Follow the directions from gendocs for the web page repository
* run "make tag-release" to create a Git tag for the release
* Push everything:
git push --tags origin master
Manage the Savannah project for GNU make:
The safest thing is to create an entirely new repository and build the final
package from there:
>>> This is only for real releases, not release candidate builds <<<
git clone git://git.savannah.gnu.org/make.git make-release
cd make-release
If you don't want to create a new repository then run "git clean -fdx".
Then:
./bootstrap.sh
./configure
make distcheck
Perform test builds on whichever systems you have access to.
Use a previous announcement as a template to create an announcement in a text
file then sign it with GPG:
gpg --clearsign <announcement.txt>
Or, use your mail client's PGP/GPG signing capabilities.
NOTE! In order to publish a package on the FSF FTP site you need to have my
GPG private key, and my passphrase to unlock it.
Depending on your distribution (whether GnuPG is integrated with your
keyring etc.) the upload operation will either pop up a window asking
for the GPG key passphrase one time, or else it will use the CLI to ask
for the GPG passphrase _THREE_ times. Sigh.
Publishing a Release Candidate
------------------------------
Usually I publish one or two release candidates for people to test before
making an official release. Release candidates use a GNU numbering scheme,
which add a ".9x" release number to the PREVIOUS major release. So the first
release candidate for GNU Make 4.4 would be GNU Make 4.3.90, the second
release candidate would be 4.3.91, etc.
Upload a release candidate using:
make upload-alpha
Announce a release candidate to these mailing lists:
To: bug-make@gnu.org
BCC: help-make@gnu.org, make-w32@gnu.org, make-alpha@gnu.org
You will have to approve the BCC's on the mailing list admin sites. Send
separate copies to (don't use CC as replies will go to these lists):
* coordinator@translationproject.org
* platform-testers@gnu.org
Publishing a Release
--------------------
When publishing a final release there are extra steps that need to be taken:
* Run "make update-makeweb" to get a copy of the GNU Make web pages
* Run "make update-gnuweb" to get a copy of the GNU website boilerplate pages
* Update the web page boilerplate if necessary:
( cd ~/src/make/make-web \
&& ~/src/gnu-www/www/server/standards/patch-from-parent \
make.html \
~/src/gnu-www/www/server/standards/boilerplate.html )
* Run "make gendocs" (requires gnulib) to generate the manual files for
the GNU Make web pages.
* Follow the directions from gendocs for the web page repository
Manage the Savannah project for GNU Make:
* In Savannah modify the "Value", "Rank", and "Description" values for the
current "SCM" entry in both "Component Version" and "Fix Release" fields
to refer to the new release. The "Rank" field should be 10 less than the
previous release so it orders properly.
* In Savannah create a new entry for the "Component Version" and "Fix
Release" fields:
* In Savannah create a new entry for the "Component Version" field:
- Value: SCM
- Rank: 20
- Descr: Issues found in code retrieved from Source Code Management (Git), rather than a distributed version. Please include the SHA you are working with.
- Descr: Fixed in Source Code Management (Git). The fix will be included in the next release of GNU make.
* In Savannah create a new entry for the "Fix Release" field:
- Value: SCM
- Rank: 20
- Descr: Fixed in Source Code Management (Git). The fix will be included in the next release of GNU Make.
Upload a release using:
make upload-ftp
Announce a release to these mailing lists:
To: info-gnu@gnu.org, bug-make@gnu.org
BCC: help-make@gnu.org, make-w32@gnu.org, make-alpha@gnu.org
You will have to approve the BCC's on the mailing list admin sites. Send
separate copies to (don't use CC as replies will go to these lists):
* coordinator@translationproject.org
* platform-testers@gnu.org
Announce on Savannah:
* Add a news item to the Savannah project site.
Start the next release:
@@ -231,71 +372,11 @@ Start the next release:
* Update the Savannah URL for the bugs fixed in the NEWS section.
Publishing a Package
--------------------
In order to publish a package on the FSF FTP site, either the release
site ftp://ftp.gnu.org, or the prerelease site ftp://alpha.gnu.org, you
first need to have my GPG private key and my passphrase to unlock it.
And, you can't have them! So there! But, just so I remember here's
what to do:
Make sure the "Steps to Release" are complete and committed and tagged.
git clone git://git.savannah.gnu.org/make.git make-release
cd make-release
<run the commands above to build the release>
make upload-alpha # for alpha.gnu.org (pre-releases)
-OR-
make upload-ftp # for ftp.gnu.org (official releases)
Depending on your distribution (whether GnuPG is integrated with your keyring
etc.) it will either pop up a window asking for your GPG key passphrase one
time, or else it will use the CLI to ask for the GPG passphrase _THREE_ times.
Sigh.
For both final releases and pre-releases, send an email with the URL of
the package to the GNU translation robot to allow the translators to
work on it:
<coordinator@translationproject.org>
Where to Announce
-----------------
Create the announcement in a text file, using 'git shortlog',
then sign it with GPG:
gpg --clearsign <announcement.txt>
Or, use your mail client's PGP/GPG signing capabilities.
Announce the release:
* For release candidate builds:
To: bug-make@gnu.org
CC: coordinator@translationproject.org
BCC: help-make@gnu.org, make-w32@gnu.org, make-alpha@gnu.org
* For release builds
To: info-gnu@gnu.org, bug-make@gnu.org
CC: coordinator@translationproject.org
BCC: help-make@gnu.org, make-w32@gnu.org, make-alpha@gnu.org
* Add a news item to the Savannah project site.
* Add an update to freecode.com (nee freshmeat.net)
Appendix A - For The Brave
--------------------------
For those of you who trust me implicitly, or are just brave (or
foolhardy), here is a canned sequence of commands to build a GNU make
foolhardy), here is a canned sequence of commands to build a GNU Make
distribution package from a virgin Git source checkout (assuming all the
prerequisites are available of course).
@@ -306,6 +387,6 @@ For a debugging version:
./bootstrap && ./configure CFLAGS=-g && make check
For a release version
For an optimized version
./bootstrap && ./configure && make check

View File

@@ -1,4 +1,4 @@
This directory contains the %VERSION% release of GNU Make.
This directory contains the @PACKAGE_VERSION@ release of @PACKAGE_NAME@.
See the file NEWS for the user-visible changes from previous releases.
In addition, there have been bugs fixed.
@@ -6,7 +6,7 @@ In addition, there have been bugs fixed.
Please check the system-specific notes below for any caveats related to your
operating system.
If you are trying to build GNU make from a Git clone rather than a downloaded
If you are trying to build GNU Make from a Git clone rather than a downloaded
source distribution, see the README.git file for instructions.
For source distribution building and installation instructions, see the file
@@ -15,12 +15,12 @@ INSTALL.
If you need to build GNU Make and have no other 'make' program to use, you can
use the shell script 'build.sh' instead. To do this, first run 'configure' as
described in INSTALL. Then, instead of typing 'make' to build the program,
type 'sh build.sh'. This should compile the program in the current directory.
Then you will have a Make program that you can use for './make install', or
type 'sh build.sh'. This will compile the program in the current directory.
Then you will have a 'make' program that you can use for './make install', or
whatever else.
Some systems' Make programs cannot process the Makefile for GNU Make. If you
get errors from your system's Make when building GNU Make, try using
Some systems' 'make' programs cannot process the Makefile for GNU Make.
If you get errors from your system's 'make' when building GNU Make, try using
'build.sh' instead.
@@ -34,20 +34,20 @@ Downloading
GNU Make can be obtained in many different ways. See a description here:
http://www.gnu.org/software/software.html
https://www.gnu.org/software/software.html
Documentation
-------------
GNU make is fully documented in the GNU Make manual, which is contained
in this distribution as the file make.texinfo. You can also find
on-line and preformatted (PostScript and DVI) versions at the FSF's web
site. There is information there about ordering hardcopy documentation.
GNU Make is fully documented in the GNU Make manual, which is contained in
this distribution as the file make.texi. You can also find on-line and
preformatted (PostScript and DVI) versions at the FSF's web site. There is
information there about ordering hardcopy documentation.
http://www.gnu.org/
http://www.gnu.org/doc/doc.html
http://www.gnu.org/manual/manual.html
https://www.gnu.org/
https://www.gnu.org/doc/doc.html
https://www.gnu.org/manual/manual.html
Development
@@ -56,49 +56,82 @@ Development
GNU Make development is hosted by Savannah, the FSF's online development
management tool. Savannah is here:
http://savannah.gnu.org
https://savannah.gnu.org
And the GNU Make development page is here:
http://savannah.gnu.org/projects/make/
https://savannah.gnu.org/projects/make/
You can find most information concerning the development of GNU Make at
this site.
Regression Tests
----------------
GNU Make contains a suite of regression tests. To run them use "make check"
after building GNU Make. If they fail a tar package will be created
containing useful information, which can be emailed (as an attachment) to
the <bug-make@gnu.org> mailing list.
Please note that since these tests rely on known-good-output comparisons,
they can show spurious failures on some systems (particularly non-POSIX systems
such as Windows).
Bug Reporting
-------------
You can send GNU make bug reports to <bug-make@gnu.org>. Please see the
section of the GNU make manual entitled 'Problems and Bugs' for
information on submitting useful and complete bug reports.
If you need help using GNU Make, try asking on <help-make@gnu.org>.
If you found a bug, you can send a bug reports to <bug-make@gnu.org>.
Please see the section of the GNU Make manual entitled 'Problems and Bugs'
for information on submitting useful and complete bug reports.
You do not need to subscribe to these lists first.
You can also use the online bug tracking system in the Savannah GNU Make
project to submit new problem reports or search for existing ones:
http://savannah.gnu.org/bugs/?group=make
https://savannah.gnu.org/bugs/?group=make
If you need help using GNU make, try these forums:
We prefer to use the bug tracking system ONLY for bugs or enhancements,
not for help requests: please use the mailing lists to get help.
help-make@gnu.org
help-utils@gnu.org
news:gnu.utils.help
news:gnu.utils.bug
Submitting Patches
------------------
If you'd like to propose a change to GNU Make, you can provide a patch with
your changes. If you are making your changes in a Git workspace you can run
"git format-patch" to create a patch file. If not, you can use the diff(1)
utility to create a patch file; please use "diff -u".
Once you have a patch you can submit it in any of these ways:
* Create a bug on Savannah and add the patch as an attachment:
https://savannah.gnu.org/bugs/?group=make&func=additem
* Send the patch via email to <bug-make@gnu.org>: be sure to add it as an
attachment to avoid interference by email processors.
All non-trivial changes require FSF copyright paperwork to be completed
before they can be accepted. Contact <bug-make@gnu.org> for help.
Git Access
----------
The GNU make source repository is available via Git from the GNU Savannah Git
The GNU Make source repository is available via Git from the GNU Savannah Git
server; look here for details:
http://savannah.gnu.org/git/?group=make
https://savannah.gnu.org/git/?group=make
Please note: you won't be able to build GNU make from Git without installing
Please note: you won't be able to build GNU Make from Git without installing
appropriate maintainer's tools, such as GNU m4, automake, autoconf, Perl, GNU
make, and GCC.
See the README.git file for instructions on how to build GNU make once these
See the README.git file for instructions on how to build GNU Make once these
tools are available. We make no guarantees about the contents or quality of
the latest code in the Git repository: it is not unheard of for code that is
known to be broken to be checked in. Use at your own risk.
@@ -112,16 +145,16 @@ that if you compile make with 'cc -O' on AIX 3.2, it will not work
correctly. It is said that using 'cc' without '-O' does work.
The standard /bin/sh on SunOS 4.1.3_U1 and 4.1.4 is broken and cannot be
used to configure GNU make. Please install a different shell such as
used to configure GNU Make. Please install a different shell such as
bash or pdksh in order to run "configure". See this message for more
information:
http://mail.gnu.org/archive/html/bug-autoconf/2003-10/msg00190.html
https://mail.gnu.org/archive/html/bug-autoconf/2003-10/msg00190.html
One area that is often a problem in configuration and porting is the code
to check the system's current load average. To make it easier to test and
debug this code, you can do 'make check-loadavg' to see if it works
properly on your system. (You must run 'configure' beforehand, but you
need not build Make itself to run this test.)
need not build 'make' itself to run this test.)
Another potential source of porting problems is the support for large
files (LFS) in configure for those operating systems that provide it.
@@ -130,7 +163,7 @@ difficulties, then as a workaround you should be able to disable LFS by
adding the '--disable-largefile' option to the 'configure' script.
On systems that support micro- and nano-second timestamp values and
where stat(2) provides this information, GNU make will use it when
where stat(2) provides this information, GNU Make will use it when
comparing timestamps to get the most accurate possible result. However,
note that many current implementations of tools that *set* timestamps do
not preserve micro- or nano-second granularity. This means that "cp -p"
@@ -144,7 +177,7 @@ force make to treat them properly. See the manual for details.
Ports
-----
- See README.customs for details on integrating GNU make with the
- See README.customs for details on integrating GNU Make with the
Customs distributed build environment from the Pmake distribution.
- See README.VMS for details about GNU Make on OpenVMS.
@@ -157,22 +190,22 @@ Ports
using DJGPP tools.
A precompiled binary of the MSDOS port of GNU Make is available as part
of DJGPP; see the WWW page http://www.delorie.com/djgpp/ for more
of DJGPP; see the WWW page https://www.delorie.com/djgpp/ for more
information.
The Cygwin project maintains its own port of GNU make. That port may have
The Cygwin project maintains its own port of GNU Make. That port may have
patches which are not present in this version. If you are using Cygwin
you should use their version of GNU make, and if you have questions about
you should use their version of GNU Make, and if you have questions about
it you should start by asking on those mailing lists and forums.
Please note there are two _separate_ ports of GNU make for Microsoft
Please note there are two _separate_ ports of GNU Make for Microsoft
systems: a native Windows tool built with (for example) MSVC or Cygwin,
and a DOS-based tool built with DJGPP. Please be sure you are looking
at the right README!
-------------------------------------------------------------------------------
Copyright (C) 1988-2019 Free Software Foundation, Inc.
Copyright (C) 1988-2022 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -185,4 +218,4 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>.
this program. If not, see <https://www.gnu.org/licenses/>.

View File

@@ -101,7 +101,7 @@ The Rest of the List
-------------------------------------------------------------------------------
Copyright (C) 1997-2019 Free Software Foundation, Inc.
Copyright (C) 1997-2022 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -114,4 +114,4 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>.
this program. If not, see <https://www.gnu.org/licenses/>.

486
autogen.sh Executable file
View File

@@ -0,0 +1,486 @@
#!/bin/sh
# Convenience script for regenerating all autogeneratable files that are
# omitted from the version control repository. In particular, this script
# also regenerates all aclocal.m4, config.h.in, Makefile.in, configure files
# with new versions of autoconf or automake.
# Copyright (C) 2003-2022 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# Originally written by Paul Eggert. The canonical version of this
# script is maintained as top/autogen.sh in gnulib. However, to be
# useful to your package, you should place a copy of it under version
# control in the top-level directory of your package. The intent is
# that all customization can be done with a bootstrap.conf file also
# maintained in your version control; gnulib comes with a template
# build-aux/bootstrap.conf to get you started.
#
# Alternatively, you can use an autogen.sh script that is specific
# to your package.
scriptversion=2022-07-24.15; # UTC
me="$0"
medir=`dirname "$me"`
# Read the function library and the configuration.
. "$medir"/bootstrap-funclib.sh
# Ensure that CDPATH is not set. Otherwise, the output from cd
# would cause trouble in at least one use below.
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
# Environment variables that may be set by the user.
: "${AUTOPOINT=autopoint}"
: "${AUTORECONF=autoreconf}"
if test "$vc_ignore" = auto; then
vc_ignore=
test -d .git && vc_ignore=.gitignore
test -d CVS && vc_ignore="$vc_ignore .cvsignore"
fi
usage() {
cat <<EOF
Usage: $me [OPTION]...
Bootstrap this package from the checked-out sources.
Optional environment variables:
GNULIB_SRCDIR Specifies the local directory where gnulib
sources reside. Use this if you already
have gnulib sources on your machine, and
you want to use these sources.
Options:
--copy copy files instead of creating symbolic links
--force attempt to bootstrap even if the sources seem
not to have been checked out
EOF
bootstrap_print_option_usage_hook
cat <<EOF
If the file bootstrap.conf exists in the same directory as this script, its
contents are read as shell variables to configure the bootstrap.
For build prerequisites, environment variables like \$AUTOCONF and \$AMTAR
are honored.
Gnulib sources are assumed to be present:
* in \$GNULIB_SRCDIR, if that environment variable is set,
* otherwise, in the 'gnulib' submodule, if such a submodule is configured,
* otherwise, in the 'gnulib' subdirectory.
Running without arguments will suffice in most cases.
EOF
}
# Parse options.
# Whether to use copies instead of symlinks.
copy=false
for option
do
case $option in
--help)
usage
exit;;
--version)
set -e
echo "autogen.sh $scriptversion"
echo "$copyright"
exit 0
;;
--force)
checkout_only_file=;;
--copy)
copy=true;;
*)
bootstrap_option_hook $option || die "$option: unknown option";;
esac
done
test -z "$GNULIB_SRCDIR" || test -d "$GNULIB_SRCDIR" \
|| die "Error: \$GNULIB_SRCDIR environment variable or --gnulib-srcdir option is specified, but does not denote a directory"
if test -n "$checkout_only_file" && test ! -r "$checkout_only_file"; then
die "Running this script from a non-checked-out distribution is risky."
fi
if $use_gnulib; then
if test -z "$GNULIB_SRCDIR"; then
gnulib_path=$(test -f .gitmodules && git config --file .gitmodules submodule.gnulib.path)
test -z "$gnulib_path" && gnulib_path=gnulib
GNULIB_SRCDIR=$gnulib_path
fi
fi
version_controlled_file() {
parent=$1
file=$2
if test -d .git; then
git rm -n "$file" > /dev/null 2>&1
elif test -d .svn; then
svn log -r HEAD "$file" > /dev/null 2>&1
elif test -d CVS; then
grep -F "/${file##*/}/" "$parent/CVS/Entries" 2>/dev/null |
grep '^/[^/]*/[0-9]' > /dev/null
else
warn_ "no version control for $file?"
false
fi
}
# Strip blank and comment lines to leave significant entries.
gitignore_entries() {
sed '/^#/d; /^$/d' "$@"
}
# If $STR is not already on a line by itself in $FILE, insert it at the start.
# Entries are inserted at the start of the ignore list to ensure existing
# entries starting with ! are not overridden. Such entries support
# whitelisting exceptions after a more generic blacklist pattern.
insert_if_absent() {
file=$1
str=$2
test -f $file || touch $file
test -r $file || die "Error: failed to read ignore file: $file"
duplicate_entries=$(gitignore_entries $file | sort | uniq -d)
if [ "$duplicate_entries" ] ; then
die "Error: Duplicate entries in $file: " $duplicate_entries
fi
linesold=$(gitignore_entries $file | wc -l)
linesnew=$( { echo "$str"; cat $file; } | gitignore_entries | sort -u | wc -l)
if [ $linesold != $linesnew ] ; then
{ echo "$str" | cat - $file > $file.bak && mv $file.bak $file; } \
|| die "insert_if_absent $file $str: failed"
fi
}
# Adjust $PATTERN for $VC_IGNORE_FILE and insert it with
# insert_if_absent.
insert_vc_ignore() {
vc_ignore_file="$1"
pattern="$2"
case $vc_ignore_file in
*.gitignore)
# A .gitignore entry that does not start with '/' applies
# recursively to subdirectories, so prepend '/' to every
# .gitignore entry.
pattern=$(echo "$pattern" | sed s,^,/,);;
esac
insert_if_absent "$vc_ignore_file" "$pattern"
}
symlink_to_dir()
{
src=$1/$2
dst=${3-$2}
test -f "$src" && {
# If the destination directory doesn't exist, create it.
# This is required at least for "lib/uniwidth/cjk.h".
dst_dir=$(dirname "$dst")
if ! test -d "$dst_dir"; then
mkdir -p "$dst_dir"
# If we've just created a directory like lib/uniwidth,
# tell version control system(s) it's ignorable.
# FIXME: for now, this does only one level
parent=$(dirname "$dst_dir")
for dot_ig in x $vc_ignore; do
test $dot_ig = x && continue
ig=$parent/$dot_ig
insert_vc_ignore $ig "${dst_dir##*/}"
done
fi
if $copy; then
{
test ! -h "$dst" || {
echo "$me: rm -f $dst" &&
rm -f "$dst"
}
} &&
test -f "$dst" &&
cmp -s "$src" "$dst" || {
echo "$me: cp -fp $src $dst" &&
cp -fp "$src" "$dst"
}
else
# Leave any existing symlink alone, if it already points to the source,
# so that broken build tools that care about symlink times
# aren't confused into doing unnecessary builds. Conversely, if the
# existing symlink's timestamp is older than the source, make it afresh,
# so that broken tools aren't confused into skipping needed builds. See
# <https://lists.gnu.org/r/bug-gnulib/2011-05/msg00326.html>.
test -h "$dst" &&
src_ls=$(ls -diL "$src" 2>/dev/null) && set $src_ls && src_i=$1 &&
dst_ls=$(ls -diL "$dst" 2>/dev/null) && set $dst_ls && dst_i=$1 &&
test "$src_i" = "$dst_i" &&
both_ls=$(ls -dt "$src" "$dst") &&
test "X$both_ls" = "X$dst$nl$src" || {
dot_dots=
case $src in
/*) ;;
*)
case /$dst/ in
*//* | */../* | */./* | /*/*/*/*/*/)
die "invalid symlink calculation: $src -> $dst";;
/*/*/*/*/) dot_dots=../../../;;
/*/*/*/) dot_dots=../../;;
/*/*/) dot_dots=../;;
esac;;
esac
echo "$me: ln -fs $dot_dots$src $dst" &&
ln -fs "$dot_dots$src" "$dst"
}
fi
}
}
# Die if there is no AC_CONFIG_AUX_DIR($build_aux) line in configure.ac.
found_aux_dir=no
grep '^[ ]*AC_CONFIG_AUX_DIR(\['"$build_aux"'])' configure.ac \
>/dev/null && found_aux_dir=yes
grep '^[ ]*AC_CONFIG_AUX_DIR('"$build_aux"')' configure.ac \
>/dev/null && found_aux_dir=yes
test $found_aux_dir = yes \
|| die "configure.ac lacks 'AC_CONFIG_AUX_DIR([$build_aux])'; add it"
# If $build_aux doesn't exist, create it now, otherwise some bits
# below will malfunction. If creating it, also mark it as ignored.
if test ! -d $build_aux; then
mkdir $build_aux
for dot_ig in x $vc_ignore; do
test $dot_ig = x && continue
insert_vc_ignore $dot_ig $build_aux
done
fi
check_build_prerequisites false
use_libtool=0
# We'd like to use grep -E, to see if any of LT_INIT,
# AC_PROG_LIBTOOL, AM_PROG_LIBTOOL is used in configure.ac,
# but that's not portable enough (e.g., for Solaris).
grep '^[ ]*A[CM]_PROG_LIBTOOL' configure.ac >/dev/null \
&& use_libtool=1
grep '^[ ]*LT_INIT' configure.ac >/dev/null \
&& use_libtool=1
if test $use_libtool = 1; then
find_tool LIBTOOLIZE glibtoolize libtoolize
fi
if $use_gnulib; then
gnulib_tool=$GNULIB_SRCDIR/gnulib-tool
<$gnulib_tool || exit $?
fi
# NOTE: we have to be careful to run both autopoint and libtoolize
# before gnulib-tool, since gnulib-tool is likely to provide newer
# versions of files "installed" by these two programs.
# Then, *after* gnulib-tool (see below), we have to be careful to
# run autoreconf in such a way that it does not run either of these
# two just-pre-run programs.
# Import from gettext.
with_gettext=yes
grep '^[ ]*AM_GNU_GETTEXT_VERSION(' configure.ac >/dev/null || \
with_gettext=no
if test $with_gettext = yes || test $use_libtool = 1; then
tempbase=.bootstrap$$
trap "rm -f $tempbase.0 $tempbase.1" 1 2 13 15
> $tempbase.0 > $tempbase.1 &&
find . ! -type d -print | sort > $tempbase.0 || exit
if test $with_gettext = yes; then
# Released autopoint has the tendency to install macros that have been
# obsoleted in current gnulib, so run this before gnulib-tool.
echo "$0: $AUTOPOINT --force"
$AUTOPOINT --force || exit
fi
# Autoreconf runs aclocal before libtoolize, which causes spurious
# warnings if the initial aclocal is confused by the libtoolized
# (or worse out-of-date) macro directory.
# libtoolize 1.9b added the --install option; but we support back
# to libtoolize 1.5.22, where the install action was default.
if test $use_libtool = 1; then
install=
case $($LIBTOOLIZE --help) in
*--install*) install=--install ;;
esac
echo "running: $LIBTOOLIZE $install --copy"
$LIBTOOLIZE $install --copy
fi
find . ! -type d -print | sort >$tempbase.1
old_IFS=$IFS
IFS=$nl
for file in $(comm -13 $tempbase.0 $tempbase.1); do
IFS=$old_IFS
parent=${file%/*}
version_controlled_file "$parent" "$file" || {
for dot_ig in x $vc_ignore; do
test $dot_ig = x && continue
ig=$parent/$dot_ig
insert_vc_ignore "$ig" "${file##*/}"
done
}
done
IFS=$old_IFS
rm -f $tempbase.0 $tempbase.1
trap - 1 2 13 15
fi
# Import from gnulib.
if $use_gnulib; then
gnulib_tool_options="\
--no-changelog\
--aux-dir=$build_aux\
--doc-base=$doc_base\
--lib=$gnulib_name\
--m4-base=$m4_base/\
--source-base=$source_base/\
--tests-base=$tests_base\
--local-dir=$local_gl_dir\
$gnulib_tool_option_extras\
"
if test $use_libtool = 1; then
case "$gnulib_tool_options " in
*' --libtool '*) ;;
*) gnulib_tool_options="$gnulib_tool_options --libtool" ;;
esac
fi
echo "$0: $gnulib_tool $gnulib_tool_options --import ..."
$gnulib_tool $gnulib_tool_options --import $gnulib_modules \
|| die "gnulib-tool failed"
for file in $gnulib_files; do
symlink_to_dir "$GNULIB_SRCDIR" $file \
|| die "failed to symlink $file"
done
fi
bootstrap_post_import_hook \
|| die "bootstrap_post_import_hook failed"
# Remove any dangling symlink matching "*.m4" or "*.[ch]" in some
# gnulib-populated directories. Such .m4 files would cause aclocal to fail.
# The following requires GNU find 4.2.3 or newer. Considering the usual
# portability constraints of this script, that may seem a very demanding
# requirement, but it should be ok. Ignore any failure, which is fine,
# since this is only a convenience to help developers avoid the relatively
# unusual case in which a symlinked-to .m4 file is git-removed from gnulib
# between successive runs of this script.
find "$m4_base" "$source_base" \
-depth \( -name '*.m4' -o -name '*.[ch]' \) \
-type l -xtype l -delete > /dev/null 2>&1
# Invoke autoreconf with --force --install to ensure upgrades of tools
# such as ylwrap.
AUTORECONFFLAGS="--verbose --install --force -I $m4_base $ACLOCAL_FLAGS"
# Some systems (RHEL 5) are using ancient autotools, for which the
# --no-recursive option had not been invented. Detect that lack and
# omit the option when it's not supported. FIXME in 2017: remove this
# hack when RHEL 5 autotools are updated, or when they become irrelevant.
case $($AUTORECONF --help) in
*--no-recursive*) AUTORECONFFLAGS="$AUTORECONFFLAGS --no-recursive";;
esac
# Tell autoreconf not to invoke autopoint or libtoolize; they were run above.
echo "running: AUTOPOINT=true LIBTOOLIZE=true $AUTORECONF $AUTORECONFFLAGS"
AUTOPOINT=true LIBTOOLIZE=true $AUTORECONF $AUTORECONFFLAGS \
|| die "autoreconf failed"
# Get some extra files from gnulib, overriding existing files.
for file in $gnulib_extra_files; do
case $file in
*/INSTALL) dst=INSTALL;;
build-aux/*) dst=$build_aux/${file#build-aux/};;
*) dst=$file;;
esac
symlink_to_dir "$GNULIB_SRCDIR" $file $dst \
|| die "failed to symlink $file"
done
if test $with_gettext = yes; then
# Create gettext configuration.
echo "$0: Creating po/Makevars from po/Makevars.template ..."
rm -f po/Makevars
sed '
/^EXTRA_LOCALE_CATEGORIES *=/s/=.*/= '"$EXTRA_LOCALE_CATEGORIES"'/
/^COPYRIGHT_HOLDER *=/s/=.*/= '"$COPYRIGHT_HOLDER"'/
/^MSGID_BUGS_ADDRESS *=/s|=.*|= '"$MSGID_BUGS_ADDRESS"'|
/^XGETTEXT_OPTIONS *=/{
s/$/ \\/
a\
'"$XGETTEXT_OPTIONS"' $${end_of_xgettext_options+}
}
' po/Makevars.template >po/Makevars \
|| die 'cannot generate po/Makevars'
# If the 'gettext' module is in use, grab the latest Makefile.in.in.
# If only the 'gettext-h' module is in use, assume autopoint already
# put the correct version of this file into place.
case $gnulib_modules in
*gettext-h*) ;;
*gettext*)
cp $GNULIB_SRCDIR/build-aux/po/Makefile.in.in po/Makefile.in.in \
|| die "cannot create po/Makefile.in.in"
;;
esac
if test -d runtime-po; then
# Similarly for runtime-po/Makevars, but not quite the same.
rm -f runtime-po/Makevars
sed '
/^DOMAIN *=.*/s/=.*/= '"$package"'-runtime/
/^subdir *=.*/s/=.*/= runtime-po/
/^MSGID_BUGS_ADDRESS *=/s/=.*/= bug-'"$package"'@gnu.org/
/^XGETTEXT_OPTIONS *=/{
s/$/ \\/
a\
'"$XGETTEXT_OPTIONS_RUNTIME"' $${end_of_xgettext_options+}
}
' po/Makevars.template >runtime-po/Makevars \
|| die 'cannot generate runtime-po/Makevars'
# Copy identical files from po to runtime-po.
(cd po && cp -p Makefile.in.in *-quot *.header *.sed *.sin ../runtime-po)
fi
fi
bootstrap_epilogue
echo "$0: done. Now you can run './configure'."
# ----------------------------------------------------------------------------
# Local Variables:
# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:

273
autopull.sh Executable file
View File

@@ -0,0 +1,273 @@
#!/bin/sh
# Convenience script for fetching auxiliary files that are omitted from
# the version control repository of this package.
# Copyright (C) 2003-2022 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# Originally written by Paul Eggert. The canonical version of this
# script is maintained as top/autopull.sh in gnulib. However, to be
# useful to your package, you should place a copy of it under version
# control in the top-level directory of your package. The intent is
# that all customization can be done with a bootstrap.conf file also
# maintained in your version control; gnulib comes with a template
# build-aux/bootstrap.conf to get you started.
#
# Alternatively, you can use an autopull.sh script that is specific
# to your package.
scriptversion=2022-07-24.15; # UTC
me="$0"
medir=`dirname "$me"`
# Read the function library and the configuration.
. "$medir"/bootstrap-funclib.sh
# Ensure that CDPATH is not set. Otherwise, the output from cd
# would cause trouble in at least one use below.
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
usage() {
cat <<EOF
Usage: $me [OPTION]...
Bootstrap this package from the checked-out sources.
Optional environment variables:
GNULIB_SRCDIR Specifies the local directory where gnulib
sources reside. Use this if you already
have gnulib sources on your machine, and
you want to use these sources.
GNULIB_REFDIR Specifies the local directory where a gnulib
repository (with a .git subdirectory) resides.
Use this if you already have gnulib sources
and history on your machine, and do not want
to waste your bandwidth downloading them again.
GNULIB_URL Cloneable URL of the gnulib repository.
Options:
--bootstrap-sync if this bootstrap script is not identical to
the version in the local gnulib sources,
update this script, and then restart it with
/bin/sh or the shell \$CONFIG_SHELL
--no-bootstrap-sync do not check whether bootstrap is out of sync
--force attempt to bootstrap even if the sources seem
not to have been checked out
--no-git do not use git to update gnulib. Requires that
\$GNULIB_SRCDIR or the --gnulib-srcdir option
points to a gnulib repository with the correct
revision
--skip-po do not download po files
EOF
bootstrap_print_option_usage_hook
cat <<EOF
If the file bootstrap.conf exists in the same directory as this script, its
contents are read as shell variables to configure the bootstrap.
For build prerequisites, environment variables like \$AUTOCONF and \$AMTAR
are honored.
Gnulib sources can be fetched in various ways:
* If the environment variable GNULIB_SRCDIR is set (either as an
environment variable or via the --gnulib-srcdir option), then sources
are fetched from that local directory. If it is a git repository and
the configuration variable GNULIB_REVISION is set in bootstrap.conf,
then that revision is checked out.
* Otherwise, if this package is in a git repository with a 'gnulib'
submodule configured, then that submodule is initialized and updated
and sources are fetched from there. If GNULIB_REFDIR is set (either
as an environment variable or via the --gnulib-refdir option) and is
a git repository, then it is used as a reference.
* Otherwise, if the 'gnulib' directory does not exist, Gnulib sources
are cloned into that directory using git from \$GNULIB_URL, defaulting
to $default_gnulib_url.
If the configuration variable GNULIB_REVISION is set in bootstrap.conf,
then that revision is checked out.
* Otherwise, the existing Gnulib sources in the 'gnulib' directory are
used. If it is a git repository and the configuration variable
GNULIB_REVISION is set in bootstrap.conf, then that revision is
checked out.
If you maintain a package and want to pin a particular revision of the
Gnulib sources that has been tested with your package, then there are
two possible approaches: either configure a 'gnulib' submodule with the
appropriate revision, or set GNULIB_REVISION (and if necessary
GNULIB_URL) in bootstrap.conf.
Running without arguments will suffice in most cases.
EOF
}
# Parse options.
# Use git to update gnulib sources
use_git=true
for option
do
case $option in
--help)
usage
exit;;
--version)
set -e
echo "autopull.sh $scriptversion"
echo "$copyright"
exit 0
;;
--skip-po)
SKIP_PO=t;;
--force)
checkout_only_file=;;
--bootstrap-sync)
bootstrap_sync=true;;
--no-bootstrap-sync)
bootstrap_sync=false;;
--no-git)
use_git=false;;
*)
bootstrap_option_hook $option || die "$option: unknown option";;
esac
done
$use_git || test -n "$GNULIB_SRCDIR" \
|| die "Error: --no-git requires \$GNULIB_SRCDIR environment variable or --gnulib-srcdir option"
test -z "$GNULIB_SRCDIR" || test -d "$GNULIB_SRCDIR" \
|| die "Error: \$GNULIB_SRCDIR environment variable or --gnulib-srcdir option is specified, but does not denote a directory"
if test -n "$checkout_only_file" && test ! -r "$checkout_only_file"; then
die "Running this script from a non-checked-out distribution is risky."
fi
check_build_prerequisites $use_git
if $use_gnulib || $bootstrap_sync; then
prepare_GNULIB_SRCDIR
if $bootstrap_sync; then
upgrade_bootstrap
fi
fi
# Find sha1sum, named gsha1sum on MacPorts, shasum on Mac OS X 10.6.
# Also find the compatible sha1 utility on the BSDs
if test x"$SKIP_PO" = x; then
find_tool SHA1SUM sha1sum gsha1sum shasum sha1
fi
# See if we can use gnulib's git-merge-changelog merge driver.
if $use_git && test -d .git && check_exists git; then
if git config merge.merge-changelog.driver >/dev/null ; then
:
elif check_exists git-merge-changelog; then
echo "$0: initializing git-merge-changelog driver"
git config merge.merge-changelog.name 'GNU-style ChangeLog merge driver'
git config merge.merge-changelog.driver 'git-merge-changelog %O %A %B'
else
echo "$0: consider installing git-merge-changelog from gnulib"
fi
fi
# ----------------------------- Get translations. -----------------------------
download_po_files() {
subdir=$1
domain=$2
echo "$me: getting translations into $subdir for $domain..."
cmd=$(printf "$po_download_command_format" "$subdir" "$domain")
eval "$cmd"
}
# Mirror .po files to $po_dir/.reference and copy only the new
# or modified ones into $po_dir. Also update $po_dir/LINGUAS.
# Note po files that exist locally only are left in $po_dir but will
# not be included in LINGUAS and hence will not be distributed.
update_po_files() {
# Directory containing primary .po files.
# Overwrite them only when we're sure a .po file is new.
po_dir=$1
domain=$2
# Mirror *.po files into this dir.
# Usually contains *.s1 checksum files.
ref_po_dir="$po_dir/.reference"
test -d $ref_po_dir || mkdir $ref_po_dir || return
download_po_files $ref_po_dir $domain \
&& ls "$ref_po_dir"/*.po 2>/dev/null |
sed 's|.*/||; s|\.po$||' > "$po_dir/LINGUAS" || return
langs=$(cd $ref_po_dir && echo *.po | sed 's/\.po//g')
test "$langs" = '*' && langs=x
for po in $langs; do
case $po in x) continue;; esac
new_po="$ref_po_dir/$po.po"
cksum_file="$ref_po_dir/$po.s1"
if ! test -f "$cksum_file" ||
! test -f "$po_dir/$po.po" ||
! $SHA1SUM -c "$cksum_file" < "$new_po" > /dev/null 2>&1; then
echo "$me: updated $po_dir/$po.po..."
cp "$new_po" "$po_dir/$po.po" \
&& $SHA1SUM < "$new_po" > "$cksum_file" || return
fi
done
}
case $SKIP_PO in
'')
if test -d po; then
update_po_files po $package || exit
fi
if test -d runtime-po; then
update_po_files runtime-po $package-runtime || exit
fi;;
esac
# -----------------------------------------------------------------------------
bootstrap_post_pull_hook \
|| die "bootstrap_post_pull_hook failed"
# Don't proceed if there are uninitialized submodules. In particular,
# autogen.sh will remove dangling links, which might be links into
# uninitialized submodules.
# But it's OK if the 'gnulib' submodule is uninitialized, as long as
# GNULIB_SRCDIR is set.
if $use_git; then
# Uninitialized submodules are listed with an initial dash.
uninitialized=`git submodule | grep '^-' | awk '{ print $2 }'`
if test -n "$GNULIB_SRCDIR"; then
uninitialized=`echo "$uninitialized" | grep -v '^gnulib$'`
fi
if test -n "$uninitialized"; then
die "Some git submodules are not initialized: "`echo "$uninitialized" | tr '\n' ',' | sed -e 's|,$|.|'`" Either use option '--no-git', or run 'git submodule update --init' and bootstrap again."
fi
fi
echo "$0: done. Now you can run './autogen.sh'."
# ----------------------------------------------------------------------------
# Local Variables:
# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:

1099
bootstrap

File diff suppressed because it is too large Load Diff

594
bootstrap-funclib.sh Normal file
View File

@@ -0,0 +1,594 @@
# A library of shell functions for autopull.sh, autogen.sh, and bootstrap.
# Copyright (C) 2003-2022 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# Originally written by Paul Eggert. The canonical version of this
# script is maintained as top/bootstrap-funclib.sh in gnulib. However,
# to be useful to your package, you should place a copy of it under
# version control in the top-level directory of your package. The
# intent is that all customization can be done with a bootstrap.conf
# file also maintained in your version control; gnulib comes with a
# template build-aux/bootstrap.conf to get you started.
scriptversion=2022-07-24.15; # UTC
nl='
'
# Ensure file names are sorted consistently across platforms.
LC_ALL=C
export LC_ALL
# Honor $PERL, but work even if there is none.
PERL="${PERL-perl}"
default_gnulib_url=https://git.savannah.gnu.org/git/gnulib.git
# Copyright year, for the --version output.
copyright_year=`echo "$scriptversion" | sed -e 's/[^0-9].*//'`
copyright="Copyright (C) ${copyright_year} Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law."
# warnf_ FORMAT-STRING ARG1...
warnf_ ()
{
warnf_format_=$1
shift
nl='
'
case $* in
*$nl*) me_=$(printf "$me"|tr "$nl|" '??')
printf "$warnf_format_" "$@" | sed "s|^|$me_: |" ;;
*) printf "$me: $warnf_format_" "$@" ;;
esac >&2
}
# warn_ WORD1...
warn_ ()
{
# If IFS does not start with ' ', set it and emit the warning in a subshell.
case $IFS in
' '*) warnf_ '%s\n' "$*";;
*) (IFS=' '; warn_ "$@");;
esac
}
# die WORD1...
die() { warn_ "$@"; exit 1; }
# ------------------------------ Configuration. ------------------------------
# Directory that contains package-specific gnulib modules and/or overrides.
local_gl_dir=gl
# Name of the Makefile.am
# XXX Not used.
gnulib_mk=gnulib.mk
# List of gnulib modules needed.
gnulib_modules=
# Any gnulib files needed that are not in modules.
gnulib_files=
# A function to be called for each unrecognized option. Returns 0 if
# the option in $1 has been processed by the function. Returns 1 if
# the option has not been processed by the function. Override it via
# your own definition in bootstrap.conf
bootstrap_option_hook() { return 1; }
# A function to be called in order to print the --help information
# corresponding to user-defined command-line options.
bootstrap_print_option_usage_hook() { :; }
# A function to be called at the end of autopull.sh.
# Override it via your own definition in bootstrap.conf.
bootstrap_post_pull_hook() { :; }
# A function to be called right after gnulib-tool is run.
# Override it via your own definition in bootstrap.conf.
bootstrap_post_import_hook() { :; }
# A function to be called after everything else in this script.
# Override it via your own definition in bootstrap.conf.
bootstrap_epilogue() { :; }
# The command to download all .po files for a specified domain into a
# specified directory. Fill in the first %s with the destination
# directory and the second with the domain name.
po_download_command_format=\
"wget --mirror --level=1 -nd -nv -A.po -P '%s' \
https://translationproject.org/latest/%s/"
# Prefer a non-empty tarname (4th argument of AC_INIT if given), else
# fall back to the package name (1st argument with munging).
extract_package_name='
/^AC_INIT(\[*/{
s///
/^[^,]*,[^,]*,[^,]*,[ []*\([^][ ,)]\)/{
s//\1/
s/[],)].*//
p
q
}
s/[],)].*//
s/^GNU //
y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
s/[^abcdefghijklmnopqrstuvwxyz0123456789_]/-/g
p
}
'
package=$(${AUTOCONF:-autoconf} --trace AC_INIT:\$4 configure.ac 2>/dev/null)
if test -z "$package"; then
package=$(sed -n "$extract_package_name" configure.ac) \
|| die 'cannot find package name in configure.ac'
fi
gnulib_name=lib$package
build_aux=build-aux
source_base=lib
m4_base=m4
doc_base=doc
tests_base=tests
gnulib_extra_files="
build-aux/install-sh
build-aux/mdate-sh
build-aux/texinfo.tex
build-aux/depcomp
build-aux/config.guess
build-aux/config.sub
doc/INSTALL
"
# Additional gnulib-tool options to use. Use "\newline" to break lines.
gnulib_tool_option_extras=
# Other locale categories that need message catalogs.
EXTRA_LOCALE_CATEGORIES=
# Additional xgettext options to use. Use "\\\newline" to break lines.
XGETTEXT_OPTIONS='\\\
--flag=_:1:pass-c-format\\\
--flag=N_:1:pass-c-format\\\
--flag=error:3:c-format --flag=error_at_line:5:c-format\\\
'
# Package bug report address and copyright holder for gettext files
COPYRIGHT_HOLDER='Free Software Foundation, Inc.'
MSGID_BUGS_ADDRESS=bug-$package@gnu.org
# Files we don't want to import.
# XXX Not used.
excluded_files=
# File that should exist in the top directory of a checked out hierarchy,
# but not in a distribution tarball.
checkout_only_file=README-hacking
# Set this to '.cvsignore .gitignore' in bootstrap.conf if you want
# those files to be generated in directories like lib/, m4/, and po/.
# Or set it to 'auto' to make this script select which to use based
# on which version control system (if any) is used in the source directory.
vc_ignore=auto
# Set this to true in bootstrap.conf to enable --bootstrap-sync by
# default.
bootstrap_sync=false
# Override the default configuration, if necessary.
# Make sure that bootstrap.conf is sourced from the current directory
# if we were invoked as "sh bootstrap".
conffile=`dirname "$me"`/bootstrap.conf
test -r "$conffile" && . "$conffile"
# ------------------------- Build-time prerequisites -------------------------
check_exists() {
if test "$1" = "--verbose"; then
($2 --version </dev/null) >/dev/null 2>&1
if test $? -ge 126; then
# If not found, run with diagnostics as one may be
# presented with env variables to set to find the right version
($2 --version </dev/null)
fi
else
($1 --version </dev/null) >/dev/null 2>&1
fi
test $? -lt 126
}
# Note this deviates from the version comparison in automake
# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a
# but this should suffice as we won't be specifying old
# version formats or redundant trailing .0 in bootstrap.conf.
# If we did want full compatibility then we should probably
# use m4_version_compare from autoconf.
sort_ver() { # sort -V is not generally available
ver1="$1"
ver2="$2"
# split on '.' and compare each component
i=1
while : ; do
p1=$(echo "$ver1" | cut -d. -f$i)
p2=$(echo "$ver2" | cut -d. -f$i)
if [ ! "$p1" ]; then
echo "$1 $2"
break
elif [ ! "$p2" ]; then
echo "$2 $1"
break
elif [ ! "$p1" = "$p2" ]; then
if [ "$p1" -gt "$p2" ] 2>/dev/null; then # numeric comparison
echo "$2 $1"
elif [ "$p2" -gt "$p1" ] 2>/dev/null; then # numeric comparison
echo "$1 $2"
else # numeric, then lexicographic comparison
lp=$(printf "%s\n%s\n" "$p1" "$p2" | LANG=C sort -n | tail -n1)
if [ "$lp" = "$p2" ]; then
echo "$1 $2"
else
echo "$2 $1"
fi
fi
break
fi
i=$(($i+1))
done
}
get_version_sed='
# Move version to start of line.
s/.*[v ]\([0-9]\)/\1/
# Skip lines that do not start with version.
/^[0-9]/!d
# Remove characters after the version.
s/[^.a-z0-9-].*//
# The first component must be digits only.
s/^\([0-9]*\)[a-z-].*/\1/
#the following essentially does s/5.005/5.5/
s/\.0*\([1-9]\)/.\1/g
p
q'
get_version() {
app=$1
$app --version >/dev/null 2>&1 || { $app --version; return 1; }
$app --version 2>&1 | sed -n "$get_version_sed"
}
check_versions() {
ret=0
while read app req_ver; do
# We only need libtoolize from the libtool package.
if test "$app" = libtool; then
app=libtoolize
fi
# Exempt git if git is not needed.
if test "$app" = git; then
$check_git || continue
fi
# Honor $APP variables ($TAR, $AUTOCONF, etc.)
appvar=$(echo $app | LC_ALL=C tr '[a-z]-' '[A-Z]_')
test "$appvar" = TAR && appvar=AMTAR
case $appvar in
GZIP) ;; # Do not use $GZIP: it contains gzip options.
PERL::*) ;; # Keep perl modules as-is
*) eval "app=\${$appvar-$app}" ;;
esac
# Handle the still-experimental Automake-NG programs specially.
# They remain named as the mainstream Automake programs ("automake",
# and "aclocal") to avoid gratuitous incompatibilities with
# pre-existing usages (by, say, autoreconf, or custom autogen.sh
# scripts), but correctly identify themselves (as being part of
# "GNU automake-ng") when asked their version.
case $app in
automake-ng|aclocal-ng)
app=${app%-ng}
($app --version | grep '(GNU automake-ng)') >/dev/null 2>&1 || {
warn_ "Error: '$app' not found or not from Automake-NG"
ret=1
continue
} ;;
# Another check is for perl modules. These can be written as
# e.g. perl::XML::XPath in case of XML::XPath module, etc.
perl::*)
# Extract module name
app="${app#perl::}"
if ! $PERL -m"$app" -e 'exit 0' >/dev/null 2>&1; then
warn_ "Error: perl module '$app' not found"
ret=1
fi
continue
;;
esac
if [ "$req_ver" = "-" ]; then
# Merely require app to exist; not all prereq apps are well-behaved
# so we have to rely on $? rather than get_version.
if ! check_exists --verbose $app; then
warn_ "Error: '$app' not found"
ret=1
fi
else
# Require app to produce a new enough version string.
inst_ver=$(get_version $app)
if [ ! "$inst_ver" ]; then
warn_ "Error: '$app' not found"
ret=1
else
latest_ver=$(sort_ver $req_ver $inst_ver | cut -d' ' -f2)
if [ ! "$latest_ver" = "$inst_ver" ]; then
warnf_ '%s\n' \
"Error: '$app' version == $inst_ver is too old" \
" '$app' version >= $req_ver is required"
ret=1
fi
fi
fi
done
return $ret
}
print_versions() {
echo "Program Min_version"
echo "----------------------"
printf %s "$buildreq"
echo "----------------------"
# can't depend on column -t
}
# check_build_prerequisites check_git
check_build_prerequisites()
{
check_git="$1"
# gnulib-tool requires at least automake and autoconf.
# If either is not listed, add it (with minimum version) as a prerequisite.
case $buildreq in
*automake*) ;;
*) buildreq="automake 1.9
$buildreq" ;;
esac
case $buildreq in
*autoconf*) ;;
*) buildreq="autoconf 2.59
$buildreq" ;;
esac
# When we can deduce that gnulib-tool will require patch,
# and when patch is not already listed as a prerequisite, add it, too.
if test -d "$local_gl_dir" \
&& ! find "$local_gl_dir" -name '*.diff' -exec false {} +; then
case $buildreq in
*patch*) ;;
*) buildreq="patch -
$buildreq" ;;
esac
fi
if ! printf '%s' "$buildreq" | check_versions; then
echo >&2
if test -f README-prereq; then
die "See README-prereq for how to get the prerequisite programs"
else
die "Please install the prerequisite programs"
fi
fi
# Warn the user if autom4te appears to be broken; this causes known
# issues with at least gettext 0.18.3.
probe=$(echo 'm4_quote([hi])' | autom4te -l M4sugar -t 'm4_quote:$%' -)
if test "x$probe" != xhi; then
warn_ "WARNING: your autom4te wrapper eats stdin;"
warn_ "if bootstrap fails, consider upgrading your autotools"
fi
}
# find_tool ENVVAR NAMES...
# -------------------------
# Search for a required program. Use the value of ENVVAR, if set,
# otherwise find the first of the NAMES that can be run.
# If found, set ENVVAR to the program name, die otherwise.
#
# FIXME: code duplication, see also gnu-web-doc-update.
find_tool ()
{
find_tool_envvar=$1
shift
find_tool_names=$@
eval "find_tool_res=\$$find_tool_envvar"
if test x"$find_tool_res" = x; then
for i; do
if check_exists $i; then
find_tool_res=$i
break
fi
done
fi
if test x"$find_tool_res" = x; then
warn_ "one of these is required: $find_tool_names;"
die "alternatively set $find_tool_envvar to a compatible tool"
fi
eval "$find_tool_envvar=\$find_tool_res"
eval "export $find_tool_envvar"
}
# --------------------- Preparing GNULIB_SRCDIR for use. ---------------------
# This is part of autopull.sh, but bootstrap needs it too, for self-upgrading.
cleanup_gnulib() {
status=$?
# XXX It's a bad idea to erase the submodule directory if it contains local
# modifications.
rm -fr "$gnulib_path"
exit $status
}
git_modules_config () {
test -f .gitmodules && git config --file .gitmodules "$@"
}
prepare_GNULIB_SRCDIR ()
{
if test -n "$GNULIB_SRCDIR"; then
# Use GNULIB_SRCDIR directly.
# We already checked that $GNULIB_SRCDIR references a directory.
# Verify that it contains a gnulib checkout.
test -f "$GNULIB_SRCDIR/gnulib-tool" \
|| die "Error: --gnulib-srcdir or \$GNULIB_SRCDIR is specified, but does not contain gnulib-tool"
elif $use_git; then
gnulib_path=$(git_modules_config submodule.gnulib.path)
test -z "$gnulib_path" && gnulib_path=gnulib
# Get gnulib files. Populate $gnulib_path, possibly updating a
# submodule, for use in the rest of the script.
if test -n "$GNULIB_REFDIR" && test -d "$GNULIB_REFDIR"/.git \
&& git_modules_config submodule.gnulib.url >/dev/null; then
# Use GNULIB_REFDIR as a reference.
echo "$0: getting gnulib files..."
if git submodule -h|grep -- --reference > /dev/null; then
# Prefer the one-liner available in git 1.6.4 or newer.
git submodule update --init --reference "$GNULIB_REFDIR" \
"$gnulib_path" || exit $?
else
# This fallback allows at least git 1.5.5.
if test -f "$gnulib_path"/gnulib-tool; then
# Since file already exists, assume submodule init already complete.
git submodule update -- "$gnulib_path" || exit $?
else
# Older git can't clone into an empty directory.
rmdir "$gnulib_path" 2>/dev/null
git clone --reference "$GNULIB_REFDIR" \
"$(git_modules_config submodule.gnulib.url)" "$gnulib_path" \
&& git submodule init -- "$gnulib_path" \
&& git submodule update -- "$gnulib_path" \
|| exit $?
fi
fi
else
# GNULIB_REFDIR is not set or not usable. Ignore it.
if git_modules_config submodule.gnulib.url >/dev/null; then
echo "$0: getting gnulib files..."
git submodule init -- "$gnulib_path" || exit $?
git submodule update -- "$gnulib_path" || exit $?
elif [ ! -d "$gnulib_path" ]; then
echo "$0: getting gnulib files..."
trap cleanup_gnulib 1 2 13 15
shallow=
if test -z "$GNULIB_REVISION"; then
if git clone -h 2>&1 | grep -- --depth > /dev/null; then
shallow='--depth 2'
fi
git clone $shallow ${GNULIB_URL:-$default_gnulib_url} "$gnulib_path" \
|| cleanup_gnulib
else
if git fetch -h 2>&1 | grep -- --depth > /dev/null; then
shallow='--depth 2'
fi
mkdir -p "$gnulib_path"
# Only want a shallow checkout of $GNULIB_REVISION, but git does not
# support cloning by commit hash. So attempt a shallow fetch by commit
# hash to minimize the amount of data downloaded and changes needed to
# be processed, which can drastically reduce download and processing
# time for checkout. If the fetch by commit fails, a shallow fetch can
# not be performed because we do not know what the depth of the commit
# is without fetching all commits. So fallback to fetching all commits.
git -C "$gnulib_path" init
git -C "$gnulib_path" remote add origin \
${GNULIB_URL:-$default_gnulib_url}
git -C "$gnulib_path" fetch $shallow origin "$GNULIB_REVISION" \
|| git -C "$gnulib_path" fetch origin \
|| cleanup_gnulib
git -C "$gnulib_path" reset --hard FETCH_HEAD
fi
trap - 1 2 13 15
fi
fi
GNULIB_SRCDIR=$gnulib_path
# Verify that the submodule contains a gnulib checkout.
test -f "$gnulib_path/gnulib-tool" \
|| die "Error: $gnulib_path is supposed to contain a gnulib checkout, but does not contain gnulib-tool"
fi
# XXX Should this be done if $use_git is false?
if test -d "$GNULIB_SRCDIR"/.git && test -n "$GNULIB_REVISION" \
&& ! git_modules_config submodule.gnulib.url >/dev/null; then
(cd "$GNULIB_SRCDIR" && git checkout "$GNULIB_REVISION") || cleanup_gnulib
fi
# $GNULIB_SRCDIR now points to the version of gnulib to use, and
# we no longer need to use git or $gnulib_path below here.
}
# -------- Upgrading bootstrap to the version found in GNULIB_SRCDIR. --------
upgrade_bootstrap ()
{
{ cmp -s "$medir"/bootstrap "$GNULIB_SRCDIR/top/bootstrap" \
&& cmp -s "$medir"/bootstrap-funclib.sh "$GNULIB_SRCDIR/top/bootstrap-funclib.sh" \
&& cmp -s "$medir"/autopull.sh "$GNULIB_SRCDIR/top/autopull.sh" \
&& cmp -s "$medir"/autogen.sh "$GNULIB_SRCDIR/top/autogen.sh"; \
} || {
echo "$0: updating bootstrap & companions and restarting..."
case $(sh -c 'echo "$1"' -- a) in
a) ignored=--;;
*) ignored=ignored;;
esac
exec sh -c \
'{ if test -f "$1"; then cp "$1" "$3"; else cp "$2" "$3"; fi; } && { if test -f "$4"; then cp "$4" "$5"; else rm -f "$5"; fi; } && { if test -f "$6"; then cp "$6" "$7"; else rm -f "$7"; fi; } && { if test -f "$8"; then cp "$8" "$9"; else rm -f "$9"; fi; } && shift && shift && shift && shift && shift && shift && shift && shift && shift && exec "${CONFIG_SHELL-/bin/sh}" "$@"' \
$ignored \
"$GNULIB_SRCDIR/top/bootstrap" "$GNULIB_SRCDIR/build-aux/bootstrap" "$medir/bootstrap" \
"$GNULIB_SRCDIR/top/bootstrap-funclib.sh" "$medir/bootstrap-funclib.sh" \
"$GNULIB_SRCDIR/top/autopull.sh" "$medir/autopull.sh" \
"$GNULIB_SRCDIR/top/autogen.sh" "$medir/autogen.sh" \
"$0" "$@" --no-bootstrap-sync
}
}
# ----------------------------------------------------------------------------
if test x"$gnulib_modules$gnulib_files$gnulib_extra_files" = x; then
use_gnulib=false
else
use_gnulib=true
fi
# ----------------------------------------------------------------------------
# Local Variables:
# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:

View File

@@ -1,5 +1,5 @@
@echo off
:: Copyright (C) 2018-2019 Free Software Foundation, Inc.
:: Copyright (C) 2018-2022 Free Software Foundation, Inc.
:: This file is part of GNU Make.
::
:: GNU Make is free software; you can redistribute it and/or modify it under
@@ -13,22 +13,79 @@
:: more details.
::
:: You should have received a copy of the GNU General Public License along
:: with this program. If not, see <http://www.gnu.org/licenses/>.
:: with this program. If not, see <https://www.gnu.org/licenses/>.
setlocal
set "svurl=https://git.savannah.gnu.org/cgit"
set "gnuliburl=%svurl%/gnulib.git/plain"
where curl >nul 2>&1
if ERRORLEVEL 1 (
echo Cannot find curl: it must be installed for bootstrap
exit /b 1
)
where sed >nul 2>&1
if ERRORLEVEL 1 (
echo Cannot find sed: it must be installed for bootstrap
echo Hint: you can use the sed provided in the Git for Windows install
exit /b 1
)
if exist lib goto Downloads
mkdir lib
if ERRORLEVEL 1 exit /b 1
:Downloads
echo -- Downloading Gnulib modules
call :Download lib getloadavg.c
call :Download lib intprops.h
goto :Done
call :Download lib intprops-internal.h
echo -- Configuring the workspace
copy /Y gl\lib\*.* lib > nul
:: Create a sed script to convert templates
if exist convert.sed del /Q convert.sed
echo s,@PACKAGE@,make,g > convert.sed
if ERRORLEVEL 1 goto Failed
echo s,@PACKAGE_BUGREPORT@,bug-make@gnu.org,g >> convert.sed
if ERRORLEVEL 1 goto Failed
echo s,@PACKAGE_NAME@,GNU Make,g >> convert.sed
if ERRORLEVEL 1 goto Failed
echo s,@PACKAGE_TARNAME@,make,g >> convert.sed
if ERRORLEVEL 1 goto Failed
echo s,@PACKAGE_URL@,https://www.gnu.org/software/make/,g >> convert.sed
sed -n "s/^AC_INIT(\[GNU.Make\],\[\([0-9.]*\)\].*/s,@PACKAGE_VERSION@,\1,g/p" configure.ac >> convert.sed
if ERRORLEVEL 1 goto Failed
sed -z -e s/\\\n//g -e "s/[ \t][ \t]*/ /g" -e "s, [^ ]*\.h,,g" -e "s,src/,$(src),g" -e "s,lib/,$(lib),g" Makefile.am | sed -n "s/^\([A-Za-z0-9]*\)_SRCS *= *\(.*\)/s,%%\1_SOURCES%%,\2,/p" >> convert.sed
if ERRORLEVEL 1 goto Failed
echo - Creating Basic.mk
sed -f convert.sed Basic.mk.template > Basic.mk
if ERRORLEVEL 1 goto Failed
echo - Creating src\mkconfig.h
sed -f convert.sed src\mkconfig.h.in > src\mkconfig.h
if ERRORLEVEL 1 goto Failed
echo - Creating src\gmk-default.h
echo static const char *const GUILE_module_defn = ^" \ > src\gmk-default.h
sed -e "s/;.*//" -e "/^[ \t]*$/d" -e "s/\"/\\\\\"/g" -e "s/$/ \\\/" src\gmk-default.scm >> src\gmk-default.h
if ERRORLEVEL 1 goto Failed
echo ^";>> src\gmk-default.h
echo.
echo Done. Run build_w32.bat to build GNU make.
goto :EOF
:Download
echo Downloading %1\%2
curl -sS -o %1\%2 "%gnuliburl%/%1/%2"
if exist "%1\%2" goto :EOF
echo - Downloading %1\%2
curl -sS -o "%1\%2" "%gnuliburl%/%1/%2"
if ERRORLEVEL 1 exit /b 1
goto :EOF
:Done
echo Done. Run buld_w32.bat to build GNU make.
goto :EOF
:Failed
echo *** Bootstrap failed.
echo Resolve the issue, or use the configured source in the release tarball
exit /b 1

View File

@@ -1,6 +1,6 @@
# Bootstrap configuration. -*-shell-script-*-
# Copyright (C) 2018-2019 Free Software Foundation, Inc.
# Copyright (C) 2018-2022 Free Software Foundation, Inc.
# GNU Make is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
@@ -18,6 +18,12 @@
# Allow bootstrap to know that this is not a package
checkout_only_file=README.git
# Choose a specific version of gnulib, when checking out
GNULIB_REVISION=stable-202207
# Always copy files rather than symlink
copy=true
# Additional xgettext options to use. Use "\\\newline" to break lines.
# Ensure that all our magical output macros are correctly marked as
# C (printf) format strings.
@@ -41,7 +47,12 @@ automake 1.16.1
"
gnulib_name=libgnu
gnulib_files=doc/make-stds.texi
gnulib_files="doc/make-stds.texi m4/sig_atomic_t.m4"
# Using the full strtoll module pulls in a lot of stuff. But, it's pretty
# simple to use just the base source file, so pull that. We'll use it in
# src/misc.c if strtoll() is not found.
gnulib_files="$gnulib_files lib/strtol.c"
gnulib_modules="\
alloca
@@ -49,5 +60,6 @@ fdl
findprog-in
getloadavg
host-cpu-c-abi
strerror
make-glob"
largefile
make-glob
make-macros"

View File

@@ -1,7 +1,7 @@
# Configuration for building GNU Make in the absence of any 'make' program.
# @configure_input@
# Copyright (C) 1993-2019 Free Software Foundation, Inc.
# Copyright (C) 1993-2022 Free Software Foundation, Inc.
# This file is part of GNU Make.
#
# GNU Make is free software; you can redistribute it and/or modify it under
@@ -15,7 +15,7 @@
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>.
# this program. If not, see <https://www.gnu.org/licenses/>.
# See Makefile.in for comments describing these variables.

View File

@@ -1,7 +1,7 @@
#!/bin/sh
# Shell script to build GNU Make in the absence of any 'make' program.
# Copyright (C) 1993-2019 Free Software Foundation, Inc.
# Copyright (C) 1993-2022 Free Software Foundation, Inc.
# This file is part of GNU Make.
#
# GNU Make is free software; you can redistribute it and/or modify it under
@@ -15,11 +15,16 @@
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>.
# this program. If not, see <https://www.gnu.org/licenses/>.
# Get configure-generated values
. ./build.cfg
die () { echo "$*" 1>&2; exit 1; }
usage () { echo "$0 [-k]"; exit $1; }
keep_going=false
: ${OUTDIR:=.}
OUTLIB="$OUTDIR/lib"
@@ -55,15 +60,29 @@ get_mk_var ()
# Compile source files. Object files are put into $objs.
compile ()
{
success=true
objs=
for ofile in "$@"; do
# We should try to use a Makefile variable like libgnu_a_SOURCES or
# something but just hardcode it.
file="${ofile%.$OBJEXT}.c"
case $file in
(lib/libgnu_a-*.c) file="lib/${file#lib/libgnu_a-}" ;;
esac
echo "compiling $file..."
of="$OUTDIR/$ofile"
mkdir -p "${of%/*}"
$CC $cflags $CPPFLAGS $CFLAGS -c -o "$of" "$top_srcdir/$file"
mkdir -p "${of%/*}" || exit 1
if $CC $cflags $CPPFLAGS $CFLAGS -c -o "$of" "$top_srcdir/$file"; then
: worked
else
$keep_going || die "Compilation failed."
success=false
fi
objs="${objs:+$objs }$of"
done
$success
}
# Use config.status to convert a .in file. Output file is put into $out.
@@ -75,10 +94,13 @@ convert ()
var="GENERATE_$(echo $base | tr 'a-z./+' A-Z__X)"
# Is this file disabled?
grep "${var}_FALSE\"]=\"\"" config.status >/dev/null && return
grep "${var}_FALSE\"]=\"\"" config.status >/dev/null && return 0
# If there's no .in file then no conversion needed
in="$top_srcdir/lib/$(echo ${base%.*}.in.${base##*.} | tr / _)"
test -f "$in" || return 0
# Not disabled, so create it
in="$top_srcdir/lib/$(echo ${base%.*}.in.${base##*.} | tr / _)"
out="$OUTLIB/$base"
mkdir -p "${out%/*}"
@@ -103,7 +125,7 @@ convert ()
esac
fn="$top_srcdir/lib/${fn##*/}"
[ -f "$fn" ] || { echo "Missing file: $fn"; exit 1; }
test -f "$fn" || { echo "Missing file: $fn"; exit 1; }
sed "/definitions* of $inc/r $fn" "$int" > "${int}_"
int=${int}_
@@ -122,28 +144,39 @@ done
# Get object files from the Makefile
OBJS=$(get_mk_var Makefile make_OBJECTS | sed "s=\$[\(\{]OBJEXT[\)\}]=$OBJEXT=g")
# Exit as soon as any command fails.
set -e
while test -n "$1"; do
case $1 in
(-k) keep_going=true; shift ;;
(--) shift; break ;;
(-[h?]) usage 0 ;;
(-*) echo "Unknown option: $1"; usage 1 ;;
esac
done
test -z "$1" || die "Unknown argument: $*"
# Generate gnulib header files that would normally be created by make
set -e
for b in $(get_mk_var lib/Makefile BUILT_SOURCES); do
convert $b
done
set +e
# Build the gnulib library
cflags="$DEFS -I$OUTLIB -Ilib -I$top_srcdir/lib -I$OUTDIR/src -Isrc -I$top_srcdir/src"
compile $LIBOBJS
compile $LIBOBJS || die "Compilation failed."
echo "creating libgnu.a..."
$AR $ARFLAGS "$OUTLIB"/libgnu.a $objs
$AR $ARFLAGS "$OUTLIB"/libgnu.a $objs || die "Archive of libgnu failed."
# Compile the source files into those objects.
cflags="$DEFS $defines -I$OUTDIR/src -Isrc -I$top_srcdir/src -I$OUTLIB -Ilib -I$top_srcdir/lib"
compile $OBJS
compile $OBJS || die "Compilation failed."
# Link all the objects together.
echo "linking make..."
$CC $CFLAGS $LDFLAGS -L"$OUTLIB" $objs -lgnu $LOADLIBES -o "$OUTDIR/makenew$EXEEXT"
mv -f "$OUTDIR/makenew$EXEEXT" "$OUTDIR/make$EXEEXT"
$CC $CFLAGS $LDFLAGS -L"$OUTLIB" -o "$OUTDIR/makenew$EXEEXT" $objs -lgnu $LOADLIBES || die "Link failed."
mv -f "$OUTDIR/makenew$EXEEXT" "$OUTDIR/make$EXEEXT" || exit 1
echo done.

135
build_w32.bat Executable file → Normal file
View File

@@ -1,5 +1,5 @@
@echo off
:: Copyright (C) 1996-2019 Free Software Foundation, Inc.
:: Copyright (C) 1996-2022 Free Software Foundation, Inc.
:: This file is part of GNU Make.
::
:: GNU Make is free software; you can redistribute it and/or modify it under
@@ -13,7 +13,7 @@
:: more details.
::
:: You should have received a copy of the GNU General Public License along
:: with this program. If not, see <http://www.gnu.org/licenses/>.
:: with this program. If not, see <https://www.gnu.org/licenses/>.
setlocal
if not "%RECURSEME%"=="%~0" (
@@ -37,6 +37,8 @@ set COMPILER=cl.exe
set O=obj
set ARCH=x64
set DEBUG=N
set DIRENT=Y
set VERBOSE=N
if exist maintMakefile (
set MAINT=Y
@@ -45,13 +47,20 @@ if exist maintMakefile (
)
:ParseSW
if "%1" == "--verbose" goto SetVerbose
if "%1" == "--debug" goto SetDebug
if "%1" == "--without-guile" goto NoGuile
if "%1" == "--x86" goto Set32Bit
if "%1" == "gcc" goto SetCC
if "%1" == "tcc" goto SetTCC
if "%1" == "" goto DoneSW
goto Usage
:SetVerbose
set VERBOSE=Y
shift
goto ParseSW
:SetDebug
set DEBUG=Y
echo - Building without compiler optimizations
@@ -77,20 +86,28 @@ echo - Building with GCC
shift
goto ParseSW
:SetTCC
set COMPILER=tcc
set O=o
echo - Building with TinyC
shift
goto ParseSW
:DoneSW
if "%MAINT%" == "Y" echo - Enabling maintainer mode
if "%COMPILER%" == "gcc" goto FindGcc
if "%COMPILER%" == "tcc" goto FindTcc
:: Find a compiler. Visual Studio requires a lot of effort to locate :-/.
%COMPILER% >nul 2>&1
call %COMPILER% >nul 2>&1
if not ERRORLEVEL 1 goto FoundMSVC
:: Visual Studio 17 and above provides the "vswhere" tool
call :FindVswhere
if ERRORLEVEL 1 goto LegacyVS
for /f "tokens=* usebackq" %%i in (`%VSWHERE% -latest -property installationPath`) do (
for /f "tokens=* usebackq" %%i in (`"%VSWHERE%" -latest -property installationPath`) do (
set InstallPath=%%i
)
set "VSVARS=%InstallPath%\VC\Auxiliary\Build\vcvarsall.bat"
@@ -165,20 +182,36 @@ if "%MAINT%" == "Y" set "OPTS=%OPTS% /D MAKE_MAINTAINER_MODE"
:: Show the compiler version that we found
:: Unfortunately this also shows a "usage" note; I can't find anything better.
echo.
%COMPILER%
call %COMPILER%
goto Build
:FindGcc
set OUTDIR=.\GccRel
set LNKOUT=./GccRel
set OPTS=-O2
set DIRENT=N
if "%DEBUG%" == "Y" set OPTS=-O0
if "%DEBUG%" == "Y" set OUTDIR=.\GccDebug
if "%DEBUG%" == "Y" set LNKOUT=./GccDebug
if "%MAINT%" == "Y" set "OPTS=%OPTS% -DMAKE_MAINTAINER_MODE"
:: Show the compiler version that we found
echo.
%COMPILER% --version
call %COMPILER% --version
if not ERRORLEVEL 1 goto Build
echo No %COMPILER% found.
exit 1
:FindTcc
set OUTDIR=.\TccRel
set LNKOUT=./TccRel
set OPTS=-O2
if "%DEBUG%" == "Y" set OPTS=-O0
if "%DEBUG%" == "Y" set OUTDIR=.\TccDebug
if "%DEBUG%" == "Y" set LNKOUT=./TccDebug
if "%MAINT%" == "Y" set "OPTS=%OPTS% -DMAKE_MAINTAINER_MODE"
:: Show the compiler version that we found
echo.
call %COMPILER% -v
if not ERRORLEVEL 1 goto Build
echo No %COMPILER% found.
exit 1
@@ -197,10 +230,11 @@ mkdir %OUTDIR%\lib
if "%GUILE%" == "Y" call :ChkGuile
if not exist src\config.h.W32 goto NotConfig
echo.
echo Compiling %OUTDIR% version
if exist src\config.h.W32.template call :ConfigSCM
copy src\config.h.W32 %OUTDIR%\src\config.h
copy lib\glob.in.h %OUTDIR%\lib\glob.h
@@ -231,6 +265,7 @@ call :Compile src/read
call :Compile src/remake
call :Compile src/remote-stub
call :Compile src/rule
call :Compile src/shuffle
call :Compile src/signame
call :Compile src/strcache
call :Compile src/variable
@@ -246,7 +281,8 @@ call :Compile lib/fnmatch
call :Compile lib/glob
call :Compile lib/getloadavg
if not "%COMPILER%" == "gcc" call :Compile src\w32\compat\dirent
:: Compile dirent unless it is supported by compiler library (like with gcc).
if "%DIRENT%" == "Y" call :Compile src\w32\compat\dirent
call :Link
@@ -258,6 +294,7 @@ exit 1
:Success
echo %OUTDIR% build succeeded.
if exist Basic.mk copy /Y Basic.mk Makefile
if not exist tests\config-flags.pm copy /Y tests\config-flags.pm.W32 tests\config-flags.pm
call :Reset
goto :EOF
@@ -266,23 +303,33 @@ goto :EOF
::
:Compile
if "%VERBOSE%" == "N" echo - Compiling %1.c
echo %LNKOUT%/%1.%O% >>%OUTDIR%\link.sc
set EXTRAS=
if "%2" == "GUILE" set "EXTRAS=%GUILECFLAGS%"
if exist "%OUTDIR%\%1.%O%" del "%OUTDIR%\%1.%O%"
if "%COMPILER%" == "gcc" goto GccCompile
if "%COMPILER%" == "tcc" goto TccCompile
:: MSVC Compile
echo on
%COMPILER% /nologo /MT /W4 /EHsc %OPTS% /I %OUTDIR%/src /I src /I %OUTDIR%/lib /I lib /I src/w32/include /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR%OUTDIR% /Fp%OUTDIR%\%MAKE%.pch /Fo%OUTDIR%\%1.%O% /Fd%OUTDIR%\%MAKE%.pdb %EXTRAS% /c %1.c
if "%VERBOSE%" == "Y" echo on
call %COMPILER% /nologo /MT /W4 /EHsc %OPTS% /I %OUTDIR%/src /I src /I %OUTDIR%/lib /I lib /I src/w32/include /D _CONSOLE /D HAVE_CONFIG_H /FR%OUTDIR% /Fp%OUTDIR%\%MAKE%.pch /Fo%OUTDIR%\%1.%O% /Fd%OUTDIR%\%MAKE%.pdb %EXTRAS% /c %1.c
@echo off
goto CompileDone
:GccCompile
:: GCC Compile
echo on
%COMPILER% -mthreads -Wall -std=gnu99 -gdwarf-2 -g3 %OPTS% -I%OUTDIR%/src -I./src -I%OUTDIR%/lib -I./lib -I./src/w32/include -DWINDOWS32 -DHAVE_CONFIG_H %EXTRAS% -o %OUTDIR%/%1.%O% -c %1.c
if "%VERBOSE%" == "Y" echo on
call %COMPILER% -mthreads -Wall -std=gnu99 -gdwarf-2 -g3 %OPTS% -I%OUTDIR%/src -I./src -I%OUTDIR%/lib -I./lib -I./src/w32/include -DHAVE_CONFIG_H %EXTRAS% -o %OUTDIR%/%1.%O% -c %1.c
@echo off
goto CompileDone
:TccCompile
:: TCC Compile
if "%VERBOSE%" == "Y" echo on
call %COMPILER% -mthreads -Wall -std=c11 %OPTS% -I%OUTDIR%/src -I./src -I%OUTDIR%/lib -I./lib -I./src/w32/include -D_cdecl= -D_MSC_VER -DHAVE_CONFIG_H %EXTRAS% -o %OUTDIR%/%1.%O% -c %1.c
@echo off
goto CompileDone
:CompileDone
if not exist "%OUTDIR%\%1.%O%" exit 1
@@ -290,56 +337,57 @@ goto :EOF
:Link
echo.
echo Linking %LNKOUT%/%MAKE%.exe
echo - Linking %LNKOUT%/%MAKE%.exe
if "%COMPILER%" == "gcc" goto GccLink
if "%COMPILER%" == "tcc" goto TccLink
:: MSVC Link
echo %GUILELIBS% kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib >>%OUTDIR%\link.sc
echo on
link.exe /NOLOGO /SUBSYSTEM:console /PDB:%LNKOUT%\%MAKE%.pdb %LINKOPTS% /OUT:%LNKOUT%\%MAKE%.exe @%LNKOUT%\link.sc
if "%VERBOSE%" == "Y" echo on
call link.exe /NOLOGO /SUBSYSTEM:console /PDB:%LNKOUT%\%MAKE%.pdb %LINKOPTS% /OUT:%LNKOUT%\%MAKE%.exe @%LNKOUT%\link.sc
@echo off
goto :EOF
:GccLink
:: GCC Link
echo on
if "%VERBOSE%" == "Y" echo on
echo %GUILELIBS% -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -luuid -lodbc32 -lodbccp32 >>%OUTDIR%\link.sc
%COMPILER% -mthreads -gdwarf-2 -g3 %OPTS% -o %LNKOUT%/%MAKE%.exe @%LNKOUT%/link.sc -Wl,--out-implib=%LNKOUT%/libgnumake-1.dll.a
call %COMPILER% -mthreads -gdwarf-2 -g3 %OPTS% -o %LNKOUT%/%MAKE%.exe @%LNKOUT%/link.sc -Wl,--out-implib=%LNKOUT%/libgnumake-1.dll.a
@echo off
goto :EOF
:ConfigSCM
echo Generating config from SCM templates
sed -n "s/^AC_INIT(\[GNU make\],\[\([^]]\+\)\].*/s,%%VERSION%%,\1,g/p" configure.ac > %OUTDIR%\src\config.h.W32.sed
echo s,%%PACKAGE%%,make,g >> %OUTDIR%\src\config.h.W32.sed
sed -f %OUTDIR%\src\config.h.W32.sed src\config.h.W32.template > src\config.h.W32
echo static const char *const GUILE_module_defn = ^" \ > src\gmk-default.h
sed -e "s/;.*//" -e "/^[ \t]*$/d" -e "s/\"/\\\\\"/g" -e "s/$/ \\\/" src\gmk-default.scm >> src\gmk-default.h
echo ^";>> src\gmk-default.h
:TccLink
:: TCC Link
if "%VERBOSE%" == "Y" echo on
echo %GUILELIBS% -lkernel32 -luser32 -lgdi32 -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -lodbc32 -lodbccp32 >>%OUTDIR%\link.sc
call %COMPILER% -mthreads %OPTS% -o %LNKOUT%/%MAKE%.exe @%LNKOUT%/link.sc
@echo off
goto :EOF
:ChkGuile
:: Build with Guile is supported only on NT and later versions
if not "%OS%" == "Windows_NT" goto NoGuile
pkg-config --help > %OUTDIR%\guile.tmp 2> NUL
call pkg-config --help > %OUTDIR%\guile.tmp 2> NUL
if ERRORLEVEL 1 goto NoPkgCfg
echo Checking for Guile 2.0
set PKGMSC=
if not "%COMPILER%" == "gcc" set PKGMSC=--msvc-syntax
pkg-config --cflags --short-errors "guile-2.0" > %OUTDIR%\guile.tmp
if not ERRORLEVEL 1 set /P GUILECFLAGS= < %OUTDIR%\guile.tmp
pkg-config --libs --static --short-errors %PKGMSC% "guile-2.0" > %OUTDIR%\guile.tmp
if not ERRORLEVEL 1 set /P GUILELIBS= < %OUTDIR%\guile.tmp
echo Checking for Guile 2.0
call pkg-config --cflags --short-errors "guile-2.0" > %OUTDIR%\gl-c2.tmp 2> NUL
if not ERRORLEVEL 1 set /P GUILECFLAGS= < %OUTDIR%\gl-c2.tmp
call pkg-config --libs --static --short-errors %PKGMSC% "guile-2.0" > %OUTDIR%\gl-l2.tmp 2> NUL
if not ERRORLEVEL 1 set /P GUILELIBS= < %OUTDIR%\gl-l2.tmp
if not "%GUILECFLAGS%" == "" goto GuileDone
echo Checking for Guile 1.8
pkg-config --cflags --short-errors "guile-1.8" > %OUTDIR%\guile.tmp
if not ERRORLEVEL 1 set /P GUILECFLAGS= < %OUTDIR%\guile.tmp
call pkg-config --cflags --short-errors "guile-1.8" > %OUTDIR%\gl-c18.tmp 2> NUL
if not ERRORLEVEL 1 set /P GUILECFLAGS= < %OUTDIR%\gl-c18.tmp
pkg-config --libs --static --short-errors %PKGMSC% "guile-1.8" > %OUTDIR%\guile.tmp
if not ERRORLEVEL 1 set /P GUILELIBS= < %OUTDIR%\guile.tmp
call pkg-config --libs --static --short-errors %PKGMSC% "guile-1.8" > %OUTDIR%\gl-l18.tmp 2> NUL
if not ERRORLEVEL 1 set /P GUILELIBS= < %OUTDIR%\gl-l18.tmp
if not "%GUILECFLAGS%" == "" goto GuileDone
@@ -358,10 +406,10 @@ goto :EOF
:FindVswhere
set VSWHERE=vswhere
%VSWHERE% -help >nul 2>&1
call "%VSWHERE%" -help >nul 2>&1
if not ERRORLEVEL 1 exit /b 0
set "VSWHERE=C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere"
%VSWHERE% -help >nul 2>&1
call "%VSWHERE%" -help >nul 2>&1
if ERRORLEVEL 1 exit /b 1
goto :EOF
@@ -369,17 +417,26 @@ goto :EOF
if not exist "%VSVARS%" exit /b 1
call "%VSVARS%" %ARCH%
if ERRORLEVEL 1 exit /b 1
%COMPILER% >nul 2>&1
call %COMPILER% >nul 2>&1
if ERRORLEVEL 1 exit /b 1
goto :EOF
:NotConfig
echo.
echo *** This workspace is not configured.
echo Either retrieve the configured source in the release tarball
echo or, if building from Git, run the .\bootstrap.bat script first.
exit /b 1
:Usage
echo Usage: %0 [options] [gcc]
echo Usage: %0 [options] [gcc] OR [tcc]
echo Options:
echo. --without-guile Do not compile Guile support even if found
echo. --debug Make a Debug build--default is Release
echo. --x86 Make a 32bit binary--default is 64bit
echo. --help Display these instructions and exit
echo.
echo. "gcc" means compile with GCC, "tcc" means compile with Tiny C's TCC
goto :EOF
:Reset

View File

@@ -1,5 +1,5 @@
@echo off
rem Copyright (C) 1998-2019 Free Software Foundation, Inc.
rem Copyright (C) 1998-2022 Free Software Foundation, Inc.
rem This file is part of GNU Make.
rem
rem GNU Make is free software; you can redistribute it and/or modify it under
@@ -13,7 +13,7 @@ rem FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for.
rem more details.
rem
rem You should have received a copy of the GNU General Public License along
rem with this program. If not, see <http://www.gnu.org/licenses/>.
rem with this program. If not, see <https://www.gnu.org/licenses/>.
echo Building Make for MSDOS with DJGPP
@@ -49,14 +49,14 @@ gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/s
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/src/dir.c -o dir.o
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/src/file.c -o file.o
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/src/misc.c -o misc.o
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/src/main.c -o main.o
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -DINCLUDEDIR=\"c:/djgpp/include\" -O2 -g %XSRC%/src/read.c -o read.o
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -DLIBDIR=\"c:/djgpp/lib\" -O2 -g %XSRC%/src/remake.c -o remake.o
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -DLOCALEDIR=\"/dev/env/DJDIR/share/locale\" -O2 -g %XSRC%/src/main.c -o main.o
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -DINCLUDEDIR=\"/dev/env/DJDIR/include\" -O2 -g %XSRC%/src/read.c -o read.o
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -DLIBDIR=\"/dev/env/DJDIR/lib\" -O2 -g %XSRC%/src/remake.c -o remake.o
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/src/rule.c -o rule.o
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/src/implicit.c -o implicit.o
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/src/default.c -o default.o
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/src/variable.c -o variable.o
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/src/expand.c -o eyxpand.o
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/src/expand.c -o expand.o
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/src/function.c -o function.o
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/src/vpath.c -o vpath.o
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/src/hash.c -o hash.o
@@ -68,15 +68,17 @@ gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/s
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/src/remote-stub.c -o remote-stub.o
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/src/getopt.c -o getopt.o
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/src/getopt1.c -o getopt1.o
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/src/shuffle.c -o shuffle.o
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/src/load.c -o load.o
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/lib/glob.c -o lib/glob.o
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/lib/fnmatch.c -o lib/fnmatch.o
@echo off
echo commands.o > respf.$$$
for %%f in (job output dir file misc main read remake rule implicit default variable) do echo %%f.o >> respf.$$$
for %%f in (expand function vpath hash strcache version ar arscan signame remote-stub getopt getopt1) do echo %%f.o >> respf.$$$
for %%f in (job output dir file misc main read remake rule implicit default variable load) do echo %%f.o >> respf.$$$
for %%f in (expand function vpath hash strcache version ar arscan signame remote-stub getopt getopt1 shuffle) do echo %%f.o >> respf.$$$
for %%f in (lib\glob lib\fnmatch) do echo %%f.o >> respf.$$$
rem gcc -c -I./src -I%XSRC% -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/guile.c -o guile.o
rem echo guile.o >> respf.$$$
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/src/guile.c -o guile.o
echo guile.o >> respf.$$$
@echo Linking...
@echo on
gcc -o make.exe @respf.$$$
@@ -84,7 +86,7 @@ gcc -o make.exe @respf.$$$
if not exist make.exe echo Make.exe build failed...
if exist make.exe echo make.exe is now built!
if exist make.exe del respf.$$$
if exist make.exe copy /Y Basic.mk Makefile
if exist make.exe copy /Y %XSRC%\Basic.mk Makefile
goto End
:SmallEnv

View File

@@ -1,6 +1,6 @@
# Process this file with autoconf to produce a configure script.
#
# Copyright (C) 1993-2019 Free Software Foundation, Inc.
# Copyright (C) 1993-2022 Free Software Foundation, Inc.
# This file is part of GNU Make.
#
# GNU Make is free software; you can redistribute it and/or modify it under
@@ -14,9 +14,9 @@
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>.
# this program. If not, see <https://www.gnu.org/licenses/>.
AC_INIT([GNU make],[4.2.91],[bug-make@gnu.org])
AC_INIT([GNU Make],[4.4],[bug-make@gnu.org])
AC_PREREQ([2.69])
@@ -31,7 +31,7 @@ AC_CONFIG_LIBOBJ_DIR([lib])
# We have to enable "foreign" because ChangeLog is auto-generated
# Automake 1.15 and gnulib don't get along: gnulib has some strange error
# in the way it handles getloadavg.c which causes make distcheck to fail.
# http://lists.gnu.org/archive/html/bug-gnulib/2018-06/msg00024.html
# https://lists.gnu.org/archive/html/bug-gnulib/2018-06/msg00024.html
AM_INIT_AUTOMAKE([1.16.1 foreign -Werror -Wall])
# Checks for programs.
@@ -51,42 +51,36 @@ AC_CHECK_PROG([PERL], [perl], [perl], [perl])
# Specialized system macros
AC_CANONICAL_HOST
AC_AIX
AC_ISC_POSIX
AC_MINIX
AC_C_BIGENDIAN
# Enable gettext, in "external" mode.
AM_GNU_GETTEXT_VERSION([0.19.4])
AM_GNU_GETTEXT([external])
# This test must come as early as possible after the compiler configuration
# tests, because the choice of the file model can (in principle) affect
# whether functions and headers are available, whether they work, etc.
AC_SYS_LARGEFILE
# Checks for libraries.
AC_SEARCH_LIBS([strerror],[cposix])
AC_SEARCH_LIBS([getpwnam], [sun])
# Checks for header files.
AC_HEADER_STDC
AC_HEADER_DIRENT
AC_HEADER_STAT
AC_HEADER_TIME
AC_CHECK_HEADERS([stdlib.h locale.h unistd.h limits.h fcntl.h string.h \
memory.h sys/param.h sys/resource.h sys/time.h sys/timeb.h \
memory.h sys/param.h sys/resource.h sys/timeb.h sys/time.h \
sys/select.h sys/file.h spawn.h])
AM_PROG_CC_C_O
AC_C_CONST
AC_TYPE_SIGNAL
AC_TYPE_UID_T
AC_TYPE_PID_T
AC_TYPE_OFF_T
AC_TYPE_SIZE_T
AC_TYPE_SSIZE_T
AC_TYPE_INTMAX_T
AC_TYPE_UINTMAX_T
# Check for sig_atomic_t
gt_TYPE_SIG_ATOMIC_T
# Find out whether our struct stat returns nanosecond resolution timestamps.
AC_STRUCT_ST_MTIM_NSEC
@@ -115,9 +109,6 @@ AS_IF([test "$make_cv_file_timestamp_hi_res" = yes],
])
])
# Check for DOS-style pathnames.
pds_AC_DOS_PATHS
# See if we have a standard version of gettimeofday(). Since actual
# implementations can differ, just make sure we have the most common
# one.
@@ -127,8 +118,8 @@ AC_CACHE_CHECK([for standard gettimeofday], [ac_cv_func_gettimeofday],
int main ()
{
struct timeval t; t.tv_sec = -1; t.tv_usec = -1;
exit (gettimeofday (&t, 0) != 0
|| t.tv_sec < 0 || t.tv_usec < 0);
return gettimeofday (&t, 0) != 0
|| t.tv_sec < 0 || t.tv_usec < 0;
}]])],
[ac_cv_func_gettimeofday=yes],
[ac_cv_func_gettimeofday=no],
@@ -138,10 +129,10 @@ AS_IF([test "$ac_cv_func_gettimeofday" = yes],
[Define to 1 if you have a standard gettimeofday function])
])
AC_CHECK_FUNCS([strdup strndup umask mkstemp mktemp fdopen \
dup dup2 getcwd realpath sigsetmask sigaction \
AC_CHECK_FUNCS([strtoll strdup strndup stpcpy memrchr mempcpy umask mkstemp \
mktemp fdopen dup dup2 getcwd realpath sigsetmask sigaction \
getgroups seteuid setegid setlinebuf setreuid setregid \
getrlimit setrlimit setvbuf pipe strsignal \
mkfifo getrlimit setrlimit setvbuf pipe strerror strsignal \
lstat readlink atexit isatty ttyname pselect posix_spawn \
posix_spawnattr_setsigmask])
@@ -153,8 +144,6 @@ AC_CHECK_DECLS([bsd_signal], [], [], [[#define _GNU_SOURCE 1
AC_FUNC_FORK
AC_FUNC_SETVBUF_REVERSED
# Rumor has it that strcasecmp lives in -lresolv on some odd systems.
# It doesn't hurt much to use our own if we can't find it so I don't
# make the effort here.
@@ -176,7 +165,7 @@ AC_ARG_WITH([guile], [AS_HELP_STRING([--with-guile],
PKG_PROG_PKG_CONFIG
AS_IF([test "x$with_guile" != xno],
[ guile_versions="2.2 2.0 1.8"
[ guile_versions="3.0 2.2 2.0 1.8"
guile_version=no
have_guile=no
AC_MSG_CHECKING([for GNU Guile])
@@ -184,13 +173,41 @@ AS_IF([test "x$with_guile" != xno],
PKG_CHECK_EXISTS([guile-$v], [guile_version=$v; have_guile=yes; break], [])
done
AC_MSG_RESULT([$guile_version])
if test "$have_guile" = yes; then
PKG_CHECK_MODULES(GUILE, [guile-$guile_version])
AC_DEFINE([HAVE_GUILE], [1], [Embed GNU Guile support])
fi
AS_IF([test "$have_guile" = yes],
[ PKG_CHECK_MODULES(GUILE, [guile-$guile_version])
# Unfortunately pkg doesn't help in multi-arch environments where the
# package is installed for some architectures but not others; we need
# to try to link.
keep_CPPFLAGS="$CPPFLAGS"
keep_LIBS="$LIBS"
CPPFLAGS="$CPPFLAGS $GUILE_CFLAGS"
LIBS="$LIBS $GUILE_LIBS"
AC_CHECK_HEADER([libguile.h],
[AC_DEFINE([HAVE_GUILE], [1], [Embed GNU Guile support])],
[have_guile=no],
[/* Avoid configuration error warnings. */])
AS_IF([test "$have_guile" = yes],
[ AC_MSG_CHECKING([whether we can link GNU Guile])
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include <libguile.h>
static void *
guile_init (void *arg)
{
(void) arg;
return 0;
}
]], [[
scm_with_guile (guile_init, 0);
]])],
[have_guile=yes],
[have_guile=no])
AC_MSG_RESULT([$have_guile])])
CPPFLAGS="$keep_CPPFLAGS"
LIBS="$keep_LIBS"
])
])
AM_CONDITIONAL([HAVE_GUILE], [test "$have_guile" = yes])
AM_CONDITIONAL([HAVE_GUILE], [test "$have_guile" = "yes"])
AC_CHECK_DECLS([sys_siglist, _sys_siglist, __sys_siglist], , ,
[AC_INCLUDES_DEFAULT
@@ -243,8 +260,7 @@ AS_IF([test "$PATH_SEPARATOR" = ';'],
AC_SUBST([REMOTE]) REMOTE=stub
use_customs=false
AC_ARG_WITH([customs],
[AC_HELP_STRING([--with-customs=DIR],
[enable remote jobs via Customs--see README.customs])],
[AS_HELP_STRING([--with-customs=DIR],[enable remote jobs via Customs--see README.customs])],
[ AS_CASE([$withval], [n|no], [:],
[make_cppflags="$CPPFLAGS"
AS_CASE([$withval],
@@ -267,14 +283,12 @@ AM_CONDITIONAL([USE_CUSTOMS], [test "$use_customs" = true])
# See if the user asked to handle case insensitive file systems.
AH_TEMPLATE([HAVE_CASE_INSENSITIVE_FS], [Use case insensitive file names])
AC_ARG_ENABLE([case-insensitive-file-system],
AC_HELP_STRING([--enable-case-insensitive-file-system],
[assume file systems are case insensitive]),
AS_HELP_STRING([--enable-case-insensitive-file-system],[assume file systems are case insensitive]),
[AS_IF([test "$enableval" = yes], [AC_DEFINE([HAVE_CASE_INSENSITIVE_FS])])])
# See if we can handle the job server feature, and if the user wants it.
AC_ARG_ENABLE([job-server],
AC_HELP_STRING([--disable-job-server],
[disallow recursive make communication during -jN]),
AS_HELP_STRING([--disable-job-server],[disallow recursive make communication during -jN]),
[make_cv_job_server="$enableval" user_job_server="$enableval"],
[make_cv_job_server="yes"])
@@ -312,8 +326,7 @@ AC_CHECK_DECLS([dlopen, dlsym, dlerror], [], [],
[[#include <dlfcn.h>]])
AC_ARG_ENABLE([load],
AC_HELP_STRING([--disable-load],
[disable support for the 'load' operation]),
AS_HELP_STRING([--disable-load],[disable support for the 'load' operation]),
[make_cv_load="$enableval" user_load="$enableval"],
[make_cv_load="yes"])
@@ -363,15 +376,31 @@ AS_IF([test "$ac_cv_func_lstat" = yes && test "$ac_cv_func_readlink" = yes],
# Use posix_spawn if we have support and the user didn't disable it
AC_ARG_ENABLE([posix-spawn],
AC_HELP_STRING([--disable-posix-spawn],
[disable support for posix_spawn()]),
AS_HELP_STRING([--disable-posix-spawn],[disable support for posix_spawn()]),
[make_cv_posix_spawn="$enableval" user_posix_spawn="$enableval"],
[make_cv_posix_spawn="yes"])
AS_CASE([/$ac_cv_header_spawn/$ac_cv_func_posix_spawn/],
[*/no/*], [make_cv_posix_spawn=no])
AS_CASE([/$make_cv_posix_spawn/$user_posix_spawn/],
AS_IF([test "$make_cv_posix_spawn" = yes],
AC_CACHE_CHECK([for posix_spawn that fails synchronously],
[make_cv_synchronous_posix_spawn],
[make_cv_synchronous_posix_spawn=no
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <errno.h>
#include <spawn.h>
extern char **environ;
int main () {
char path[[]] = "./xxx-non-existent";
char *argv[[]] = {path, 0};
return posix_spawn (0, path, 0, 0, argv, environ) == ENOENT ? 0 : 1;
}]])],
[make_cv_synchronous_posix_spawn=yes],
[make_cv_synchronous_posix_spawn=no],
[make_cv_synchronous_posix_spawn="no (cross-compiling)"])]))
AS_CASE([/$user_posix_spawn/$make_cv_posix_spawn/$make_cv_synchronous_posix_spawn/],
[*/no/*], [make_cv_posix_spawn=no],
[AC_DEFINE(USE_POSIX_SPAWN, 1, [Define to 1 to use posix_spawn().])
])
@@ -416,13 +445,21 @@ AS_CASE([$host],
[*-*-mingw32],
[AM_CONDITIONAL([WINDOWSENV], [true])
w32_target_env=yes
AC_DEFINE([WINDOWS32], [1], [Use platform specific coding])
AC_DEFINE([HAVE_DOS_PATHS], [1], [Use platform specific coding])
AC_DEFINE([WINDOWS32], [1], [Build for the WINDOWS32 API.])
AC_DEFINE([HAVE_DOS_PATHS], [1], [Support DOS-style pathnames.])
])
AC_DEFINE_UNQUOTED([PATH_SEPARATOR_CHAR],['$PATH_SEPARATOR'],
[Define to the character that separates directories in PATH.])
AC_DEFINE_UNQUOTED([HAVE_DECL_GETLOADAVG],[$HAVE_DECL_GETLOADAVG],
[Define to 1 if you have the declaration of 'getloadavg'.])
# Remember that we ran configure to generate config.h
AC_DEFINE([MK_CONFIGURE], [1],
[Define to 1 if config.h is generated by running the configure script.])
# Include the Maintainer's Makefile section, if it's here.
MAINT_MAKEFILE=/dev/null
@@ -491,12 +528,20 @@ AS_IF([test "x$make_cv_posix_spawn" = xno && test "x$user_posix_spawn" = xyes],
echo
])
# autoconf initializes $prefix to NONE.
AM_CONDITIONAL([KNOWN_PREFIX],
[test "x$prefix" = xNONE -o "x$prefix" = x/usr/local \
-o "x$prefix" = x/usr/gnu -o "x$prefix" = x/usr])
# Specify what files are to be created.
AC_CONFIG_FILES([Makefile build.cfg lib/Makefile po/Makefile.in doc/Makefile \
tests/config-flags.pm])
AC_CONFIG_FILES([build.cfg tests/config-flags.pm \
Makefile lib/Makefile doc/Makefile po/Makefile.in])
# We don't need this: the standard automake output suffices for POSIX systems.
#mk/Posix.mk
# Put build.sh in the build directory so it's easy to find
AC_CONFIG_LINKS([build.sh:build.sh])
# OK, do it!
AC_OUTPUT

View File

@@ -1,5 +1,5 @@
# -*-Makefile-*-, or close enough
# Copyright (C) 2000-2019 Free Software Foundation, Inc.
# Copyright (C) 2000-2022 Free Software Foundation, Inc.
# This file is part of GNU Make.
#
# GNU Make is free software; you can redistribute it and/or modify it under
@@ -13,7 +13,7 @@
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>.
# this program. If not, see <https://www.gnu.org/licenses/>.
TEXI2HTML = texi2html
TEXI2HTML_FLAGS = -split_chapter

View File

@@ -1,4 +1,4 @@
.TH MAKE 1 "28 February 2016" "GNU" "User Commands"
.TH MAKE 1 "31 May 2022" "GNU" "User Commands"
.SH NAME
make \- GNU make utility to maintain groups of programs
.SH SYNOPSIS
@@ -26,9 +26,9 @@ To prepare to use
.BR make ,
you must write a file called the
.I makefile
that describes the relationships among files in your program, and the states
the commands for updating each file. In a program, typically the executable
file is updated from object files, which are in turn made by compiling source
that describes the relationships among files in your program, and provides
commands for updating each file. In a program, typically the executable file
is updated from object files, which are in turn made by compiling source
files.
.LP
Once a suitable makefile exists, each time you change some source files,
@@ -48,10 +48,10 @@ files, it issues the commands recorded in the makefile.
.B make
executes commands in the
.I makefile
to update one or more target
.IR names ,
to update one or more
.IR targets ,
where
.I name
.I target
is typically a program.
If no
.B \-f
@@ -130,21 +130,28 @@ are omitted, then the behavior is the same as if
.B \-d
was specified.
.I FLAGS
may be
.I a
may be any or all of the following names, comma- or space-separated. Only the
first character is significant: the rest may be omitted:
.I all
for all debugging output (same as using
.BR \-d ),
.I b
.I basic
for basic debugging,
.I v
.I verbose
for more verbose basic debugging,
.I i
for showing implicit rules,
.I j
for details on invocation of commands, and
.I m
for debugging while remaking makefiles. Use
.I n
.I implicit
for showing implicit rule search operations,
.I jobs
for details on invocation of commands,
.I makefile
for debugging while remaking makefiles,
.I print
shows all recipes that are run even if they are silent, and
.I why
shows the reason
.BR make
decided to rebuild each target. Use
.I none
to disable all previous debugging flags.
.TP 0.5i
\fB\-e\fR, \fB\-\-environment\-overrides\fR
@@ -198,6 +205,16 @@ option is given without an argument,
.BR make
will not limit the number of jobs that can run simultaneously.
.TP 0.5i
\fB\--jobserver-style=\fR\fIstyle\fR
The style of jobserver to use. The
.I style
may be one of
.BR fifo ,
.BR pipe ,
or
.B sem
(Windows only).
.TP 0.5i
\fB\-k\fR, \fB\-\-keep\-going\fR
Continue as much as possible after an error.
While the target that failed, and those that depend on it, cannot
@@ -312,6 +329,26 @@ Turn off
.BR \-w ,
even if it was turned on implicitly.
.TP 0.5i
.BI \-\-shuffle "[=MODE]"
Enable shuffling of goal and prerequisite ordering.
.I MODE
is one of
.I none
to disable shuffle mode,
.I random
to shuffle prerequisites in random order,
.I reverse
to consider prerequisites in reverse order, or an integer
.I <seed>
which enables
.I random
mode with a specific
.I seed
value. If
.I MODE
is omitted the default is
.IR random .
.TP 0.5i
\fB\-W\fR \fIfile\fR, \fB\-\-what\-if\fR=\fIfile\fR, \fB\-\-new\-file\fR=\fIfile\fR, \fB\-\-assume\-new\fR=\fIfile\fR
Pretend that the target
.I file
@@ -361,7 +398,7 @@ This manual page contributed by Dennis Morse of Stanford University.
Further updates contributed by Mike Frysinger. It has been reworked by Roland
McGrath. Maintained by Paul Smith.
.SH "COPYRIGHT"
Copyright \(co 1992-1993, 1996-2019 Free Software Foundation, Inc.
Copyright \(co 1992-1993, 1996-2022 Free Software Foundation, Inc.
This file is part of
.IR "GNU make" .
.LP
@@ -376,4 +413,4 @@ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
.LP
You should have received a copy of the GNU General Public License along with
this program. If not, see
.IR http://www.gnu.org/licenses/ .
.IR https://www.gnu.org/licenses/ .

File diff suppressed because it is too large Load Diff

10
gl/.gitignore vendored Normal file
View File

@@ -0,0 +1,10 @@
*~
#*
.#*
.*cache
*.diff
*.patch
*.orig
*.rej
*.out
*.log

65
gl/README Normal file
View File

@@ -0,0 +1,65 @@
04 July 2022 -*-text-*-
The gnulib project provides a fantastic array of modules that can support both
POSIX and also extended features for GNU software.
Unfortunately using it in GNU make is problematic: GNU make is a foundational
utility (if you don't have a "make" program you pretty much can't build any
software), one of our goals in GNU make is to provide scripts (e.g.,
"build.sh") that will build GNU make without needing an instance of make.
Instead of running "./configure && make", you should be able to run
"./configure && ./build.sh" and get a build of GNU make as a result.
However, more and more gnulib modules are relying not on M4 macros and
the configure script to manage their configuration, but in addition special
makefile recipes that perform various post-configure operations. Since we
don't have an instance of "make", we cannot use these modules as-is.
There are various options we could choose for solving this:
- Avoid gnulib modules and write our own portability interfaces.
I really am not too excited about this.
- Give up on "build.sh" and require users to already have "make".
The argument here is that you must already have a compiler, and it couldn't
have been built without "make", and/or if you build it with a cross-compiler
then you should be able to use that cross-development environment to build
GNU make as well.
- Provide a "mini-make" with just enough functionality to support the gnulib
makefiles but no extra features, that didn't need any complex gnulib
modules. As with the first option, I'm not too excited about this.
Although arguably the second option is the sane one, I'm not really excited
about any of them for the time being. So I elected to try something between
the first and second options:
The gnulib-port Git branch will contain unmodified copies of gnulib modules
that we want to use with GNU make. From there, we merge them into the main
Git branch then modify / simplify them to avoid unnecessary extra modules and
allow "build.sh" to be used.
By keeping the unmodified versions on the gnulib-port branch, we enable Git
merge facilities to merge in new versions as follows:
* Check out the gnulib-port branch
* Update its content with any updates to gnulib modules. Something like:
(
cd gl \
&& find */. -type f \
| while read fn; do
test -f "$GNULIB_SRCDIR/$fn" && cp "$GNULIB_SRCDIR/$fn" "$fn"
done
)
* Commit the changes _without modification_
* Check out the main branch
* Run "git merge --no-ff gnulib-port" to merge in the changes
* Resolve any conflicts and commit the merge.
-- pds

View File

@@ -1,7 +1,7 @@
dnl acinclude.m4 -- Extra macros needed for GNU make.
dnl
dnl Automake will incorporate this into its generated aclocal.m4.
dnl Copyright (C) 1998-2019 Free Software Foundation, Inc.
dnl Copyright (C) 1998-2022 Free Software Foundation, Inc.
dnl This file is part of GNU Make.
dnl
dnl GNU Make is free software; you can redistribute it and/or modify it under
@@ -15,7 +15,7 @@ dnl FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for.
dnl more details.
dnl
dnl You should have received a copy of the GNU General Public License along
dnl with this program. If not, see <http://www.gnu.org/licenses/>.
dnl with this program. If not, see <https://www.gnu.org/licenses/>.
dnl ---------------------------------------------------------------------------
dnl Got this from the lynx 2.8 distribution.

View File

@@ -1,7 +1,7 @@
# Test if the system uses DOS-style pathnames (drive specs and backslashes)
# By Paul Smith <psmith@gnu.org>. Based on dos.m4 by Jim Meyering.
#
# Copyright (C) 1993-2019 Free Software Foundation, Inc.
# Copyright (C) 1993-2022 Free Software Foundation, Inc.
# This file is part of GNU Make.
#
# GNU Make is free software; you can redistribute it and/or modify it under
@@ -15,7 +15,7 @@
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>.
# this program. If not, see <https://www.gnu.org/licenses/>.
AC_DEFUN([pds_AC_DOS_PATHS], [
AC_CACHE_CHECK([whether system uses MSDOS-style paths], [ac_cv_dos_paths], [

216
gl/m4/getloadavg.m4 Normal file
View File

@@ -0,0 +1,216 @@
# Check for getloadavg.
# Copyright (C) 1992-1996, 1999-2000, 2002-2003, 2006, 2008-2022 Free Software
# Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
#serial 10
# Autoconf defines AC_FUNC_GETLOADAVG, but that is obsolescent.
# New applications should use gl_GETLOADAVG instead.
# gl_GETLOADAVG
# -------------
AC_DEFUN([gl_GETLOADAVG],
[AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
# Persuade glibc <stdlib.h> to declare getloadavg().
AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
gl_save_LIBS=$LIBS
# getloadavg is present in libc on glibc >= 2.2, Mac OS X, FreeBSD >= 2.0,
# NetBSD >= 0.9, OpenBSD >= 2.0, Solaris >= 7.
HAVE_GETLOADAVG=1
AC_CHECK_FUNC([getloadavg], [],
[gl_func_getloadavg_done=no
# Some systems with -lutil have (and need) -lkvm as well, some do not.
# On Solaris, -lkvm requires nlist from -lelf, so check that first
# to get the right answer into the cache.
# For kstat on solaris, we need to test for libelf and libkvm to force the
# definition of SVR4 below.
if test $gl_func_getloadavg_done = no; then
AC_CHECK_LIB([elf], [elf_begin], [LIBS="-lelf $LIBS"])
AC_CHECK_LIB([kvm], [kvm_open], [LIBS="-lkvm $LIBS"])
# Check for the 4.4BSD definition of getloadavg.
AC_CHECK_LIB([util], [getloadavg],
[LIBS="-lutil $LIBS" gl_func_getloadavg_done=yes])
fi
if test $gl_func_getloadavg_done = no; then
# There is a commonly available library for RS/6000 AIX.
# Since it is not a standard part of AIX, it might be installed locally.
gl_getloadavg_LIBS=$LIBS
if test $cross_compiling != yes; then
LIBS="-L/usr/local/lib $LIBS"
fi
AC_CHECK_LIB([getloadavg], [getloadavg],
[LIBS="-lgetloadavg $LIBS" gl_func_getloadavg_done=yes],
[LIBS=$gl_getloadavg_LIBS])
fi
# Set up the replacement function if necessary.
if test $gl_func_getloadavg_done = no; then
HAVE_GETLOADAVG=0
# Solaris has libkstat which does not require root.
AC_CHECK_LIB([kstat], [kstat_open])
test $ac_cv_lib_kstat_kstat_open = yes && gl_func_getloadavg_done=yes
# AIX has libperfstat which does not require root
if test $gl_func_getloadavg_done = no; then
AC_CHECK_LIB([perfstat], [perfstat_cpu_total])
test $ac_cv_lib_perfstat_perfstat_cpu_total = yes && gl_func_getloadavg_done=yes
fi
if test $gl_func_getloadavg_done = no; then
AC_CHECK_HEADER([sys/dg_sys_info.h],
[gl_func_getloadavg_done=yes
AC_DEFINE([DGUX], [1], [Define to 1 for DGUX with <sys/dg_sys_info.h>.])
AC_CHECK_LIB([dgc], [dg_sys_info])])
fi
fi])
if test "x$gl_save_LIBS" = x; then
GETLOADAVG_LIBS=$LIBS
else
GETLOADAVG_LIBS=`echo "$LIBS" | sed "s!$gl_save_LIBS!!"`
fi
LIBS=$gl_save_LIBS
AC_SUBST([GETLOADAVG_LIBS])dnl
# Test whether the system declares getloadavg. Solaris has the function
# but declares it in <sys/loadavg.h>, not <stdlib.h>.
AC_CHECK_HEADERS([sys/loadavg.h])
if test $ac_cv_header_sys_loadavg_h = yes; then
HAVE_SYS_LOADAVG_H=1
else
HAVE_SYS_LOADAVG_H=0
fi
AC_CHECK_DECL([getloadavg], [], [HAVE_DECL_GETLOADAVG=0],
[[#if HAVE_SYS_LOADAVG_H
/* OpenIndiana has a bug: <sys/time.h> must be included before
<sys/loadavg.h>. */
# include <sys/time.h>
# include <sys/loadavg.h>
#endif
#include <stdlib.h>]])
])# gl_GETLOADAVG
# gl_PREREQ_GETLOADAVG
# --------------------
# Set up the AC_LIBOBJ replacement of 'getloadavg'.
AC_DEFUN([gl_PREREQ_GETLOADAVG],
[
# Figure out what our getloadavg.c needs.
AC_CHECK_HEADERS_ONCE([sys/param.h unistd.h])
# On HPUX9, an unprivileged user can get load averages this way.
if test $gl_func_getloadavg_done = no; then
AC_CHECK_FUNCS([pstat_getdynamic], [gl_func_getloadavg_done=yes])
fi
# We cannot check for <dwarf.h>, because Solaris 2 does not use dwarf (it
# uses stabs), but it is still SVR4. We cannot check for <elf.h> because
# Irix 4.0.5F has the header but not the library.
if test $gl_func_getloadavg_done = no && test "$ac_cv_lib_elf_elf_begin" = yes \
&& test "$ac_cv_lib_kvm_kvm_open" = yes; then
gl_func_getloadavg_done=yes
AC_DEFINE([SVR4], [1], [Define to 1 on System V Release 4.])
fi
if test $gl_func_getloadavg_done = no; then
AC_CHECK_HEADER([inq_stats/cpustats.h],
[gl_func_getloadavg_done=yes
AC_DEFINE([UMAX], [1], [Define to 1 for Encore UMAX.])
AC_DEFINE([UMAX4_3], [1],
[Define to 1 for Encore UMAX 4.3 that has <inq_status/cpustats.h>
instead of <sys/cpustats.h>.])])
fi
if test $gl_func_getloadavg_done = no; then
AC_CHECK_HEADER([sys/cpustats.h],
[gl_func_getloadavg_done=yes; AC_DEFINE([UMAX])])
fi
if test $gl_func_getloadavg_done = no; then
AC_CHECK_HEADERS([mach/mach.h])
fi
AC_CHECK_HEADERS([nlist.h],
[AC_CHECK_MEMBERS([struct nlist.n_un.n_name],
[], [],
[#include <nlist.h>])
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <nlist.h>]],
[[struct nlist x;
#ifdef HAVE_STRUCT_NLIST_N_UN_N_NAME
x.n_un.n_name = "";
#else
x.n_name = "";
#endif]])],
[AC_DEFINE([N_NAME_POINTER], [1],
[Define to 1 if the nlist n_name member is a pointer])])
])dnl
])# gl_PREREQ_GETLOADAVG
# ---- GNU make
# These macros are imported from stdlib which we don't want to include
# Only the getloadavg content is imported.
AC_DEFUN_ONCE([gl_STDLIB_H],
[
AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
dnl Check for declarations of anything we want to poison if the
dnl corresponding gnulib module is not in use, and which is not
dnl guaranteed by C89.
gl_WARN_ON_USE_PREPARE([[#include <stdlib.h>
#if HAVE_SYS_LOADAVG_H
/* OpenIndiana has a bug: <sys/time.h> must be included before
<sys/loadavg.h>. */
# include <sys/time.h>
# include <sys/loadavg.h>
#endif
#if HAVE_RANDOM_H
# include <random.h>
#endif
]], [getloadavg])
])
# gl_STDLIB_MODULE_INDICATOR([modulename])
# sets the shell variable that indicates the presence of the given module
# to a C preprocessor expression that will evaluate to 1.
# This macro invocation must not occur in macros that are AC_REQUIREd.
AC_DEFUN([gl_STDLIB_MODULE_INDICATOR],
[
dnl Ensure to expand the default settings once only.
gl_STDLIB_H_REQUIRE_DEFAULTS
gl_MODULE_INDICATOR_SET_VARIABLE([$1])
dnl Define it also as a C macro, for the benefit of the unit tests.
gl_MODULE_INDICATOR_FOR_TESTS([$1])
])
# Initializes the default values for AC_SUBSTed shell variables.
# This macro must not be AC_REQUIREd. It must only be invoked, and only
# outside of macros or in macros that are not AC_REQUIREd.
AC_DEFUN([gl_STDLIB_H_REQUIRE_DEFAULTS],
[
m4_defun(GL_MODULE_INDICATOR_PREFIX[_STDLIB_H_MODULE_INDICATOR_DEFAULTS], [
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETLOADAVG])
])
m4_require(GL_MODULE_INDICATOR_PREFIX[_STDLIB_H_MODULE_INDICATOR_DEFAULTS])
AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
])
AC_DEFUN([gl_STDLIB_H_DEFAULTS],
[
dnl Assume proper GNU behavior unless another module says otherwise.
HAVE_DECL_GETLOADAVG=1; AC_SUBST([HAVE_DECL_GETLOADAVG])
])

View File

@@ -0,0 +1,24 @@
Description:
Construct a full filename by concatenating a directory name, a relative
filename, and a suffix.
Files:
lib/concat-filename.h
lib/concat-filename.c
Depends-on:
filename
configure.ac:
Makefile.am:
lib_SOURCES += concat-filename.c
Include:
"concat-filename.h"
License:
LGPLv2+
Maintainer:
all

28
gl/modules/findprog-in Normal file
View File

@@ -0,0 +1,28 @@
Description:
Locating a program in a given path.
Files:
lib/findprog.h
lib/findprog-in.c
m4/findprog-in.m4
m4/eaccess.m4
Depends-on:
stdbool
filename
concat-filename
configure.ac:
gl_FINDPROG_IN
Makefile.am:
lib_SOURCES += findprog.h findprog-in.c
Include:
"findprog.h"
License:
LGPLv2+
Maintainer:
all

40
gl/modules/getloadavg Normal file
View File

@@ -0,0 +1,40 @@
Description:
Return the current system load averages.
Files:
lib/getloadavg.c
m4/getloadavg.m4
Depends-on:
snippet/warn-on-use
extensions
intprops [test $HAVE_GETLOADAVG = 0]
stdbool [test $HAVE_GETLOADAVG = 0]
configure.ac:
gl_STDLIB_H
gl_STDLIB_H_REQUIRE_DEFAULTS
AC_REQUIRE([AC_CANONICAL_HOST])
gl_GETLOADAVG
gl_CONDITIONAL([GL_COND_OBJ_GETLOADAVG], [test $HAVE_GETLOADAVG = 0])
AM_COND_IF([GL_COND_OBJ_GETLOADAVG], [
gl_PREREQ_GETLOADAVG
])
gl_STDLIB_MODULE_INDICATOR([getloadavg])
Makefile.am:
if GL_COND_OBJ_GETLOADAVG
lib_SOURCES += getloadavg.c
endif
Include:
<stdlib.h>
Link:
$(GETLOADAVG_LIBS)
License:
GPL
Maintainer:
Jim Meyering

View File

@@ -2,6 +2,11 @@ Description:
GNU make version of fnmatch()/glob() functions. This is a holdover from
a very old version of the globbing library.
Files:
lib/fnmatch.c
lib/fnmatch.in.h
lib/glob.c
lib/glob.in.h
configure.ac:
# Check the system to see if it provides GNU glob. If not, use our
@@ -28,7 +33,6 @@ AM_CONDITIONAL([USE_SYSTEM_GLOB], [test "$make_cv_sys_gnu_glob" = yes])
USE_SYSTEM_GLOB="$make_cv_sys_gnu_glob"
AC_SUBST([USE_SYSTEM_GLOB])
Makefile.am:
if !USE_SYSTEM_GLOB
libgnu_a_SOURCES += fnmatch.c
@@ -60,7 +64,6 @@ endif
EXTRA_DIST += fnmatch.in.h glob.in.h
Include:
<glob.h>

16
gl/modules/make-macros Normal file
View File

@@ -0,0 +1,16 @@
Description:
Install m4 macros for GNU make.
Files:
m4/acinclude.m4
m4/dospaths.m4
configure.ac:
# Check for DOS-style pathnames.
pds_AC_DOS_PATHS
License:
GPLv3+
Maintainer:
gnumake

11
lib/.gitignore vendored
View File

@@ -1,11 +0,0 @@
*
!/.gitignore
!/fnmatch.c
!/fnmatch.in.h
/fnmatch.h
!/glob.c
!/glob.in.h
/glob.h

5
m4/.gitignore vendored
View File

@@ -1,5 +0,0 @@
*
!/.gitignore
!/aclocal.m4
!/dospaths.m4

View File

@@ -17,15 +17,15 @@ GPG_KEYID := 80CB727A20C79BB2
# SRCROOTDIR is just a handy location to keep source files in
SRCROOTDIR ?= $(HOME)/src
# Where the gnulib project has been locally cloned
GNULIBDIR ?= $(SRCROOTDIR)/gnulib
# Where to put the CVS checkout of the GNU web repository
GNUWEBDIR ?= $(SRCROOTDIR)/gnu-www
# Where to put the CVS checkout of the GNU make web repository
MAKEWEBDIR ?= $(SRCROOTDIR)/make/make-web
# Enable Perl warnings for the test suite
PERLFLAGS := -w
# We like mondo-warnings!
# Also force comments to be preserved. This helps when using ccache, in
# combination with GCC 7's implicit-fallthrough warning.
@@ -43,31 +43,28 @@ GUILE_CFLAGS := $(patsubst -I%,-isystem %,$(GUILE_CFLAGS))
MAKE_MAINTAINER_MODE := -DMAKE_MAINTAINER_MODE
AM_CPPFLAGS += $(MAKE_MAINTAINER_MODE)
TEMPLATES = README README.DOS README.W32 README.OS2 \
src/config.ami src/configh.dos src/config.h.W32 src/config.h-vms
all: $(TEMPLATES)
# Create preprocessor output files--GCC specific!
%.i : %.c
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) -E -dD -o $@ $<
# General rule for turning a .template into a regular file.
#
$(TEMPLATES) : % : %.template Makefile
rm -f $@
sed -e 's@%VERSION%@$(VERSION)@g' \
-e 's@%PACKAGE%@$(PACKAGE)@g' \
$< > $@
chmod a-w $@
# Create the mkconfig.h file for non-POSIX config headers
all: src/mkconfig.h
src/mkconfig.h: src/mkconfig.h.in config.status
./config.status --header=$@
# Build the README
all: README
README : README.in config.status
./config.status --file=$@
# Construct Makefiles by adding on dependencies, etc.
#
cvt = $(patsubst $1/%,$$($1)%,$(filter %.c,$2))
Basic.mk: Basic.mk.template .dep_segment Makefile
rm -f $@
sed -e 's@%VERSION%@$(VERSION)@g' \
-e 's@%make_SOURCES%@$(call cvt,src,$(make_SRCS))@g' \
sed -e 's@%make_SOURCES%@$(call cvt,src,$(make_SRCS))@g' \
-e 's@%w32_SOURCES%@$(call cvt,src,$(w32_SRCS))@g' \
-e 's@%vms_SOURCES%@$(call cvt,src,$(vms_SRCS))@g' \
-e 's@%amiga_SOURCES%@$(call cvt,src,$(amiga_SRCS))@g' \
@@ -76,12 +73,12 @@ Basic.mk: Basic.mk.template .dep_segment Makefile
-e 's@%glob_SOURCES%@$(call cvt,lib,$(glob_SRCS))@g' \
$< > $@
echo >>$@; echo '# --------------- DEPENDENCIES' >>$@; echo '#' >>$@; \
echo >>$@; echo '$$(OBJECTS): $$(SRCDIR)/src/mkconfig.h' >>$@; \
sed -e 's@^\([^ ]*\)\.o:@$$(OUTDIR)\1.$$(OBJEXT):@' \
-e 's@\([^ ]*\.[ch]\)@$$(SRCDIR)/\1@g' \
-e 's@$$(SRCDIR)/src/config.h@$$(OUTDIR)src/config.h@g' \
-e 's@$$(SRCDIR)/lib/stdlib.h@@g' \
-e 's@$$(SRCDIR)/lib/sys/types.h@@g' \
-e 's@$$(SRCDIR)/lib/unistd.h@@g' \
-e 's@$$(SRCDIR)/lib/alloca.h@@g' \
-e 's@$$(SRCDIR)/lib/stdbool.h@@g' \
$(word 2,$^) >>$@
chmod a-w $@
@@ -116,13 +113,16 @@ GIT := git
git-clean:
-$(GIT) clean -fdX
git-very-clean: git-clean
-$(GIT) clean -fd
-$(GIT) clean -fdx
## ---------------------- ##
## Generating ChangeLog. ##
## ---------------------- ##
# Where the gnulib project has been locally cloned
GNULIBDIR ?= $(or $(wildcard $(GNULIB_SRCDIR)),./gnulib)
gl2cl-date := 2013-10-10
gl2cl := $(GNULIBDIR)/build-aux/gitlog-to-changelog
@@ -134,12 +134,13 @@ ChangeLog: .check-git-HEAD
echo "WARNING: $(gl2cl) is not available. No $@ generated."; \
fi
.PHONY: .check-git-HEAD
.check-git-HEAD:
.check-git-HEAD: FORCE
sha="`git rev-parse HEAD`"; \
[ -f '$@' ] && [ "`cat '$@' 2>/dev/null`" = "$$sha" ] \
test -f '$@' && [ "`cat '$@' 2>/dev/null`" = "$$sha" ] \
|| echo "$$sha" > '$@'
.PHONY: FORCE
FORCE:;@:
## ---------------- ##
## Updating files. ##
@@ -165,16 +166,15 @@ update: po-check
# PO archive mirrors --- Be careful; some might not be fully populated!
# ftp://ftp.unex.es/pub/gnu-i18n/po/maint/
# http://translation.sf.net/maint/
# ftp://tiger.informatik.hu-berlin.de/pub/po/maint/
po_wget_flags = --recursive --level=1 --no-directories --no-check-certificate
po_wget_flags = --recursive --level=1 --no-directories --no-check-certificate
po_repo = https://translationproject.org/latest/$(PACKAGE)
po_sync = translationproject.org::tp/latest/$(PACKAGE)/
.PHONY: do-po-update po-update
do-po-update:
tmppo="/tmp/po-$(PACKAGE)-$(VERSION).$$$$" \
tmppo="/tmp/po-$(PACKAGE)-$(PACKAGE_VERSION).$$$$" \
&& rm -rf "$$tmppo" \
&& mkdir "$$tmppo" \
&& $(RSYNC) $(po_sync) "$$tmppo" \
@@ -184,7 +184,7 @@ do-po-update:
$(MAKE) po-check
po-update:
[ -d "po" ] && $(MAKE) do-po-update
test -d "po" && $(MAKE) do-po-update
# -------------------------- #
# Updating GNU build files. #
@@ -207,36 +207,86 @@ target = $(patsubst get-%,%,$@)
config-url = $(git-url)/config.git/plain/$(patsubst get-build-aux/%,%,$@)
get-build-aux/config.guess get-build-aux/config.sub:
@echo $(WGET) $(config-url) -O $(target) \
&& $(WGET) $(config-url) -O $(target).t \
@echo Retrieving $(target) from $(config-url)
$(WGET) $(config-url) -O $(target).t \
&& $(move_if_change)
gnulib-url = $(git-url)/gnulib.git/plain/build-aux/$(patsubst get-build-aux/%,%,$@)
get-build-aux/texinfo.tex:
@echo $(WGET) $(gnulib-url) -O $(target) \
&& $(WGET) $(gnulib-url) -O $(target).t \
@echo Retrieving $(target) from $(gnulib-url)
$(WGET) $(gnulib-url) -O $(target).t \
&& $(move_if_change)
gnustandards-url = $(cvs-url)/gnustandards/gnustandards/$(patsubst get-doc/%,%,$@)
get-doc/make-stds.texi get-doc/fdl.texi:
@echo $(WGET) $(gnustandards-url) -O $(target) \
&& $(WGET) $(gnustandards-url) -O $(target).t \
@echo Retrieving $(target) from $(gnustandards-url)
$(WGET) $(gnustandards-url) -O $(target).t \
&& $(move_if_change)
# ---------------------------- #
# Extra configuration checks. #
# ---------------------------- #
# Make the dist file contents more regular, if we're using GNU tar.
# Suggested by Tzvetelin Katchov <katchov@gnu.org>
export TAR_OPTIONS := --mode=u+w,go-w --owner=0 --group=0 --numeric-owner --sort=name
# When I released 4.3 somehow the INSTALL file was missing.
# When I tried to build it again, it was there. I have no idea what happened
# but add a new check to be sure it doesn't happen again.
mk_dist_files = AUTHORS ChangeLog COPYING INSTALL README src/mkconfig.h
dist: mk-distcheck
.PHONY: mk-distcheck
mk-distcheck: distdir
@echo "Checking for extra installed files..."
for fn in $(mk_dist_files); do \
test -f '$(distdir)'/"$$fn" \
|| { echo "Missing dist file: $$fn"; exit 1; }; \
done; true
# ---------------------------------- #
# Alternative configuration checks. #
# ---------------------------------- #
CFGCHECK_CONFIGFLAGS =
CFGCHECK_BUILDFLAGS =
# We can't use our mondo warnings as these are used to compile gnulib modules
# as well, and that will fail.
CFGCHECK_MAKEFLAGS = # CFLAGS='$(AM_CFLAGS)'
# We don't support C90 anymore, strictly, but this test still works (with lots
# of warnings) and it helps us avoid egregious incompatibilities.
checkcfg.strict-c90: CFGCHECK_CONFIGFLAGS = CFLAGS='-std=c90 -pedantic'
checkcfg.strict-c90: CFGCHECK_MAKEFLAGS =
checkcfg.no-jobserver:CFGCHECK_CONFIGFLAGS = --disable-job-server
checkcfg.no-load: CFGCHECK_CONFIGFLAGS = --disable-load
checkcfg.no-guile: CFGCHECK_CONFIGFLAGS = --without-guile
checkcfg.no-spawn: CFGCHECK_CONFIGFLAGS = --disable-posix-spawn
checkcfg.no-sysglob: CFGCHECK_CONFIGFLAGS = make_cv_sys_gnu_glob=no
checkcfg.no-loadavg: CFGCHECK_CONFIGFLAGS = ac_cv_func_getloadavg=no \
ac_cv_have_decl_getloadavg=no \
gl_cv_have_raw_decl_getloadavg=no \
ac_cv_lib_util_getloadavg=no \
ac_cv_lib_getloadavg_getloadavg=no
checkcfg.no-sync: CFGCHECK_CONFIGFLAGS = CPPFLAGS=-DNO_OUTPUT_SYNC
checkcfg.no-archives: CFGCHECK_CONFIGFLAGS = CPPFLAGS=-DNO_ARCHIVES
CONFIG_CHECKS := \
checkcfg.--disable-job-server \
checkcfg.--disable-load \
checkcfg.--without-guile \
checkcfg.--disable-posix-spawn \
checkcfg.make_cv_sys_gnu_glob^no \
checkcfg.ac_cv_func_getloadavg^no+ac_cv_have_decl_getloadavg^no+gl_cv_have_raw_decl_getloadavg^no+ac_cv_lib_util_getloadavg^no+ac_cv_lib_getloadavg_getloadavg^no \
checkcfg.CPPFLAGS^-DNO_OUTPUT_SYNC \
checkcfg.CPPFLAGS^-DNO_ARCHIVES
checkcfg.strict-c90 \
checkcfg.no-jobserver \
checkcfg.no-load \
checkcfg.no-guile \
checkcfg.no-spawn \
checkcfg.no-sysglob \
checkcfg.no-loadavg \
checkcfg.no-sync \
checkcfg.no-archives
.PHONY: check-alt-config
check-alt-config: $(CONFIG_CHECKS)
@@ -245,25 +295,29 @@ check-alt-config: $(CONFIG_CHECKS)
NR_MAKE = $(MAKE)
# Check builds both with build.sh and with make
build.sh_SCRIPT = exec >>'checkcfg.$*.log' 2>&1; set -x; \
cd $(distdir)/_build \
&& OUTDIR=_bld ../build.sh -k $(CFGCHECK_BUILD_FLAGS) \
&& _bld/make GMK_OUTDIR=../_bld $(AM_MAKEFLAGS) check-local \
&& _bld/make GMK_OUTDIR=../_bld $(AM_MAKEFLAGS) clean
nrmake_SCRIPT = exec >>'checkcfg.$*.log' 2>&1; set -x; \
cd $(distdir)/_build \
&& $(NR_MAKE) $(AM_MAKEFLAGS) $(CFGCHECK_MAKEFLAGS) \
&& ./make $(AM_MAKEFLAGS) check \
&& ./make $(AM_MAKEFLAGS) clean
$(CONFIG_CHECKS): checkcfg.%: distdir
@echo "Building $@ (output in checkcfg.$*.log)"
exec >'checkcfg.$*.log' 2>&1; \
echo "Testing configure with $(subst ^,=,$(subst +, ,$*))"; set -x; \
echo "Testing configure with $(CFGCHECK_CONFIGFLAGS)"; set -x; \
rm -rf $(distdir)/_build \
&& mkdir $(distdir)/_build \
&& cd $(distdir)/_build \
&& ../configure --srcdir=.. $(subst ^,=,$(subst +, ,$*)) \
$(AM_DISTCHECK_CONFIGURE_FLAGS) $(DISTCHECK_CONFIGURE_FLAGS)
exec >>'checkcfg.$*.log' 2>&1; set -x; \
cd $(distdir)/_build \
&& OUTDIR=_bld ../build.sh \
&& _bld/make $(AM_MAKEFLAGS) check-local \
&& _bld/make $(AM_MAKEFLAGS) clean
exec >>'checkcfg.$*.log' 2>&1; set -x; \
cd $(distdir)/_build \
&& $(NR_MAKE) $(AM_MAKEFLAGS) CFLAGS='$(AM_CFLAGS)' \
&& ./make $(AM_MAKEFLAGS) check \
&& ./make $(AM_MAKEFLAGS) clean
&& ../configure --srcdir=.. $(CFGCHECK_CONFIGFLAGS) \
$(AM_DISTCHECK_CONFIGURE_FLAGS) $(DISTCHECK_CONFIGURE_FLAGS)
$(build.sh_SCRIPT)
$(nrmake_SCRIPT)
# Try using Basic.mk. I can't test this on POSIX systems because it is only
# used for non-POSIX systems; POSIX systems can just use normal
@@ -276,10 +330,10 @@ checkcfg.basicmk: checkcfg.% : distdir
&& mkdir $(distdir)/_build \
&& cd $(distdir)/_build \
&& ../configure --srcdir=.. \
$(AM_DISTCHECK_CONFIGURE_FLAGS) $(DISTCHECK_CONFIGURE_FLAGS)
$(AM_DISTCHECK_CONFIGURE_FLAGS) $(DISTCHECK_CONFIGURE_FLAGS)
exec >>'checkcfg.$*.log' 2>&1; set -x; \
cd $(distdir)/_build \
&& $(NR_MAKE) $(AM_MAKEFLAGS) -f ../Basic.mk SRCDIR=.. CFLAGS='$(AM_CFLAGS)' \
&& $(NR_MAKE) $(AM_MAKEFLAGS) -f ../Basic.mk SRCDIR=.. $(CFGCHECK_MAKEFLAGS)
&& ./make $(AM_MAKEFLAGS) -f ../Basic.mk SRCDIR=.. check \
&& ./make $(AM_MAKEFLAGS) -f ../Basic.mk SRCDIR=.. clean
exec >>'checkcfg.$*.log' 2>&1; \
@@ -287,8 +341,8 @@ checkcfg.basicmk: checkcfg.% : distdir
&& rm -rf $(distdir)/_build \
&& cd $(distdir) \
&& ./configure \
$(AM_DISTCHECK_CONFIGURE_FLAGS) $(DISTCHECK_CONFIGURE_FLAGS) \
&& $(NR_MAKE) $(AM_MAKEFLAGS) -f Basic.mk CFLAGS='$(AM_CFLAGS)' \
$(AM_DISTCHECK_CONFIGURE_FLAGS) $(DISTCHECK_CONFIGURE_FLAGS) \
&& $(NR_MAKE) $(AM_MAKEFLAGS) -f Basic.mk $(CFGCHECK_MAKEFLAGS)' \
&& ./make $(AM_MAKEFLAGS) -f Basic.mk check \
&& ./make $(AM_MAKEFLAGS) -f Basic.mk clean
@@ -309,10 +363,10 @@ local-check: po-check changelog-check
# copyright-check writable-files
changelog-check:
if head $(top_srcdir)/ChangeLog | grep 'Version $(VERSION)' >/dev/null; then \
if head $(top_srcdir)/ChangeLog | grep 'Version $(PACKAGE_VERSION)' >/dev/null; then \
:; \
else \
echo "$(VERSION) not in ChangeLog" 1>&2; \
echo "$(PACKAGE_VERSION) not in ChangeLog" 1>&2; \
exit 1; \
fi
@@ -341,16 +395,16 @@ gnuweb-dir = www/server/standards
# Get the GNU make web page boilerplate etc.
update-makeweb:
[ -d '$(MAKEWEBDIR)' ] || mkdir -p '$(MAKEWEBDIR)'
[ -d '$(MAKEWEBDIR)'/CVS ] \
test -d '$(MAKEWEBDIR)' || mkdir -p '$(MAKEWEBDIR)'
test -d '$(MAKEWEBDIR)'/CVS \
&& { cd '$(MAKEWEBDIR)' && $(CVS) update; } \
|| { mkdir -p '$(dir $(MAKEWEBDIR))' && cd '$(dir $(MAKEWEBDIR))' \
&& $(CVS) -d $(makeweb-repo) co -d '$(notdir $(MAKEWEBDIR))' make; }
# Get the GNU web page boilerplate etc.
update-gnuweb:
[ -d '$(GNUWEBDIR)' ] || mkdir -p '$(GNUWEBDIR)'
[ -d '$(GNUWEBDIR)/$(gnuweb-dir)'/CVS ] \
test -d '$(GNUWEBDIR)' || mkdir -p '$(GNUWEBDIR)'
test -d '$(GNUWEBDIR)/$(gnuweb-dir)'/CVS \
&& { cd '$(GNUWEBDIR)/$(gnuweb-dir)' && $(CVS) update; } \
|| { cd '$(GNUWEBDIR)' && $(CVS) -d $(gnuweb-repo) co '$(gnuweb-dir)'; }
@@ -359,7 +413,7 @@ gendocs: update-gnuweb update-makeweb
cd doc \
&& rm -rf doc/manual \
&& $(GNULIBDIR)/build-aux/gendocs.sh --email '$(BUGLIST)' \
make 'GNU Make Manual'
make '$(PACKAGE_NAME) Manual'
find '$(MAKEWEBDIR)'/manual \( -name CVS -prune \) -o \( -name '[!.]*' -type f -exec rm -f '{}' \; \)
cp -r doc/manual '$(MAKEWEBDIR)'
@echo 'Status of $(MAKEWEBDIR) repo:' && cd '$(MAKEWEBDIR)' \
@@ -367,7 +421,7 @@ gendocs: update-gnuweb update-makeweb
@echo '- cvs add <new files>' \
&& echo '- cvs remove <deleted files>' \
&& echo '- cvs commit' \
&& echo '- cvs tag make-$(subst .,-,$(VERSION))'
&& echo '- cvs tag make-$(subst .,-,$(PACKAGE_VERSION))'
## --------------------------------------------- ##
@@ -392,7 +446,7 @@ $(COV_BUILD_FILE): $(filter %.c %.h,$(DISTFILES))
cd '$(distdir)'/_build \
&& ../configure --srcdir=.. \
$(AM_DISTCHECK_CONFIGURE_FLAGS) $(DISTCHECK_CONFIGURE_FLAGS) \
CFLAGS='$(AM_CFLAGS)'
$(CFGCHECK_MAKEFLAGS)
PATH="$${COVERITY_PATH:+$$COVERITY_PATH/bin:}$$PATH"; \
cd '$(distdir)'/_build \
&& cov-build --dir cov-int ../build.sh
@@ -402,18 +456,18 @@ $(COV_BUILD_FILE): $(filter %.c %.h,$(DISTFILES))
cov-submit: $(COV_BUILD_FILE)-submitted
$(COV_BUILD_FILE)-submitted: $(COV_BUILD_FILE)
@[ -n "$(COVERITY_TOKEN)" ] || { echo 'COVERITY_TOKEN not set'; exit 1; }
@[ -n "$(COVERITY_EMAIL)" ] || { echo 'COVERITY_EMAIL not set'; exit 1; }
@test -n "$(COVERITY_TOKEN)" || { echo 'COVERITY_TOKEN not set'; exit 1; }
@test -n "$(COVERITY_EMAIL)" || { echo 'COVERITY_EMAIL not set'; exit 1; }
rm -f '$@'
case '$(VERSION)' in \
case '$(PACKAGE_VERSION)' in \
(*.*.9*) type="daily build"; ext=".$$(date +%Y%m%d)" ;; \
(*) type="release"; ext= ;; \
esac; \
curl --form token='$(COVERITY_TOKEN)' \
--form email='$(COVERITY_EMAIL)' \
--form file='@$<' \
--form version="$(VERSION)$$ext" \
--form description="GNU make $$type" \
--form version="$(PACKAGE_VERSION)$$ext" \
--form description="$(PACKAGE_NAME) $$type" \
'https://scan.coverity.com/builds?project=gmake'
cp '$<' '$@'
@@ -424,11 +478,11 @@ $(COV_BUILD_FILE)-submitted: $(COV_BUILD_FILE)
.PHONY: tag-release
tag-release:
case '$(VERSION)' in \
case '$(PACKAGE_VERSION)' in \
(*.*.9*) message=" candidate" ;; \
(*) message= ;; \
esac; \
$(GIT) tag -m "GNU Make release$$message $(VERSION)" -u '$(GPG_KEYID)' '$(VERSION)'
$(GIT) tag -m "$(PACKAGE_NAME) release$$message $(PACKAGE_VERSION)" -u '$(GPG_KEYID)' '$(PACKAGE_VERSION)'
## ------------------------- ##
@@ -459,14 +513,14 @@ distsign: $(DIST_ARCHIVES_SIG) $(DIST_ARCHIVES_DIRECTIVE)
echo 'version: 1.2'; \
echo 'directory: make'; \
echo 'filename: $*'; \
echo 'comment: Official upload of GNU make version $(VERSION)'; \
echo 'comment: Official upload of $(PACKAGE_NAME) version $(PACKAGE_VERSION)'; \
) > "$*.directive"
$(GPG) $(GPGFLAGS) -o "$@" --clearsign "$*.directive"
@rm -f "$*.directive"
# Upload the artifacts
FTPPUT = ncftpput
FTPPUT := $(firstword $(shell command -v ncftpput) $(wildcard $(GNULIBDIR)/build-aux/ncftpput-ftp) invalid)
gnu-upload-host = ftp-upload.gnu.org
gnu-upload-dir = /incoming
@@ -480,7 +534,7 @@ $(UPLOADS): $(DIST_ARCHIVES) $(DIST_ARCHIVES_SIG) $(DIST_ARCHIVES_DIRECTIVE)
# Rebuild Makefile.in if this file is modifed.
Makefile.in: maintMakefile
# Copyright (C) 1997-2019 Free Software Foundation, Inc.
# Copyright (C) 1997-2022 Free Software Foundation, Inc.
# This file is part of GNU Make.
#
# GNU Make is free software; you can redistribute it and/or modify it under
@@ -494,4 +548,4 @@ Makefile.in: maintMakefile
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>.
# this program. If not, see <https://www.gnu.org/licenses/>.

View File

@@ -1,11 +1,15 @@
import re
"""GDB pretty-printer macros for GNU Make."""
import gdb # pylint: disable=import-error
import gdb.printing # pylint: disable=import-error
import gdb #pylint: disable=import-error
import gdb.printing #pylint: disable=import-error
# Memoize types we commonly use
_TYPES = {}
def getType(tname):
"""Given a type name return a GDB type."""
global _TYPES
if tname not in _TYPES:
tn = tname.rstrip('*')
@@ -18,48 +22,129 @@ def getType(tname):
_TYPES[tn] = _TYPES[t].pointer()
return _TYPES[tname]
class ShowArgv(gdb.Function):
"""Return the pretty-print of a null-terminated array of strings
def isNullptr(val):
"""Return True if the value is a null pointer."""
return int(val.cast(getType('unsigned long long'))) == 0
class ShowArgv(gdb.Command):
"""Print a null-terminated array of strings.
Argument:
A char** where the last one is NULL (e.g., argv)
"""
def __init__(self):
gdb.Function.__init__(self, "showargv")
"""Create the showargv function."""
gdb.Command.__init__(self, "showargv", gdb.COMMAND_USER)
def invoke(self, arg, from_tty):
"""Show the argv."""
args = gdb.string_to_argv(arg)
if len(args) != 1:
raise gdb.GdbError(self._usage)
val = gdb.parse_and_eval(args[0])
if val is None:
raise gdb.GdbError('%s is not a valid expression' % (args[0]))
strs = []
while not isNullptr(val.dereference()):
strs.append('"'+val.dereference().string()+'"')
val += 1
gdb.write("[%d] = [%s]\n" % (len(strs), ', '.join(strs)))
gdb.flush()
def invoke(self, argv):
str = '['
i = 0
while argv[i] != 0:
if i > 0:
str += ', '
str += argv[i].string()
i += 1
str += ']'
return str
ShowArgv()
class ShowNextList(gdb.Command):
"""Print a structure that has a "next" pointer.
Argument:
A pointer to a struct which contains a "next" member.
"""
_usage = 'usage: showlist <listptr>'
def __init__(self):
"""Create a "showlist" function."""
gdb.Command.__init__(self, "showlist", gdb.COMMAND_USER)
def invoke(self, arg, from_tty):
"""Show the elements in the provided list."""
args = gdb.string_to_argv(arg)
if len(args) != 1:
raise gdb.GdbError(self._usage)
val = gdb.parse_and_eval(args[0])
if val is None:
raise gdb.GdbError('%s is not a valid expression' % (args[0]))
i = 0
while not isNullptr(val):
gdb.write("%s : %s\n" % (val, val.dereference()))
gdb.flush()
i += 1
val = val['next']
gdb.write("%s contains %d elements\n" % (args[0], i))
gdb.flush()
ShowNextList()
class FileLocation(object):
"""Print a file location"""
"""Print a file location."""
def __init__(self, val):
"""Create a FileLocation object."""
self.val = val
def to_string(self):
if long(self.val['filenm']):
"""Convert a FileLocation to a string."""
if int(self.val['filenm']):
return "%s:%d" % (str(self.val['filenm']), self.val['lineno'])
return ''
return 'NILF'
class StringListPrinter(object):
"""Print a stringlist."""
def __init__(self, val):
"""Create a StringListPrinter object."""
self.val = val
def to_string(self):
"""Convert a HashTable into a string."""
return "size=%d, capacity=%d" % (self.val['idx'], self.val['max'])
def children(self):
"""Yield each string in the list."""
i = 0
elts = self.val['list']
while i < self.val['idx']:
nm = '[%d] ' % i
yield (nm, elts.dereference())
i += 1
elts += 1
def display_hint(self):
"""Show the display hint for the pretty-printer."""
return 'array'
class VariablePrinter(object):
"""Print a struct variable"""
"""Print a struct variable."""
def __init__(self, val):
"""Create a VariablePrinter object."""
self.val = val
def to_string(self):
"""Convert a VariablePrinter object into a string."""
if self.val['append']:
a = '+='
elif self.val['conditional']:
@@ -80,48 +165,58 @@ class VariablePrinter(object):
self.val['fileinfo'], ','.join(flags),
self.val['name'].string(), a, self.val['value'].string())
class HashTablePrinter(object):
"""Manage a hash table."""
"""Pretty-print a hash table."""
DELITEM = None
def __init__(self, val):
"""Create a HashTablePrinter object."""
self.val = val
def to_string(self):
"""Convert a HashTable into a string."""
return "size=%d, capacity=%d, empty=%d, collisions=%d, rehashes=%d" % (
self.val['ht_size'], self.val['ht_capacity'],
self.val['ht_empty_slots'], self.val['ht_collisions'],
self.val['ht_rehashes'])
def children(self):
"""Yield each ID and value."""
for (i, v) in self.iterator():
nm = '[%d] ' % i
yield (nm, i)
yield (nm, v)
def iterator(self):
"""Provide an iterator for HashTable."""
if HashTablePrinter.DELITEM is None:
HashTablePrinter.DELITEM = gdb.lookup_global_symbol('hash_deleted_item').value()
lst = self.val['ht_vec']
for i in xrange(0, self.val['ht_size']):
for i in range(0, self.val['ht_size']):
v = lst[i]
if long(v) != 0 and v != HashTablePrinter.DELITEM:
if int(v) != 0 and v != HashTablePrinter.DELITEM:
yield (i, v)
def display_hint(self):
"""Show the display hint for the pretty-printer."""
return 'map'
class VariableSetPrinter(object):
"""Print a variable_set"""
"""Print a variable_set."""
def __init__(self, val):
"""Create a variable_set pretty-printer."""
self.tbl = HashTablePrinter(val['table'])
def to_string(self):
"""Convert a variable_set to string."""
return self.tbl.to_string()
def children(self):
"""Iterate through variables and values."""
for (i, v) in self.tbl.iterator():
ptr = v.cast(getType('struct variable*'))
nm = '[%d] ' % (i)
@@ -129,29 +224,35 @@ class VariableSetPrinter(object):
yield (nm, str(ptr.dereference()))
def display_hint(self):
"""Show the display hint for the pretty-printer."""
return 'map'
class VariableSetListPrinter(object):
"""Print a variable_set_list"""
"""Print a variable_set_list."""
GLOBALSET = None
def __init__(self, val):
"""Create a variable_set_list pretty-printer."""
self.val = val
def to_string(self):
"""Convert a variable_set_list to string."""
return str(self.val.address)
def children(self):
"""Iterate through variables and values."""
if VariableSetListPrinter.GLOBALSET is None:
block = gdb.lookup_global_symbol('init_hash_global_variable_set').symtab.static_block()
VariableSetListPrinter.GLOBALSET = gdb.lookup_symbol('global_variable_set', block)[0].value().address
VariableSetListPrinter.GLOBALSET = gdb.lookup_symbol(
'global_variable_set', block)[0].value().address
ptr = self.val.address
i = 0
while long(ptr) != 0:
while not isNullptr(ptr):
nm = '[%d] ' % (i)
yield (nm, ptr['set'])
if long(ptr['set']) == long(VariableSetListPrinter.GLOBALSET):
if int(ptr['set']) == int(VariableSetListPrinter.GLOBALSET):
yield (nm, "global_variable_set")
else:
yield (nm, str(ptr['set'].dereference()))
@@ -159,17 +260,22 @@ class VariableSetListPrinter(object):
ptr = ptr['next']
def display_hint(self):
"""Show the display hint for the pretty-printer."""
return 'map'
def build_pretty_printer():
"""Install all the pretty-printers."""
pp = gdb.printing.RegexpCollectionPrettyPrinter("gnumake")
pp.add_printer('floc', r'^floc$', FileLocation)
pp.add_printer('stringlist', r'^stringlist$', StringListPrinter)
pp.add_printer('variable', r'^variable$', VariablePrinter)
pp.add_printer('hashtable', r'^hash_table$', HashTablePrinter)
pp.add_printer('variableset', r'^variable_set$', VariableSetPrinter)
pp.add_printer('variablesetlist', r'^variable_set_list$', VariableSetListPrinter)
return pp
# Use replace=True so we can re-source this file
gdb.printing.register_pretty_printer(gdb.current_objfile(),
build_pretty_printer(), replace=True)

View File

@@ -76,7 +76,7 @@ $ filelist = "[.src]ar [.src]arscan [.src]commands [.src]default [.src]dir " + -
"[.src]hash [.src]implicit [.src]job [.src]load [.src]main " + -
"[.src]misc [.src]read [.src]remake [.src]remote-stub " + -
"[.src]rule [.src]output [.src]signame [.src]variable " + -
"[.src]version [.src]strcache [.src]vpath " + -
"[.src]version [.src]shuffle [.src]strcache [.src]vpath " + -
"[.src]vmsfunctions [.src]vmsify [.src]vms_progname " + -
"[.src]vms_exit [.src]vms_export_symbol " + -
"[.lib]alloca [.lib]fnmatch [.lib]glob [.src]getopt1 [.src]getopt"
@@ -154,7 +154,7 @@ $ exit
$ endsubroutine : compileit
$!
$!-----------------------------------------------------------------------------
$!Copyright (C) 1996-2019 Free Software Foundation, Inc.
$!Copyright (C) 1996-2022 Free Software Foundation, Inc.
$!This file is part of GNU Make.
$!
$!GNU Make is free software; you can redistribute it and/or modify it under
@@ -168,4 +168,4 @@ $!FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
$!details.
$!
$!You should have received a copy of the GNU General Public License along with
$!this program. If not, see <http://www.gnu.org/licenses/>.
$!this program. If not, see <https://www.gnu.org/licenses/>.

View File

@@ -2,7 +2,7 @@
#
# Amiga overrides for use with Basic.mk.
#
# Copyright (C) 2017-2019 Free Software Foundation, Inc.
# Copyright (C) 2017-2022 Free Software Foundation, Inc.
# This file is part of GNU Make.
#
# GNU Make is free software; you can redistribute it and/or modify it under
@@ -16,7 +16,7 @@
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>.
# this program. If not, see <https://www.gnu.org/licenses/>.
CC = sc
LD = $(CC) Link

View File

@@ -2,7 +2,7 @@
#
# POSIX overrides for use with Basic.mk.
#
# Copyright (C) 2017-2019 Free Software Foundation, Inc.
# Copyright (C) 2017-2022 Free Software Foundation, Inc.
# This file is part of GNU Make.
#
# GNU Make is free software; you can redistribute it and/or modify it under
@@ -16,11 +16,11 @@
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>.
# this program. If not, see <https://www.gnu.org/licenses/>.
# Very little is needed here since the default Basic.mk assumes POSIX
prog_SOURCES += $(posix_SOURCES)
prog_SOURCES += $(src)/posixos.c
extra_CPPFLAGS += @GUILE_CFLAGS@
extra_LDFLAGS += @AM_LDFLAGS@

View File

@@ -2,7 +2,7 @@
#
# VMS overrides for use with Basic.mk.
#
# Copyright (C) 2017-2019 Free Software Foundation, Inc.
# Copyright (C) 2017-2022 Free Software Foundation, Inc.
# This file is part of GNU Make.
#
# GNU Make is free software; you can redistribute it and/or modify it under
@@ -16,7 +16,7 @@
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>.
# this program. If not, see <https://www.gnu.org/licenses/>.
src = [.src]
lib = [.lib]
@@ -93,5 +93,5 @@ define CLEANSPACE
endef
$(OUTDIR)$(src)config.h: $(SRCDIR)$(src)config.h.W32
$(OUTDIR)$(src)config.h: $(SRCDIR)$(src)config.h-vms
$(call CP.cmd,$<,$@)

View File

@@ -2,7 +2,7 @@
#
# Windows overrides for use with Basic.mk.
#
# Copyright (C) 2017-2019 Free Software Foundation, Inc.
# Copyright (C) 2017-2022 Free Software Foundation, Inc.
# This file is part of GNU Make.
#
# GNU Make is free software; you can redistribute it and/or modify it under
@@ -16,7 +16,7 @@
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>.
# this program. If not, see <https://www.gnu.org/licenses/>.
# TARGET_TYPE can be either "release" or "debug"
TARGET_TYPE = release

View File

@@ -2,7 +2,7 @@
#
# MS-DOS overrides for use with Basic.mk.
#
# Copyright (C) 2017-2019 Free Software Foundation, Inc.
# Copyright (C) 2017-2022 Free Software Foundation, Inc.
# This file is part of GNU Make.
#
# GNU Make is free software; you can redistribute it and/or modify it under
@@ -16,7 +16,7 @@
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>.
# this program. If not, see <https://www.gnu.org/licenses/>.
OBJEXT = o
EXEEXT = .exe

View File

@@ -19,6 +19,7 @@ nl
pl
pt
pt_BR
ro
ru
sr
sv

View File

@@ -1,5 +1,5 @@
# List of source files containing translatable strings.
# Copyright (C) 2000-2019 Free Software Foundation, Inc.
# Copyright (C) 2000-2022 Free Software Foundation, Inc.
# This file is part of GNU Make.
#
# GNU Make is free software; you can redistribute it and/or modify it under
@@ -13,7 +13,7 @@
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>.
# this program. If not, see <https://www.gnu.org/licenses/>.
src/ar.c
src/arscan.c
@@ -37,6 +37,7 @@ src/read.c
src/remake.c
src/remote-cstms.c
src/rule.c
src/shuffle.c
src/signame.c
src/strcache.c
src/variable.c

View File

@@ -4,28 +4,27 @@ $!
$! This is used for building off the master instead of a release tarball.
$!
$!
$!
$! First try ODS-5, Pathworks V6 or UNZIP name.
$!
$ config_template = f$search("sys$disk:[]config*h-vms.template")
$ config_template = f$search("sys$disk:[.src]mkconfig*h.in")
$ if config_template .eqs. ""
$ then
$!
$! Try NFS, VMStar, or Pathworks V5 ODS-2 encoded name.
$!
$ config_template = f$search("sys$disk:[]config.h-vms*template")
$ config_template = f$search("sys$disk:[.src]mkconfig.h*in")
$ if config_template .eqs. ""
$ then
$ write sys$output "Could not find config.h-vms*template!"
$ write sys$output "Could not find mkconfig.h.in!"
$ exit 44
$ endif
$ endif
$ config_template_file = f$parse(config_template,,,"name")
$ config_template_type = f$parse(config_template,,,"type")
$ config_template = "sys$disk:[]" + config_template_file + config_template_type
$ config_template = "sys$disk:[.src]" + config_template_file + config_template_type
$!
$!
$! Pull the package and version from configure.ac
$! Pull the version from configure.ac
$!
$ open/read ac_file sys$disk:[]configure.ac
$ac_read_loop:
@@ -39,21 +38,26 @@ $ version = f$element (0,"]",version)
$ac_read_loop_end:
$ close ac_file
$!
$ if (package .eqs. "") .or. (version .eqs. "")
$ if (version .eqs. "")
$ then
$ write sys$output "Unable to determine package and/or version!"
$ write sys$output "Unable to determine version!"
$ exit 44
$ endif
$!
$!
$ outfile = "sys$disk:[]config.h-vms"
$ outfile = "sys$disk:[.src]mkconfig.h"
$!
$! Note the pipe command is close to the length of 255, which is the
$! maximum token length prior to VMS V8.2:
$! %DCL-W-TKNOVF, command element is too long - shorten
$ pipe (write sys$output "sub/%PACKAGE%/''package'/WHOLE/NOTYPE" ;-
write sys$output "sub/%VERSION%/''version'/WHOLE/NOTYPE" ;-
$! PDS: Blown out; someone else will have to figure this out
$ pipe (write sys$output "sub,@PACKAGE@,make,WHOLE/NOTYPE" ;-
write sys$output "sub,@PACKAGE_BUGREPORT@,bug-make@gnu.org,WHOLE/NOTYPE" ;-
write sys$output "sub,@PACKAGE_NAME@,GNU Make,WHOLE/NOTYPE" ;-
write sys$output "sub,@PACKAGE_TARNAME@,make,WHOLE/NOTYPE" ;-
write sys$output "sub,@PACKAGE_URL@,https://www.gnu.org/software/make/,WHOLE/NOTYPE" ;-
write sys$output "sub,@PACKAGE_VERSION@,''version',WHOLE/NOTYPE" ;-
write sys$output "exit") |-
edit/edt 'config_template'/out='outfile'/command=sys$pipe >nla0:
$!
$ write sys$output package, ", version: ", version, " prepared for VMS"
$ write sys$output "GNU Make version: ", version, " prepared for VMS"

View File

@@ -1,6 +1,6 @@
#!/bin/sh
#
# Copyright (C) 2014-2019 Free Software Foundation, Inc.
# Copyright (C) 2014-2022 Free Software Foundation, Inc.
# This file is part of GNU Make.
#
# Update GNU make copyrights using gnulib update-copyright
@@ -17,7 +17,7 @@ getfiles () {
run () {
cmd=$(command -v "$update") || die "Cannot locate update-copyright ($update)"
[ -x "$cmd" ] || die "Cannot locate update-copyright ($update)"
test -x "$cmd" || die "Cannot locate update-copyright ($update)"
force=false
@@ -30,9 +30,9 @@ run () {
if $force; then
: just do it
elif [ ! -f src/makeint.h ]; then
elif test ! -f src/makeint.h; then
die "Run in the root of the GNU make workspace"
elif [ -f configure ]; then
elif test -f configure; then
die "Run in a clean workspace (git clean -fdX)"
fi
@@ -60,4 +60,4 @@ run "$@"
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>.
# this program. If not, see <https://www.gnu.org/licenses/>.

View File

@@ -1,5 +1,5 @@
/* Running commands on Amiga
Copyright (C) 1995-2019 Free Software Foundation, Inc.
Copyright (C) 1995-2022 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -12,7 +12,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
this program. If not, see <https://www.gnu.org/licenses/>. */
#include "makeint.h"
#include "variable.h"
@@ -42,7 +42,7 @@ MyExecute (char **argv)
buffer = AllocMem (len, MEMF_ANY);
if (!buffer)
O (fatal, NILF, "MyExecute: Cannot allocate space for calling a command\n");
O (fatal, NILF, "MyExecute: Cannot allocate space for calling a command");
ptr = buffer;
@@ -51,9 +51,8 @@ MyExecute (char **argv)
if (((*aptr)[0] == ';' && !(*aptr)[1]))
{
*ptr ++ = '"';
strcpy (ptr, *aptr);
ptr += strlen (ptr);
*ptr ++ = '"';
ptr = stpcpy (ptr, *aptr);
*(ptr++) = '"';
}
else if ((*aptr)[0] == '@' && (*aptr)[1] == '@' && !(*aptr)[2])
{
@@ -61,10 +60,7 @@ MyExecute (char **argv)
continue;
}
else
{
strcpy (ptr, *aptr);
ptr += strlen (ptr);
}
ptr = stpcpy (ptr, *aptr);
*ptr ++ = ' ';
*ptr = 0;
}

View File

@@ -1,5 +1,5 @@
/* Definitions for amiga specific things
Copyright (C) 1995-2019 Free Software Foundation, Inc.
Copyright (C) 1995-2022 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -12,7 +12,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
this program. If not, see <https://www.gnu.org/licenses/>. */
int MyExecute (char ** argv);
char * wildcard_expansion (char * wc, char * o);

View File

@@ -1,5 +1,5 @@
/* Interface to 'ar' archives for GNU Make.
Copyright (C) 1988-2019 Free Software Foundation, Inc.
Copyright (C) 1988-2022 Free Software Foundation, Inc.
This file is part of GNU Make.
@@ -13,7 +13,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
this program. If not, see <https://www.gnu.org/licenses/>. */
#include "makeint.h"
@@ -22,6 +22,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#include "filedef.h"
#include "dep.h"
#include <fnmatch.h>
#include <intprops.h>
/* Return nonzero if NAME is an archive-member reference, zero if not. An
archive-member reference is a name like 'lib(member)' where member is a
@@ -35,7 +36,7 @@ ar_name (const char *name)
const char *p = strchr (name, '(');
const char *end;
if (p == 0 || p == name)
if (p == NULL || p == name)
return 0;
end = p + strlen (p) - 1;
@@ -60,6 +61,9 @@ ar_parse_name (const char *name, char **arname_p, char **memname_p)
*arname_p = xstrdup (name);
p = strchr (*arname_p, '(');
/* This is never called unless ar_name() is true so p cannot be NULL. */
if (!p)
OS (fatal, NILF, "Internal: ar_parse_name: bad name '%s'", *arname_p);
*(p++) = '\0';
p[strlen (p) - 1] = '\0';
*memname_p = p;
@@ -69,10 +73,10 @@ ar_parse_name (const char *name, char **arname_p, char **memname_p)
/* This function is called by 'ar_scan' to find which member to look at. */
/* ARGSUSED */
static long int
static intmax_t
ar_member_date_1 (int desc UNUSED, const char *mem, int truncated,
long int hdrpos UNUSED, long int datapos UNUSED,
long int size UNUSED, long int date,
long int size UNUSED, intmax_t date,
int uid UNUSED, int gid UNUSED, unsigned int mode UNUSED,
const void *name)
{
@@ -86,7 +90,7 @@ ar_member_date (const char *name)
{
char *arname;
char *memname;
long int val;
intmax_t val;
ar_parse_name (name, &arname, &memname);
@@ -111,7 +115,7 @@ ar_member_date (const char *name)
free (arname);
return (val <= 0 ? (time_t) -1 : (time_t) val);
return 0 < val && val <= TYPE_MAXIMUM (time_t) ? val : -1;
}
/* Set the archive-member NAME's modtime to now. */
@@ -194,10 +198,10 @@ struct ar_glob_state
/* This function is called by 'ar_scan' to match one archive
element against the pattern in STATE. */
static long int
static intmax_t
ar_glob_match (int desc UNUSED, const char *mem, int truncated UNUSED,
long int hdrpos UNUSED, long int datapos UNUSED,
long int size UNUSED, long int date UNUSED, int uid UNUSED,
long int size UNUSED, intmax_t date UNUSED, int uid UNUSED,
int gid UNUSED, unsigned int mode UNUSED, const void *arg)
{
struct ar_glob_state *state = (struct ar_glob_state *)arg;
@@ -218,7 +222,7 @@ ar_glob_match (int desc UNUSED, const char *mem, int truncated UNUSED,
++state->n;
}
return 0L;
return 0;
}
/* Return nonzero if PATTERN contains any metacharacters.

View File

@@ -1,5 +1,5 @@
/* Library function for scanning an archive file.
Copyright (C) 1987-2019 Free Software Foundation, Inc.
Copyright (C) 1987-2022 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -12,7 +12,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
this program. If not, see <https://www.gnu.org/licenses/>. */
#include "makeint.h"
@@ -75,9 +75,9 @@ static void *VMS_lib_idx;
static const void *VMS_saved_arg;
static long int (*VMS_function) ();
static intmax_t (*VMS_function) ();
static long int VMS_function_ret;
static intmax_t VMS_function_ret;
/* This is a callback procedure for lib$get_index */
@@ -203,7 +203,7 @@ VMS_get_member_info(struct dsc$descriptor_s *module, unsigned long *rfa)
Returns -2 if archive has invalid format.
Returns 0 if have scanned successfully. */
long int
intmax_t
ar_scan (const char *archive, ar_member_func_t function, const void *varg)
{
char *vms_archive;
@@ -376,8 +376,41 @@ struct ar_hdr
# define AR_HDR_SIZE (sizeof (struct ar_hdr))
#endif
#include "intprops.h"
#include "output.h"
static uintmax_t
parse_int (const char *ptr, const size_t len, const int base, uintmax_t max,
const char *type, const char *archive, const char *name)
{
const char *const ep = ptr + len;
const int maxchar = '0' + base - 1;
uintmax_t val = 0;
/* In all the versions I know of the spaces come last, but be safe. */
while (ptr < ep && *ptr == ' ')
++ptr;
while (ptr < ep && *ptr != ' ')
{
uintmax_t nv;
if (*ptr < '0' || *ptr > maxchar)
OSSS (fatal, NILF,
_("Invalid %s for archive %s member %s"), type, archive, name);
nv = (val * base) + (*ptr - '0');
if (nv < val || nv > max)
OSSS (fatal, NILF,
_("Invalid %s for archive %s member %s"), type, archive, name);
val = nv;
++ptr;
}
return val;
}
/* Takes three arguments ARCHIVE, FUNCTION and ARG.
Open the archive named ARCHIVE, find its members one by one,
@@ -405,7 +438,7 @@ struct ar_hdr
Returns -2 if archive has invalid format.
Returns 0 if have scanned successfully. */
long int
intmax_t
ar_scan (const char *archive, ar_member_func_t function, const void *arg)
{
#ifdef AIAMAG
@@ -416,7 +449,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
# endif
#endif
char *namemap = 0;
int namemap_size = 0;
unsigned int namemap_size = 0;
int desc = open (archive, O_RDONLY, 0);
if (desc < 0)
return -1;
@@ -516,7 +549,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
while (1)
{
int nread;
ssize_t nread;
struct ar_hdr member_header;
#ifdef AIAMAGBIG
struct ar_hdr_big member_header_big;
@@ -525,7 +558,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
# define ARNAME_MAX 255
char name[ARNAME_MAX + 1];
int name_len;
long int dateval;
intmax_t dateval;
int uidval, gidval;
long int data_offset;
#else
@@ -537,9 +570,13 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
#endif
long int eltsize;
unsigned int eltmode;
long int fnval;
intmax_t eltdate;
int eltuid, eltgid;
intmax_t fnval;
off_t o;
memset(&member_header, '\0', sizeof (member_header));
EINTRLOOP (o, lseek (desc, member_offset, 0));
if (o < 0)
goto invalid;
@@ -566,7 +603,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
name[name_len] = '\0';
sscanf (member_header_big.ar_date, "%12ld", &dateval);
sscanf (member_header_big.ar_date, "%12" SCNdMAX, &dateval);
sscanf (member_header_big.ar_uid, "%12d", &uidval);
sscanf (member_header_big.ar_gid, "%12d", &gidval);
sscanf (member_header_big.ar_mode, "%12o", &eltmode);
@@ -594,7 +631,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
name[name_len] = '\0';
sscanf (member_header.ar_date, "%12ld", &dateval);
sscanf (member_header.ar_date, "%12" SCNdMAX, &dateval);
sscanf (member_header.ar_uid, "%12d", &uidval);
sscanf (member_header.ar_gid, "%12d", &gidval);
sscanf (member_header.ar_mode, "%12o", &eltmode);
@@ -669,10 +706,11 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
&& (name[0] == ' ' || name[0] == '/')
&& namemap != 0)
{
int name_off = atoi (name + 1);
int name_len;
const char* err;
unsigned int name_off = make_toui (name + 1, &err);
size_t name_len;
if (name_off < 0 || name_off >= namemap_size)
if (err|| name_off >= namemap_size)
goto invalid;
name = namemap + name_off;
@@ -685,14 +723,15 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
&& name[1] == '1'
&& name[2] == '/')
{
int name_len = atoi (name + 3);
const char* err;
unsigned int name_len = make_toui (name + 3, &err);
if (name_len < 1)
if (err || name_len == 0 || name_len >= MIN (PATH_MAX, INT_MAX))
goto invalid;
name = alloca (name_len + 1);
nread = readbuf (desc, name, name_len);
if (nread != name_len)
if (nread < 0 || (unsigned int) nread != name_len)
goto invalid;
name[name_len] = '\0';
@@ -703,8 +742,16 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
}
#ifndef M_XENIX
sscanf (TOCHAR (member_header.ar_mode), "%o", &eltmode);
eltsize = atol (TOCHAR (member_header.ar_size));
#define PARSE_INT(_m, _t, _b, _n) \
(_t) parse_int (TOCHAR (member_header._m), sizeof (member_header._m), \
_b, TYPE_MAXIMUM (_t), _n, archive, name)
eltmode = PARSE_INT (ar_mode, unsigned int, 8, "mode");
eltsize = PARSE_INT (ar_size, long, 10, "size");
eltdate = PARSE_INT (ar_date, intmax_t, 10, "date");
eltuid = PARSE_INT (ar_uid, int, 10, "uid");
eltgid = PARSE_INT (ar_gid, int, 10, "gid");
#undef PARSE_INT
#else /* Xenix. */
eltmode = (unsigned short int) member_header.ar_mode;
eltsize = member_header.ar_size;
@@ -714,9 +761,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
(*function) (desc, name, ! long_name, member_offset,
member_offset + AR_HDR_SIZE, eltsize,
#ifndef M_XENIX
atol (TOCHAR (member_header.ar_date)),
atoi (TOCHAR (member_header.ar_uid)),
atoi (TOCHAR (member_header.ar_gid)),
eltdate, eltuid, eltgid,
#else /* Xenix. */
member_header.ar_date,
member_header.ar_uid,
@@ -856,10 +901,10 @@ ar_name_equal (const char *name, const char *mem, int truncated)
#ifndef VMS
/* ARGSUSED */
static long int
static intmax_t
ar_member_pos (int desc UNUSED, const char *mem, int truncated,
long int hdrpos, long int datapos UNUSED, long int size UNUSED,
long int date UNUSED, int uid UNUSED, int gid UNUSED,
intmax_t date UNUSED, int uid UNUSED, int gid UNUSED,
unsigned int mode UNUSED, const void *name)
{
if (!ar_name_equal (name, mem, truncated))
@@ -877,12 +922,13 @@ ar_member_pos (int desc UNUSED, const char *mem, int truncated,
int
ar_member_touch (const char *arname, const char *memname)
{
long int pos = ar_scan (arname, ar_member_pos, memname);
intmax_t pos = ar_scan (arname, ar_member_pos, memname);
off_t opos;
int fd;
struct ar_hdr ar_hdr;
off_t o;
int r;
unsigned int ui;
int datelen;
struct stat statbuf;
if (pos < 0)
@@ -890,11 +936,13 @@ ar_member_touch (const char *arname, const char *memname)
if (!pos)
return 1;
opos = (off_t) pos;
EINTRLOOP (fd, open (arname, O_RDWR, 0666));
if (fd < 0)
return -3;
/* Read in this member's header */
EINTRLOOP (o, lseek (fd, pos, 0));
EINTRLOOP (o, lseek (fd, opos, 0));
if (o < 0)
goto lose;
r = readbuf (fd, &ar_hdr, AR_HDR_SIZE);
@@ -906,15 +954,16 @@ ar_member_touch (const char *arname, const char *memname)
goto lose;
/* Advance member's time to that time */
#if defined(ARFMAG) || defined(ARFZMAG) || defined(AIAMAG) || defined(WINDOWS32)
for (ui = 0; ui < sizeof ar_hdr.ar_date; ui++)
ar_hdr.ar_date[ui] = ' ';
sprintf (TOCHAR (ar_hdr.ar_date), "%lu", (long unsigned) statbuf.st_mtime);
ar_hdr.ar_date[strlen ((char *) ar_hdr.ar_date)] = ' ';
datelen = snprintf (TOCHAR (ar_hdr.ar_date), sizeof ar_hdr.ar_date,
"%" PRIdMAX, (intmax_t) statbuf.st_mtime);
if (! (0 <= datelen && datelen < (int) sizeof ar_hdr.ar_date))
goto lose;
memset (ar_hdr.ar_date + datelen, ' ', sizeof ar_hdr.ar_date - datelen);
#else
ar_hdr.ar_date = statbuf.st_mtime;
#endif
/* Write back this member's header */
EINTRLOOP (o, lseek (fd, pos, 0));
EINTRLOOP (o, lseek (fd, opos, 0));
if (o < 0)
goto lose;
r = writebuf (fd, &ar_hdr, AR_HDR_SIZE);
@@ -933,18 +982,21 @@ ar_member_touch (const char *arname, const char *memname)
#ifdef TEST
long int
intmax_t
describe_member (int desc, const char *name, int truncated,
long int hdrpos, long int datapos, long int size,
long int date, int uid, int gid, unsigned int mode,
intmax_t date, int uid, int gid, unsigned int mode,
const void *arg)
{
extern char *ctime ();
time_t d = date;
char const *ds;
printf (_("Member '%s'%s: %ld bytes at %ld (%ld).\n"),
name, truncated ? _(" (name might be truncated)") : "",
size, hdrpos, datapos);
printf (_(" Date %s"), ctime (&date));
ds = ctime (&d);
printf (_(" Date %s"), ds ? ds : "?");
printf (_(" uid = %d, gid = %d, mode = 0%o.\n"), uid, gid, mode);
return 0;

View File

@@ -1,5 +1,5 @@
/* Command processing for GNU Make.
Copyright (C) 1988-2019 Free Software Foundation, Inc.
Copyright (C) 1988-2022 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -12,10 +12,11 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
this program. If not, see <https://www.gnu.org/licenses/>. */
#include "makeint.h"
#include "filedef.h"
#include "os.h"
#include "dep.h"
#include "variable.h"
#include "job.h"
@@ -30,10 +31,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#else
# define FILE_LIST_SEPARATOR ' '
#endif
#ifndef HAVE_UNISTD_H
pid_t getpid ();
#endif
static unsigned long
@@ -58,10 +55,13 @@ dep_hash_cmp (const void *x, const void *y)
return strcmp (dep_name (dx), dep_name (dy));
}
/* Set FILE's automatic variables up. */
/* Set FILE's automatic variables up.
* Use STEM to set $*.
* If STEM is 0, then set FILE->STEM and $* to the target name with any
* suffix in the .SUFFIXES list stripped off. */
void
set_file_variables (struct file *file)
set_file_variables (struct file *file, const char *stem)
{
struct dep *d;
const char *at, *percent, *star, *less;
@@ -95,7 +95,7 @@ set_file_variables (struct file *file)
}
/* $* is the stem from an implicit or static pattern rule. */
if (file->stem == 0)
if (stem == 0)
{
/* In Unix make, $* is set to the target name with
any suffix in the .SUFFIXES list stripped off for
@@ -118,25 +118,25 @@ set_file_variables (struct file *file)
for (d = enter_file (strcache_add (".SUFFIXES"))->deps; d ; d = d->next)
{
size_t slen = strlen (dep_name (d));
if (len > slen && strneq (dep_name (d), name + (len - slen), slen))
const char *dn = dep_name (d);
size_t slen = strlen (dn);
if (len > slen && memcmp (dn, name + (len - slen), slen) == 0)
{
file->stem = strcache_add_len (name, len - slen);
file->stem = stem = strcache_add_len (name, len - slen);
break;
}
}
if (d == 0)
file->stem = "";
file->stem = stem = "";
}
star = file->stem;
star = stem;
/* $< is the first not order-only dependency. */
less = "";
for (d = file->deps; d != 0; d = d->next)
if (!d->ignore_mtime)
if (!d->ignore_mtime && !d->ignore_automatic_vars && !d->need_2nd_expansion)
{
if (!d->need_2nd_expansion)
less = dep_name (d);
less = dep_name (d);
break;
}
@@ -178,7 +178,7 @@ set_file_variables (struct file *file)
bar_len = 0;
for (d = file->deps; d != 0; d = d->next)
{
if (!d->need_2nd_expansion)
if (!d->need_2nd_expansion && !d->ignore_automatic_vars)
{
if (d->ignore_mtime)
bar_len += strlen (dep_name (d)) + 1;
@@ -200,7 +200,7 @@ set_file_variables (struct file *file)
qmark_len = plus_len + 1; /* Will be this or less. */
for (d = file->deps; d != 0; d = d->next)
if (! d->ignore_mtime && ! d->need_2nd_expansion)
if (! d->ignore_mtime && ! d->need_2nd_expansion && ! d->ignore_automatic_vars)
{
const char *c = dep_name (d);
@@ -214,8 +214,7 @@ set_file_variables (struct file *file)
#endif
len = strlen (c);
memcpy (cp, c, len);
cp += len;
cp = mempcpy (cp, c, len);
*cp++ = FILE_LIST_SEPARATOR;
if (! (d->changed || always_make_flag))
qmark_len -= len + 1; /* Don't space in $? for this one. */
@@ -247,7 +246,7 @@ set_file_variables (struct file *file)
for (d = file->deps; d != 0; d = d->next)
{
if (d->need_2nd_expansion)
if (d->need_2nd_expansion || d->ignore_automatic_vars)
continue;
slot = hash_find_slot (&dep_hash, d);
@@ -269,7 +268,7 @@ set_file_variables (struct file *file)
{
const char *c;
if (d->need_2nd_expansion || hash_find_item (&dep_hash, d) != d)
if (d->need_2nd_expansion || d->ignore_automatic_vars || hash_find_item (&dep_hash, d) != d)
continue;
c = dep_name (d);
@@ -285,19 +284,16 @@ set_file_variables (struct file *file)
if (d->ignore_mtime)
{
memcpy (bp, c, len);
bp += len;
bp = mempcpy (bp, c, len);
*bp++ = FILE_LIST_SEPARATOR;
}
else
{
memcpy (cp, c, len);
cp += len;
cp = mempcpy (cp, c, len);
*cp++ = FILE_LIST_SEPARATOR;
if (d->changed || always_make_flag)
{
memcpy (qp, c, len);
qp += len;
qp = mempcpy (qp, c, len);
*qp++ = FILE_LIST_SEPARATOR;
}
}
@@ -326,14 +322,12 @@ set_file_variables (struct file *file)
void
chop_commands (struct commands *cmds)
{
unsigned int nlines;
unsigned short idx;
unsigned short nlines;
unsigned short i;
char **lines;
/* If we don't have any commands,
or we already parsed them, never mind. */
if (!cmds || cmds->command_lines != 0)
/* If we don't have any commands, or we already parsed them, never mind. */
if (!cmds || cmds->command_lines != NULL)
return;
/* Chop CMDS->commands up into lines in CMDS->command_lines. */
@@ -352,25 +346,27 @@ chop_commands (struct commands *cmds)
}
else
{
const char *p;
const char *p = cmds->commands;
size_t max = 5;
nlines = 5;
lines = xmalloc (nlines * sizeof (char *));
idx = 0;
p = cmds->commands;
nlines = 0;
lines = xmalloc (max * sizeof (char *));
while (*p != '\0')
{
const char *end = p;
find_end:;
end = strchr (end, '\n');
if (end == 0)
if (end == NULL)
end = p + strlen (p);
else if (end > p && end[-1] == '\\')
{
int backslash = 1;
const char *b;
for (b = end - 2; b >= p && *b == '\\'; --b)
backslash = !backslash;
if (end > p + 1)
{
const char *b;
for (b = end - 2; b >= p && *b == '\\'; --b)
backslash = !backslash;
}
if (backslash)
{
++end;
@@ -378,40 +374,36 @@ chop_commands (struct commands *cmds)
}
}
if (idx == nlines)
if (nlines == USHRT_MAX)
ON (fatal, &cmds->fileinfo,
_("Recipe has too many lines (limit %hu)"), nlines);
if (nlines == max)
{
nlines += 2;
lines = xrealloc (lines, nlines * sizeof (char *));
max += 2;
lines = xrealloc (lines, max * sizeof (char *));
}
lines[idx++] = xstrndup (p, (size_t) (end - p));
lines[nlines++] = xstrndup (p, (size_t) (end - p));
p = end;
if (*p != '\0')
++p;
}
if (idx != nlines)
{
nlines = idx;
lines = xrealloc (lines, nlines * sizeof (char *));
}
}
/* Finally, set the corresponding CMDS->lines_flags elements and the
CMDS->any_recurse flag. */
if (nlines > USHRT_MAX)
ON (fatal, &cmds->fileinfo, _("Recipe has too many lines (%ud)"), nlines);
cmds->ncommand_lines = (unsigned short)nlines;
cmds->ncommand_lines = nlines;
cmds->command_lines = lines;
cmds->any_recurse = 0;
cmds->lines_flags = xmalloc (nlines);
for (idx = 0; idx < nlines; ++idx)
for (i = 0; i < nlines; ++i)
{
unsigned char flags = 0;
const char *p = lines[idx];
const char *p = lines[i];
while (ISBLANK (*p) || *p == '-' || *p == '@' || *p == '+')
switch (*(p++))
@@ -428,12 +420,12 @@ chop_commands (struct commands *cmds)
}
/* If no explicit '+' was given, look for MAKE variable references. */
if (!(flags & COMMANDS_RECURSE)
if (! ANY_SET (flags, COMMANDS_RECURSE)
&& (strstr (p, "$(MAKE)") != 0 || strstr (p, "${MAKE}") != 0))
flags |= COMMANDS_RECURSE;
cmds->lines_flags[idx] = flags;
cmds->any_recurse |= flags & COMMANDS_RECURSE ? 1 : 0;
cmds->lines_flags[i] = flags;
cmds->any_recurse |= ANY_SET (flags, COMMANDS_RECURSE) ? 1 : 0;
}
}
@@ -465,12 +457,17 @@ execute_file_commands (struct file *file)
initialize_file_variables (file, 0);
set_file_variables (file);
set_file_variables (file, file->stem);
/* If this is a loaded dynamic object, unload it before remaking.
Some systems don't support overwriting a loaded object. */
if (file->loaded)
unload_file (file->name);
/* Some systems don't support overwriting a loaded object so if this one
unload it before remaking. Keep its name in .LOADED: it will be rebuilt
and loaded again. If rebuilding or loading again fail, then we'll exit
anyway and it won't matter. */
if (file->loaded && unload_file (file->name) == 0)
{
file->loaded = 0;
file->unloaded = 1;
}
/* Start the commands running. */
new_job (file);
@@ -479,11 +476,11 @@ execute_file_commands (struct file *file)
/* This is set while we are inside fatal_error_signal,
so things can avoid nonreentrant operations. */
int handling_fatal_signal = 0;
volatile sig_atomic_t handling_fatal_signal = 0;
/* Handle fatal signals. */
RETSIGTYPE
void
fatal_error_signal (int sig)
{
#ifdef __MSDOS__
@@ -508,7 +505,7 @@ fatal_error_signal (int sig)
#ifdef WINDOWS32
extern HANDLE main_thread;
/* Windows creates a sperate thread for handling Ctrl+C, so we need
/* Windows creates a separate thread for handling Ctrl+C, so we need
to suspend the main thread, or else we will have race conditions
when both threads call reap_children. */
if (main_thread)
@@ -516,12 +513,12 @@ fatal_error_signal (int sig)
DWORD susp_count = SuspendThread (main_thread);
if (susp_count != 0)
fprintf (stderr, "SuspendThread: suspend count = %ld\n", susp_count);
fprintf (stderr, "SuspendThread: suspend count = %lu\n", susp_count);
else if (susp_count == (DWORD)-1)
{
DWORD ierr = GetLastError ();
fprintf (stderr, "SuspendThread: error %ld: %s\n",
fprintf (stderr, "SuspendThread: error %lu: %s\n",
ierr, map_windows32_error_to_string (ierr));
}
}
@@ -532,6 +529,10 @@ fatal_error_signal (int sig)
It is blocked now while we run this handler. */
signal (sig, SIG_DFL);
temp_stdin_unlink ();
osync_clear ();
jobserver_clear ();
/* A termination signal won't be sent to the entire
process group, but it means we want to kill the children. */
@@ -596,7 +597,7 @@ fatal_error_signal (int sig)
#else
/* Signal the same code; this time it will really be fatal. The signal
will be unblocked when we return and arrive then to kill us. */
if (kill (getpid (), sig) < 0)
if (kill (make_pid (), sig) < 0)
pfatal_with_name ("kill");
#endif /* not WINDOWS32 */
#endif /* not Amiga */

View File

@@ -1,5 +1,5 @@
/* Definition of data structures describing shell commands for GNU Make.
Copyright (C) 1988-2019 Free Software Foundation, Inc.
Copyright (C) 1988-2022 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -12,7 +12,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
this program. If not, see <https://www.gnu.org/licenses/>. */
/* Structure that gives the commands to make a file
and information about where these commands came from. */
@@ -34,9 +34,12 @@ struct commands
#define COMMANDS_SILENT 2 /* Silent: @. */
#define COMMANDS_NOERROR 4 /* No errors: -. */
RETSIGTYPE fatal_error_signal (int sig);
struct file;
struct child;
void fatal_error_signal (int sig);
void execute_file_commands (struct file *file);
void print_commands (const struct commands *cmds);
void delete_child_targets (struct child *child);
void chop_commands (struct commands *cmds);
void set_file_variables (struct file *file);
void set_file_variables (struct file *file, const char *stem);

View File

@@ -1,5 +1,5 @@
/* config.h -- hand-massaged for Amiga -*-C-*-
Copyright (C) 1995-2019 Free Software Foundation, Inc.
Copyright (C) 1995-2022 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -12,7 +12,11 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
this program. If not, see <https://www.gnu.org/licenses/>. */
#include "mkconfig.h"
#define MK_AMIGAOS 1
/* Define if on AIX 3.
System headers sometimes define this.
@@ -37,8 +41,9 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Define for DGUX with <sys/dg_sys_info.h>. */
/* #undef DGUX */
/* Define if the 'getloadavg' function needs to be run setuid or setgid. */
/* #undef GETLOADAVG_PRIVILEGED */
/* Define to the widest signed integer type if <stdint.h> and <inttypes.h> do
not define. */
#define intmax_t long
/* Define to 'unsigned long' or 'unsigned long long'
if <inttypes.h> doesn't define. */
@@ -53,12 +58,12 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
/* #undef HAVE_ALLOCA_H */
/* Define to 1 if you have the declaration of 'getloadavg'. */
/* #undef HAVE_DECL_GETLOADAVG */
/* Define if your system has a working fnmatch function. */
/* #undef HAVE_FNMATCH */
/* Define if your system has its own 'getloadavg' function. */
/* #undef HAVE_GETLOADAVG */
/* Define if you have the getmntent function. */
/* #undef HAVE_GETMNTENT */
@@ -134,14 +139,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Define if you need to in order for stat and other things to work. */
/* #undef _POSIX_SOURCE */
/* Define as the return type of signal handlers (int or void). */
#define RETSIGTYPE void
/* Define if the setvbuf function takes the buffering type as its second
argument and the buffer pointer as the third, as on System V
before release 3. */
/* #undef SETVBUF_REVERSED */
/* If using the C implementation of alloca, define if you know the
direction of stack growth for your system; otherwise it will be
automatically deduced at run-time.
@@ -173,12 +170,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
instead of <sys/cpustats.h>. */
/* #undef UMAX4_3 */
/* Name of this package (needed by automake) */
#define PACKAGE "%PACKAGE%"
/* Version of this package (needed by automake) */
#define VERSION "%VERSION%"
/* Define to the name of the SCCS 'get' command. */
#define SCCS_GET "get"
@@ -261,6 +252,9 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Define if you have the strsignal function. */
/* #undef HAVE_STRSIGNAL */
/* Define if you have the strtoll function. */
/* #undef HAVE_STRTOLL */
/* Define if you have the wait3 function. */
/* #undef HAVE_WAIT3 */
@@ -324,10 +318,10 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Define if you have the sun library (-lsun). */
/* #undef HAVE_LIBSUN */
/* Output sync sypport */
/* Output sync support */
#define NO_OUTPUT_SYNC
/* Define for Case Insensitve behavior */
/* Define for Case Insensitive behavior */
#define HAVE_CASE_INSENSITIVE_FS
/* Build host information. */

View File

@@ -1,6 +1,6 @@
/* config.h-vms. Generated by hand by Klaus Kämpf <kkaempf@rmi.de> -*-C-*-
Copyright (C) 1996-2019 Free Software Foundation, Inc.
Copyright (C) 1996-2022 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -13,10 +13,11 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
this program. If not, see <https://www.gnu.org/licenses/>. */
/* config.h. Generated automatically by configure. */
/* config.h.in. Generated automatically from configure.ac by autoheader. */
#include "mkconfig.h"
#define MK_VMS 1
/* Pull in types.h here to get __CRTL_VER defined for old versions of the
compiler which don't define it. */
@@ -65,8 +66,9 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Define for DGUX with <sys/dg_sys_info.h>. */
/* #undef DGUX */
/* Define to 1 if the 'getloadavg' function needs to be run setuid or setgid. */
/* #undef GETLOADAVG_PRIVILEGED */
/* Define to the widest signed integer type if <stdint.h> and <inttypes.h> do
not define. */
#define intmax_t unsigned long
/* Define to 'unsigned long' or 'unsigned long long'
if <inttypes.h> doesn't define. */
@@ -81,15 +83,15 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix). */
/* #undef HAVE_ALLOCA_H */
/* Define to 1 if you have the declaration of 'getloadavg'. */
/* #undef HAVE_DECL_GETLOADAVG */
/* Define to 1 if you have the fdopen function. */
#define HAVE_FDOPEN 1
/* Define to 1 if your system has a working fnmatch function. */
/* #undef HAVE_FNMATCH */
/* Define to 1 if your system has its own 'getloadavg' function. */
/* #undef HAVE_GETLOADAVG */
/* Define to 1 if you have the getmntent function. */
/* #undef HAVE_GETMNTENT */
@@ -172,14 +174,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Define to 1 if you need to in order for stat and other things to work. */
/* #undef _POSIX_SOURCE */
/* Define as the return type of signal handlers (int or void). */
#define RETSIGTYPE void
/* Define to 1 if the setvbuf function takes the buffering type as its second
argument and the buffer pointer as the third, as on System V
before release 3. */
/* #undef SETVBUF_REVERSED */
/* If using the C implementation of alloca, define if you know the
direction of stack growth for your system; otherwise it will be
automatically deduced at run-time.
@@ -213,12 +207,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
instead of <sys/cpustats.h>. */
/* #undef UMAX4_3 */
/* Name of this package (needed by automake) */
#define PACKAGE "%PACKAGE%"
/* Version of this package (needed by automake) */
#define VERSION "%VERSION%"
/* Define to the name of the SCCS 'get' command. */
/* #undef SCCS_GET */
@@ -259,6 +247,9 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Define to 1 if you have the memmove function. */
#define HAVE_MEMMOVE 1
/* Define to 1 if you have the 'mkfifo' function. */
/* #undef HAVE_MKFIFO */
/* Define to 1 if you have the mktemp function. */
#define HAVE_MKTEMP 1
@@ -301,6 +292,9 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Define to 1 if you have the strsignal function. */
/* #undef HAVE_STRSIGNAL */
/* Define to 1 if you have the `strtoll' function. */
#define HAVE_STRTOLL 1
/* Define to 1 if you have the wait3 function. */
/* #undef HAVE_WAIT3 */
@@ -324,6 +318,9 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Define to 1 if you have the <memory.h> header file. */
/* #undef HAVE_MEMORY_H */
/* Define to 1 if you have the `mempcpy' function. */
/* #undef HAVE_MEMPCPY */
/* Define to 1 if you have the <ndir.h> header file. */
/* #undef HAVE_NDIR_H */

View File

@@ -1,6 +1,6 @@
/* config.h.W32 -- hand-massaged config.h file for Windows builds -*-C-*-
Copyright (C) 1996-2019 Free Software Foundation, Inc.
Copyright (C) 1996-2022 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -13,34 +13,32 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
this program. If not, see <https://www.gnu.org/licenses/>. */
#include "mkconfig.h"
#define MK_W32 1
/* Build for the WINDOWS32 API. */
#define WINDOWS32 1
/* Suppress some Visual C++ warnings.
Maybe after the code cleanup for ISO C we can remove some/all of these. */
#if _MSC_VER > 1000
# pragma warning(disable:4100) /* unreferenced formal parameter */
# pragma warning(disable:4102) /* unreferenced label */
# pragma warning(disable:4127) /* conditional expression is constant */
# pragma warning(disable:4130) /* logical operation on address of string constant */
# pragma warning(disable:4131) /* uses old-style declarator */
# pragma warning(disable:4702) /* unreachable code */
# define _CRT_SECURE_NO_WARNINGS /* function or variable may be unsafe */
# define _CRT_NONSTDC_NO_WARNINGS /* functions w/o a leading underscore */
# define _CRT_SECURE_NO_WARNINGS 1 /* function or variable may be unsafe */
# define _CRT_NONSTDC_NO_WARNINGS 1 /* functions w/o a leading underscore */
#endif
/* Define to 1 if the 'closedir' function returns void instead of 'int'. */
/* #undef CLOSEDIR_VOID */
/* Define to one of '_getb67', 'GETB67', 'getb67' for Cray-2 and Cray-YMP
systems. This function is required for 'alloca.c' support on those systems.
*/
/* #undef CRAY_STACKSEG_END */
/* Define to 1 if using 'alloca.c'. */
/* #undef C_ALLOCA */
/* Define to 1 if using 'getloadavg.c'. */
#define C_GETLOADAVG 1
/* Define to 1 for DGUX with <sys/dg_sys_info.h>. */
/* #undef DGUX */
@@ -51,15 +49,11 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Use high resolution file timestamps if nonzero. */
#define FILE_TIMESTAMP_HI_RES 0
/* Define to 1 if the 'getloadavg' function needs to be run setuid or setgid.
*/
/* #undef GETLOADAVG_PRIVILEGED */
/* Define to 1 if you have 'alloca', as a function or macro. */
/* Define to 1 if you have 'alloca' after including <alloca.h>, a header that
may be supplied by this distribution. */
#define HAVE_ALLOCA 1
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
*/
/* Define to 1 if <alloca.h> works. */
/* #undef HAVE_ALLOCA_H */
/* Define to 1 if you have the 'atexit' function. */
@@ -71,10 +65,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Define to 1 if you have the clock_gettime function. */
/* #undef HAVE_CLOCK_GETTIME */
/* Embed GNU Guile support. Windows build sets this on the
compilation command line. */
/* #undef HAVE_GUILE */
/* Define if the GNU dcgettext() function is already present or preinstalled.
*/
/* #undef HAVE_DCGETTEXT */
@@ -83,6 +73,21 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
don't. */
#define HAVE_DECL_BSD_SIGNAL 0
/* Define to 1 if you have the declaration of `dlerror', and to 0 if you
don't. */
#define HAVE_DECL_DLERROR 0
/* Define to 1 if you have the declaration of `dlopen', and to 0 if you don't.
*/
#define HAVE_DECL_DLOPEN 0
/* Define to 1 if you have the declaration of `dlsym', and to 0 if you don't.
*/
#define HAVE_DECL_DLSYM 0
/* Define to 1 if you have the declaration of 'getloadavg'. */
/* #undef HAVE_DECL_GETLOADAVG */
/* Define to 1 if you have the declaration of 'sys_siglist', and to 0 if you
don't. */
#define HAVE_DECL_SYS_SIGLIST 0
@@ -102,13 +107,16 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Define to 1 if you have the <direct.h> header file, and it defines getcwd()
and chdir().
*/
#if (defined(_MSC_VER) || defined(__BORLANDC__)) && !defined(__INTERIX)
#if (defined(_MSC_VER) || defined(__BORLANDC__) || defined(__TINYC__)) && !defined(__INTERIX)
# define HAVE_DIRECT_H 1
#endif
/* Use platform specific coding */
/* Support DOS-style pathnames. */
#define HAVE_DOS_PATHS 1
/* Define to 1 if you have the 'dup' function. */
#define HAVE_DUP 1
/* Define to 1 if you have the 'dup2' function. */
#define HAVE_DUP2 1
@@ -120,8 +128,8 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#define HAVE_FDOPEN 1
#endif
/* Define to 1 if you have the 'fileno' function. */
#define HAVE_FILENO 1
/* Define to 1 if you have the `fork' function. */
/* #undef HAVE_FORK */
/* Define to 1 if you have the 'getcwd' function. */
#define HAVE_GETCWD 1
@@ -135,9 +143,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Define to 1 if you have the 'gethostname' function. */
/* #undef HAVE_GETHOSTNAME */
/* Define to 1 if you have the 'getloadavg' function. */
/* #undef HAVE_GETLOADAVG */
/* Define to 1 if you have the 'getrlimit' function. */
/* #undef HAVE_GETRLIMIT */
@@ -149,6 +154,10 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#define HAVE_GETTIMEOFDAY 1
#endif
/* Embed GNU Guile support. Windows build sets this on the
compilation command line. */
/* #undef HAVE_GUILE */
/* Define if you have the iconv() function. */
/* #undef HAVE_ICONV */
@@ -157,17 +166,26 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#define HAVE_INTTYPES_H 1
#endif
/* Define to 1 if you have the `isatty' function. */
#define HAVE_ISATTY 1
/* Define to 1 if you have the 'dgc' library (-ldgc). */
/* #undef HAVE_LIBDGC */
/* Define to 1 if you have the 'kstat' library (-lkstat). */
/* #undef HAVE_LIBKSTAT */
/* Define to 1 if you have the `perfstat' library (-lperfstat). */
/* #undef HAVE_LIBPERFSTAT */
/* Define to 1 if you have the <limits.h> header file. */
#define HAVE_LIMITS_H 1
/* Define to 1 if you have the <locale.h> header file. */
/*#define HAVE_LOCALE_H 1*/
/* #undef HAVE_LOCALE_H */
/* Define to 1 if the system has the type 'long long int'. */
#define HAVE_LONG_LONG_INT 1
/* Define to 1 if you have the 'lstat' function. */
/* #undef HAVE_LSTAT */
@@ -178,9 +196,24 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the `mempcpy' function. */
/* #undef HAVE_MEMPCPY */
/* Define to 1 if you have the `memrchr' function. */
/* #undef HAVE_MEMRCHR */
/* Define to 1 if you have the <minix/config.h> header file. */
/* #undef HAVE_MINIX_CONFIG_H */
/* Define to 1 if you have the 'mkfifo' function. */
/* #undef HAVE_MKFIFO */
/* Define to 1 if you have the 'mkstemp' function. */
/* #undef HAVE_MKSTEMP */
/* Define to 1 if you have the `mkstemp' function. */
/* #undef HAVE_MKSTEMP */
/* Define to 1 if you have the 'mktemp' function. */
#define HAVE_MKTEMP 1
@@ -193,6 +226,15 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Define to 1 if you have the 'pipe' function. */
/* #undef HAVE_PIPE */
/* Define to 1 if you have the `posix_spawn' function. */
/* #undef HAVE_POSIX_SPAWN */
/* Define to 1 if you have the `posix_spawnattr_setsigmask' function. */
/* #undef HAVE_POSIX_SPAWNATTR_SETSIGMASK */
/* Define to 1 if you have the `pselect' function. */
/* #undef HAVE_PSELECT */
/* Define to 1 if you have the 'pstat_getdynamic' function. */
/* #undef HAVE_PSTAT_GETDYNAMIC */
@@ -214,9 +256,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Define to 1 if you have the 'setlinebuf' function. */
/* #undef HAVE_SETLINEBUF */
/* Define to 1 if you have the 'setlocale' function. */
/*#define HAVE_SETLOCALE 1*/
/* Define to 1 if you have the 'setregid' function. */
/* #undef HAVE_SETREGID */
@@ -238,16 +277,25 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Define to 1 if you have the 'socket' function. */
/* #undef HAVE_SOCKET */
/* Define to 1 if you have the <spawn.h> header file. */
/* #undef HAVE_SPAWN_H */
/* Define to 1 if you have the <stdint.h> header file. */
#ifdef __MINGW32__
#define HAVE_STDINT_H 1
#endif
/* Define to 1 if you have the <stdio.h> header file. */
#define HAVE_STDIO_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the `stpcpy' function. */
/* #undef HAVE_STPCPY */
/* Define to 1 if you have the 'strcasecmp' function. */
#ifdef __MINGW32__
#if defined(__MINGW32__) || defined(__TINYC__)
#define HAVE_STRCASECMP 1
#endif
@@ -261,6 +309,9 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Define to 1 if you have the 'strdup' function. */
#define HAVE_STRDUP 1
/* Define to 1 if you have the `strerror' function. */
#define HAVE_STRERROR 1
/* Define to 1 if you have the 'stricmp' function. */
#define HAVE_STRICMP 1
@@ -273,7 +324,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the 'strncasecmp' function. */
#ifdef __MINGW32__
#if defined(__MINGW32__) || defined(__TINYC__)
#define HAVE_STRNCASECMP 1
#endif
@@ -291,19 +342,13 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Define to 1 if you have the 'strsignal' function. */
/* #undef HAVE_STRSIGNAL */
/* Define to 1 if you have the `strtoll' function. */
#define HAVE_STRTOLL 1
/* Define to 1 if `d_type' is a member of `struct dirent'. */
#define HAVE_STRUCT_DIRENT_D_TYPE 1
/* Define to 1 if you have the `isatty' function. */
#define HAVE_ISATTY 1
/* Define to 1 if you have the `ttyname' function. */
#define HAVE_TTYNAME 1
char *ttyname (int);
/* Define to 1 if you have the `umask' function. */
#ifdef __MINGW32__
# define HAVE_UMASK 1
/* SV 57152: MinGW64 version of dirent doesn't support d_type. */
#ifndef __MINGW64__
# define HAVE_STRUCT_DIRENT_D_TYPE 1
#endif
/* Define to 1 if 'n_un.n_name' is a member of 'struct nlist'. */
@@ -313,6 +358,12 @@ char *ttyname (int);
*/
/* #undef HAVE_SYS_DIR_H */
/* Define to 1 if you have the <sys/file.h> header file. */
/* #undef HAVE_SYS_FILE_H */
/* Define to 1 if you have the <sys/loadavg.h> header file. */
/* #undef HAVE_SYS_LOADAVG_H */
/* Define to 1 if you have the <sys/ndir.h> header file, and it defines 'DIR'.
*/
/* #undef HAVE_SYS_NDIR_H */
@@ -325,6 +376,9 @@ char *ttyname (int);
/* Define to 1 if you have the <sys/resource.h> header file. */
/* #undef HAVE_SYS_RESOURCE_H */
/* Define to 1 if you have the <sys/select.h> header file. */
/* #undef HAVE_SYS_SELECT_H */
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
@@ -342,6 +396,21 @@ char *ttyname (int);
/* Define to 1 if you have the <sys/wait.h> header file. */
/* #undef HAVE_SYS_WAIT_H */
/* Define to 1 if you have the `ttyname' function. */
#define HAVE_TTYNAME 1
char *ttyname (int);
/* Define to 1 if the system has the type `intmax_t'. */
#define HAVE_INTMAX_T 1
/* Define to 1 if the system has the type `uintmax_t'. */
#define HAVE_UINTMAX_T 1
/* Define to 1 if you have the `umask' function. */
#if defined(__MINGW32__) || defined(__TINYC__)
# define HAVE_UMASK 1
#endif
/* Define to 1 if you have the \'union wait' type in <sys/wait.h>. */
/* #undef HAVE_UNION_WAIT */
@@ -350,12 +419,33 @@ char *ttyname (int);
#define HAVE_UNISTD_H 1
#endif
/* Define to 1 if the system has the type 'unsigned long long int'. */
#define HAVE_UNSIGNED_LONG_LONG_INT 1
/* Define to 1 if you have the `vfork' function. */
/* #undef HAVE_VFORK */
/* Define to 1 if you have the <vfork.h> header file. */
/* #undef HAVE_VFORK_H */
/* Define to 1 if you have the 'wait3' function. */
/* #undef HAVE_WAIT3 */
/* Define to 1 if you have the 'waitpid' function. */
/* #undef HAVE_WAITPID */
/* Define to 1 if you have the <wchar.h> header file. */
/* #undef HAVE_WCHAR_H */
/* Define to 1 if `fork' works. */
/* #undef HAVE_WORKING_FORK */
/* Define to 1 if `vfork' works. */
/* #undef HAVE_WORKING_VFORK */
/* Define to 1 if the system has the type `_Bool'. */
/* #undef HAVE__BOOL */
/* Build host information. */
#define MAKE_HOST "Windows32"
@@ -378,38 +468,15 @@ char *ttyname (int);
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
/* #undef NO_MINUS_C_MINUS_O */
/* Name of this package (needed by automake) */
#define PACKAGE "%PACKAGE%"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "bug-make@gnu.org"
/* Define to the full name of this package. */
#define PACKAGE_NAME "GNU make"
/* Define to the home page for this package. */
#define PACKAGE_URL "http://www.gnu.org/software/make/"
/* Define to the version of this package. */
#define PACKAGE_VERSION "%VERSION%"
/* Define to the character that separates directories in PATH. */
#define PATH_SEPARATOR_CHAR ';'
/* Define as the return type of signal handlers ('int' or 'void'). */
#define RETSIGTYPE void
/* Define to the name of the SCCS 'get' command. */
#define SCCS_GET "echo no sccs get"
/* Define this if the SCCS 'get' command understands the '-G<file>' option. */
/* #undef SCCS_GET_MINUS_G */
/* Define to 1 if the 'setvbuf' function takes the buffering type as its
second argument and the buffer pointer as the third, as on System V before
release 3. */
/* #undef SETVBUF_REVERSED */
/* If using the C implementation of alloca, define if you know the
direction of stack growth for your system; otherwise it will be
automatically deduced at run time.
@@ -430,11 +497,6 @@ char *ttyname (int);
/* Define to 1 on System V Release 4. */
/* #undef SVR4 */
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#ifdef __MINGW32__
#define TIME_WITH_SYS_TIME 1
#endif
/* Define to 1 for Encore UMAX. */
/* #undef UMAX */
@@ -442,9 +504,6 @@ char *ttyname (int);
<sys/cpustats.h>. */
/* #undef UMAX4_3 */
/* Version number of package */
#define VERSION "%VERSION%"
/* Define if using the dmalloc debugging malloc package */
/* #undef WITH_DMALLOC */
@@ -483,6 +542,14 @@ char *ttyname (int);
# define __USE_MINGW_ANSI_STDIO 1
#endif
/* Number of bits in a timestamp, on hosts where this is settable. */
/* #undef _TIME_BITS */
/* For 64-bit time_t on 32-bit mingw. */
#ifdef __MINGW32__
# define __MINGW_USE_VC2005_COMPAT 1
#endif
#include <sys/types.h>
/* Define to 'int' if <sys/types.h> doesn't define. */
@@ -504,9 +571,10 @@ char *ttyname (int);
/* Define to 'int' if <sys/types.h> doesn't define. */
#define uid_t int
/* Define uintmax_t if not defined in <stdint.h> or <inttypes.h>. */
/* Define {u,}intmax_t if not defined in <stdint.h> or <inttypes.h>. */
#if !HAVE_STDINT_H && !HAVE_INTTYPES_H
#define uintmax_t unsigned long
#define intmax_t long long
#define uintmax_t unsigned long long
#endif
/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
@@ -522,10 +590,14 @@ char *ttyname (int);
/*
* If you have a shell that does not grok 'sh -c quoted-command-line'
* correctly, you need this setting. Please see below for specific
* shell support.
* correctly, you need this setting; it is the default for tcc.
* Please see below for specific shell support.
*/
#if defined(__TINYC__)
#define BATCH_MODE_ONLY_SHELL 1
#else
/*#define BATCH_MODE_ONLY_SHELL 1 */
#endif
/*
* Define if you have the Cygnus "Cygwin" GNU Windows32 tool set.

View File

@@ -1,6 +1,6 @@
/* configh.dos -- hand-massaged config.h file for MS-DOS builds -*-C-*-
Copyright (C) 1994-2019 Free Software Foundation, Inc.
Copyright (C) 1994-2022 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -13,7 +13,11 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
this program. If not, see <https://www.gnu.org/licenses/>. */
#include "mkconfig.h"
#define MK_DJGPP 1
/* Include this header to make __DJGPP_MINOR__ available because DJGPP ports
of GCC 4.3.0 and later no longer do it automatically. */
@@ -49,6 +53,9 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Define to 1 if you have the 'getgroups' function. */
#define HAVE_GETGROUPS 1
/* Define to 1 if the system has the type 'long long int'. */
#define HAVE_LONG_LONG_INT 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
@@ -66,13 +73,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#define SCCS_GET "get"
/* Define to 'unsigned long' or 'unsigned long long'
if <inttypes.h> doesn't define. */
#define uintmax_t unsigned long long
/* Define the type of the first arg to select(). */
#define fd_set_size_t int
/* Define to 1 if you have the select function. */
#define HAVE_SELECT 1
@@ -82,35 +82,30 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Define to 1 if you have the 'strncasecmp' function. */
#define HAVE_STRNCASECMP 1
/* Name of the package */
#define PACKAGE "%PACKAGE%"
/* Define to 1 if you have the `strtoll' function. */
#define HAVE_STRTOLL 1
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "bug-%PACKAGE%@gnu.org"
/* Define to the full name of this package. */
#define PACKAGE_NAME "GNU %PACKAGE%"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "GNU %PACKAGE% %VERSION%"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "%PACKAGE%"
/* Define to the version of this package. */
#define PACKAGE_VERSION "%VERSION%"
/* Output sync sypport */
#define NO_OUTPUT_SYNC
/* Version number of package */
#define VERSION "%VERSION%"
/* Output sync support */
#define NO_OUTPUT_SYNC 1
/* Build host information. */
#define MAKE_HOST "i386-pc-msdosdjgpp"
/* Grok DOS paths (drive specs and backslash path element separators) */
#define HAVE_DOS_PATHS
#define HAVE_DOS_PATHS 1
/* Define the type of the first arg to select(). */
#define fd_set_size_t int
/* Define to the widest signed integer type if <stdint.h> and <inttypes.h> do
not define. */
#define intmax_t long long
/* Define to `int' if <sys/types.h> does not define. */
#if __DJGPP__ == 2 && __DJGPP_MINOR__ < 5
#define ssize_t int
#endif
/* Define to 'unsigned long' or 'unsigned long long'
if <inttypes.h> doesn't define. */
#define uintmax_t unsigned long long

View File

@@ -1,5 +1,5 @@
/* Debugging macros and interface.
Copyright (C) 1999-2019 Free Software Foundation, Inc.
Copyright (C) 1999-2022 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -12,13 +12,15 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
this program. If not, see <https://www.gnu.org/licenses/>. */
#define DB_NONE (0x000)
#define DB_BASIC (0x001)
#define DB_VERBOSE (0x002)
#define DB_JOBS (0x004)
#define DB_IMPLICIT (0x008)
#define DB_PRINT (0x010)
#define DB_WHY (0x020)
#define DB_MAKEFILES (0x100)
#define DB_ALL (0xfff)

View File

@@ -1,5 +1,5 @@
/* Data base of default implicit rules for GNU Make.
Copyright (C) 1988-2019 Free Software Foundation, Inc.
Copyright (C) 1988-2022 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -12,7 +12,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
this program. If not, see <https://www.gnu.org/licenses/>. */
#include "makeint.h"
@@ -506,7 +506,7 @@ static const char *default_variables[] =
"COMPILE.s", "$(AS) $(ASFLAGS) $(TARGET_MACH)",
"LINK.S", "$(CC) $(ASFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_MACH)",
"COMPILE.S", "$(CC) $(ASFLAGS) $(CPPFLAGS) $(TARGET_MACH) -c",
"PREPROCESS.S", "$(CC) -E $(CPPFLAGS)",
"PREPROCESS.S", "$(CPP) $(CPPFLAGS)",
"PREPROCESS.F", "$(FC) $(FFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -F",
"PREPROCESS.r", "$(FC) $(FFLAGS) $(RFLAGS) $(TARGET_ARCH) -F",
"LINT.c", "$(LINT) $(LINTFLAGS) $(CPPFLAGS) $(TARGET_ARCH)",
@@ -518,7 +518,12 @@ static const char *default_variables[] =
#else /* !VMS */
"AR", "ar",
"ARFLAGS", "rv",
#ifdef _AIX
/* AIX requires object file format specification: choose -Xany. */
"ARFLAGS", "-Xany -rv",
#else
"ARFLAGS", "-rv",
#endif
"AS", "as",
#ifdef GCC_IS_NATIVE
"CC", "gcc",
@@ -636,7 +641,7 @@ static const char *default_variables[] =
"COMPILE.s", "$(AS) $(ASFLAGS) $(TARGET_MACH)",
"LINK.S", "$(CC) $(ASFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_MACH)",
"COMPILE.S", "$(CC) $(ASFLAGS) $(CPPFLAGS) $(TARGET_MACH) -c",
"PREPROCESS.S", "$(CC) -E $(CPPFLAGS)",
"PREPROCESS.S", "$(CPP) $(CPPFLAGS)",
"PREPROCESS.F", "$(FC) $(FFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -F",
"PREPROCESS.r", "$(FC) $(FFLAGS) $(RFLAGS) $(TARGET_ARCH) -F",
"LINT.c", "$(LINT) $(LINTFLAGS) $(CPPFLAGS) $(TARGET_ARCH)",
@@ -663,7 +668,7 @@ static const char *default_variables[] =
#endif /* !VMS */
/* Make this assignment to avoid undefined variable warnings. */
"GNUMAKEFLAGS", "",
GNUMAKEFLAGS_NAME, "",
0, 0
};

View File

@@ -1,5 +1,5 @@
/* Definitions of dependency data structures for GNU Make.
Copyright (C) 1988-2019 Free Software Foundation, Inc.
Copyright (C) 1988-2022 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -12,7 +12,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
this program. If not, see <https://www.gnu.org/licenses/>. */
/* Structure used in chains of names, for parsing and globbing. */
@@ -30,25 +30,32 @@ struct nameseq
These flags are saved in the 'flags' field of each
'struct goaldep' in the chain returned by 'read_all_makefiles'. */
#define RM_NOFLAG 0
#define RM_NO_DEFAULT_GOAL (1 << 0) /* Do not set default goal. */
#define RM_INCLUDED (1 << 1) /* Search makefile search path. */
#define RM_DONTCARE (1 << 2) /* No error if it doesn't exist. */
#define RM_NO_TILDE (1 << 3) /* Don't expand ~ in file name. */
#define RM_NOFLAG 0
/* Structure representing one dependency of a file.
Each struct file's 'deps' points to a chain of these, through 'next'.
'stem' is the stem for this dep line of static pattern rule or NULL. */
'stem' is the stem for this dep line of static pattern rule or NULL.
explicit is set when implicit rule search is performed and the prerequisite
does not contain %. When explicit is set the file is not intermediate. */
#define DEP(_t) \
NAMESEQ (_t); \
struct file *file; \
_t *shuf; \
const char *stem; \
unsigned int flags : 8; \
unsigned int changed : 1; \
unsigned int ignore_mtime : 1; \
unsigned int staticpattern : 1; \
unsigned int need_2nd_expansion : 1
unsigned int need_2nd_expansion : 1; \
unsigned int ignore_automatic_vars : 1; \
unsigned int is_explicit : 1; \
unsigned int wait_here : 1
struct dep
{
@@ -74,6 +81,8 @@ struct goaldep
#define PARSEFS_NOGLOB 0x0004
#define PARSEFS_EXISTS 0x0008
#define PARSEFS_NOCACHE 0x0010
#define PARSEFS_ONEWORD 0x0020
#define PARSEFS_WAIT 0x0040
#define PARSE_FILE_SEQ(_s,_t,_c,_p,_f) \
(_t *)parse_file_seq ((_s),sizeof (_t),(_c),(_p),(_f))
@@ -93,24 +102,23 @@ char *tilde_expand (const char *name);
struct nameseq *ar_glob (const char *arname, const char *member_pattern, size_t size);
#endif
#define dep_name(d) ((d)->name ? (d)->name : (d)->file->name)
#define dep_name(d) ((d)->name ? (d)->name : (d)->file->name)
#define alloc_seq_elt(_t) xcalloc (sizeof (_t))
#define alloc_seq_elt(_t) xcalloc (sizeof (_t))
void free_ns_chain (struct nameseq *n);
#if defined(MAKE_MAINTAINER_MODE) && defined(__GNUC__)
#if defined(MAKE_MAINTAINER_MODE) && defined(__GNUC__) && !defined(__STRICT_ANSI__)
/* Use inline to get real type-checking. */
#define SI static inline
SI struct nameseq *alloc_ns() { return alloc_seq_elt (struct nameseq); }
SI struct dep *alloc_dep() { return alloc_seq_elt (struct dep); }
SI struct goaldep *alloc_goaldep() { return alloc_seq_elt (struct goaldep); }
SI struct nameseq *alloc_ns (void) { return alloc_seq_elt (struct nameseq); }
SI struct dep *alloc_dep (void) { return alloc_seq_elt (struct dep); }
SI struct goaldep *alloc_goaldep (void) { return alloc_seq_elt (struct goaldep); }
SI void free_ns(struct nameseq *n) { free (n); }
SI void free_dep(struct dep *d) { free_ns ((struct nameseq *)d); }
SI void free_goaldep(struct goaldep *g) { free_dep ((struct dep *)g); }
SI void free_dep_chain(struct dep *d) { free_ns_chain((struct nameseq *)d); }
SI void free_goal_chain(struct goaldep *g) { free_dep_chain((struct dep *)g); }
SI void free_ns (struct nameseq *n) { free (n); }
SI void free_dep (struct dep *d) { free_ns ((struct nameseq *)d); }
SI void free_goaldep (struct goaldep *g) { free_dep ((struct dep *)g); }
SI void free_dep_chain (struct dep *d) { free_ns_chain((struct nameseq *)d); }
SI void free_goal_chain (struct goaldep *g) { free_dep_chain((struct dep *)g); }
#else
# define alloc_ns() alloc_seq_elt (struct nameseq)
# define alloc_dep() alloc_seq_elt (struct dep)

339
src/dir.c
View File

@@ -1,5 +1,5 @@
/* Directory hashing for GNU Make.
Copyright (C) 1988-2019 Free Software Foundation, Inc.
Copyright (C) 1988-2022 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -12,12 +12,13 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
this program. If not, see <https://www.gnu.org/licenses/>. */
#include "makeint.h"
#include "hash.h"
#include "filedef.h"
#include "dep.h"
#include "debug.h"
#ifdef HAVE_DIRENT_H
# include <dirent.h>
@@ -175,7 +176,7 @@ vms_hash (const char *name)
while (*name)
{
unsigned char uc = *name;
unsigned char uc = (unsigned char) *name;
int g;
#ifdef HAVE_CASE_INSENSITIVE_FS
h = (h << 4) + (isupper (uc) ? tolower (uc) : uc);
@@ -232,6 +233,12 @@ vmsstat_dir (const char *name, struct stat *st)
#endif /* _USE_STD_STAT */
#endif /* VMS */
/* Never have more than this many directories open at once. */
#define MAX_OPEN_DIRECTORIES 10
static unsigned int open_directories = 0;
/* Hash table of directories. */
#ifndef DIRECTORY_BUCKETS
@@ -262,9 +269,25 @@ struct directory_contents
# endif
#endif /* WINDOWS32 */
struct hash_table dirfiles; /* Files in this directory. */
unsigned long counter; /* command_count value when last read. */
DIR *dirstream; /* Stream reading this directory. */
};
static struct directory_contents *
clear_directory_contents (struct directory_contents *dc)
{
dc->counter = 0;
if (dc->dirstream)
{
--open_directories;
closedir (dc->dirstream);
dc->dirstream = 0;
}
hash_free (&dc->dirfiles, 1);
return NULL;
}
static unsigned long
directory_contents_hash_1 (const void *key_0)
{
@@ -363,7 +386,9 @@ static struct hash_table directory_contents;
struct directory
{
const char *name; /* Name of the directory. */
const char *name; /* Name of the directory. */
unsigned long counter; /* command_count value when last read.
Used for non-existent directories. */
/* The directory's contents. This data may be shared by several
entries in the hash table, which refer to the same directory
@@ -393,12 +418,6 @@ directory_hash_cmp (const void *x, const void *y)
/* Table of directories hashed by name. */
static struct hash_table directories;
/* Never have more than this many directories open at once. */
#define MAX_OPEN_DIRECTORIES 10
static unsigned int open_directories = 0;
/* Hash table of files in each directory. */
@@ -449,150 +468,162 @@ find_directory (const char *name)
struct directory *dir;
struct directory **dir_slot;
struct directory dir_key;
struct directory_contents *dc;
struct directory_contents **dc_slot;
struct directory_contents dc_key;
struct stat st;
int r;
#ifdef WINDOWS32
char *w32_path;
#endif
dir_key.name = name;
dir_slot = (struct directory **) hash_find_slot (&directories, &dir_key);
dir = *dir_slot;
if (HASH_VACANT (dir))
if (!HASH_VACANT (dir))
{
unsigned long ctr = dir->contents ? dir->contents->counter : dir->counter;
/* No commands have run since we parsed this directory so it's good. */
if (ctr == command_count)
return dir;
DB (DB_VERBOSE, ("Directory %s cache invalidated (count %lu != command %lu)\n",
name, ctr, command_count));
if (dir->contents)
clear_directory_contents (dir->contents);
}
else
{
/* The directory was not found. Create a new entry for it. */
const char *p = name + strlen (name);
struct stat st;
int r;
size_t len = strlen (name);
dir = xmalloc (sizeof (struct directory));
#if defined(HAVE_CASE_INSENSITIVE_FS) && defined(VMS)
/* Todo: Why is this only needed on VMS? */
{
char *lname = downcase_inplace (xstrdup (name));
dir->name = strcache_add_len (lname, p - name);
dir->name = strcache_add_len (lname, len);
free (lname);
}
#else
dir->name = strcache_add_len (name, p - name);
dir->name = strcache_add_len (name, len);
#endif
hash_insert_at (&directories, dir, dir_slot);
/* The directory is not in the name hash table.
Find its device and inode numbers, and look it up by them. */
}
dir->contents = NULL;
dir->counter = command_count;
/* See if the directory exists. */
#if defined(WINDOWS32)
{
char tem[MAXPATHLEN], *tstart, *tend;
{
char tem[MAX_PATH+1], *tstart, *tend;
size_t len = strlen (name);
/* Remove any trailing slashes. Windows32 stat fails even on
valid directories if they end in a slash. */
memcpy (tem, name, p - name + 1);
tstart = tem;
if (tstart[1] == ':')
tstart += 2;
for (tend = tem + (p - name - 1);
tend > tstart && (*tend == '/' || *tend == '\\');
tend--)
*tend = '\0';
/* Remove any trailing slashes. Windows32 stat fails even on
valid directories if they end in a slash. */
memcpy (tem, name, len + 1);
tstart = tem;
if (tstart[1] == ':')
tstart += 2;
for (tend = tem + (len - 1); tend > tstart && ISDIRSEP (*tend); tend--)
*tend = '\0';
r = stat (tem, &st);
}
r = stat (tem, &st);
}
#else
EINTRLOOP (r, stat (name, &st));
EINTRLOOP (r, stat (name, &st));
#endif
if (r < 0)
{
/* Couldn't stat the directory. Mark this by
setting the 'contents' member to a nil pointer. */
dir->contents = 0;
}
if (r < 0)
/* Couldn't stat the directory; nothing else to do. */
return dir;
/* Search the contents hash table; device and inode are the key. */
memset (&dc_key, '\0', sizeof (dc_key));
dc_key.dev = st.st_dev;
#ifdef WINDOWS32
dc_key.path_key = w32_path = w32ify (name, 1);
dc_key.ctime = st.st_ctime;
#else
# ifdef VMS_INO_T
dc_key.ino[0] = st.st_ino[0];
dc_key.ino[1] = st.st_ino[1];
dc_key.ino[2] = st.st_ino[2];
# else
dc_key.ino = st.st_ino;
# endif
#endif
dc_slot = (struct directory_contents **) hash_find_slot (&directory_contents, &dc_key);
dc = *dc_slot;
if (HASH_VACANT (dc))
{
/* Nope; this really is a directory we haven't seen before. */
#ifdef WINDOWS32
char fs_label[BUFSIZ];
char fs_type[BUFSIZ];
unsigned long fs_serno;
unsigned long fs_flags;
unsigned long fs_len;
#endif
/* Enter it in the contents hash table. */
dc = xcalloc (sizeof (struct directory_contents));
*dc = dc_key;
#ifdef WINDOWS32
dc->path_key = xstrdup (w32_path);
dc->mtime = st.st_mtime;
/* NTFS is the only WINDOWS32 filesystem that bumps mtime on a
directory when files are added/deleted from a directory. */
w32_path[3] = '\0';
if (GetVolumeInformation (w32_path, fs_label, sizeof (fs_label),
&fs_serno, &fs_len, &fs_flags, fs_type,
sizeof (fs_type)) == FALSE)
dc->fs_flags = FS_UNKNOWN;
else if (!strcmp (fs_type, "FAT"))
dc->fs_flags = FS_FAT;
else if (!strcmp (fs_type, "NTFS"))
dc->fs_flags = FS_NTFS;
else
dc->fs_flags = FS_UNKNOWN;
#endif /* WINDOWS32 */
hash_insert_at (&directory_contents, dc, dc_slot);
}
/* Point the name-hashed entry for DIR at its contents data. */
dir->contents = dc;
/* If the contents have changed, we need to reseed. */
if (dc->counter != command_count)
{
if (dc->counter)
clear_directory_contents (dc);
dc->counter = command_count;
ENULLLOOP (dc->dirstream, opendir (name));
if (dc->dirstream == 0)
/* Couldn't open the directory. Mark this by setting the
'files' member to a nil pointer. */
dc->dirfiles.ht_vec = 0;
else
{
/* Search the contents hash table; device and inode are the key. */
#ifdef WINDOWS32
char *w32_path;
#endif
struct directory_contents *dc;
struct directory_contents **dc_slot;
struct directory_contents dc_key;
dc_key.dev = st.st_dev;
#ifdef WINDOWS32
dc_key.path_key = w32_path = w32ify (name, 1);
dc_key.ctime = st.st_ctime;
#else
# ifdef VMS_INO_T
dc_key.ino[0] = st.st_ino[0];
dc_key.ino[1] = st.st_ino[1];
dc_key.ino[2] = st.st_ino[2];
# else
dc_key.ino = st.st_ino;
# endif
#endif
dc_slot = (struct directory_contents **) hash_find_slot (&directory_contents, &dc_key);
dc = *dc_slot;
if (HASH_VACANT (dc))
{
/* Nope; this really is a directory we haven't seen before. */
#ifdef WINDOWS32
char fs_label[BUFSIZ];
char fs_type[BUFSIZ];
unsigned long fs_serno;
unsigned long fs_flags;
unsigned long fs_len;
#endif
dc = (struct directory_contents *)
xmalloc (sizeof (struct directory_contents));
/* Enter it in the contents hash table. */
dc->dev = st.st_dev;
#ifdef WINDOWS32
dc->path_key = xstrdup (w32_path);
dc->ctime = st.st_ctime;
dc->mtime = st.st_mtime;
/* NTFS is the only WINDOWS32 filesystem that bumps mtime on a
directory when files are added/deleted from a directory. */
w32_path[3] = '\0';
if (GetVolumeInformation (w32_path, fs_label, sizeof (fs_label),
&fs_serno, &fs_len, &fs_flags, fs_type,
sizeof (fs_type)) == FALSE)
dc->fs_flags = FS_UNKNOWN;
else if (!strcmp (fs_type, "FAT"))
dc->fs_flags = FS_FAT;
else if (!strcmp (fs_type, "NTFS"))
dc->fs_flags = FS_NTFS;
else
dc->fs_flags = FS_UNKNOWN;
#else
# ifdef VMS_INO_T
dc->ino[0] = st.st_ino[0];
dc->ino[1] = st.st_ino[1];
dc->ino[2] = st.st_ino[2];
# else
dc->ino = st.st_ino;
# endif
#endif /* WINDOWS32 */
hash_insert_at (&directory_contents, dc, dc_slot);
ENULLLOOP (dc->dirstream, opendir (name));
if (dc->dirstream == 0)
/* Couldn't open the directory. Mark this by setting the
'files' member to a nil pointer. */
dc->dirfiles.ht_vec = 0;
else
{
hash_init (&dc->dirfiles, DIRFILE_BUCKETS,
dirfile_hash_1, dirfile_hash_2, dirfile_hash_cmp);
/* Keep track of how many directories are open. */
++open_directories;
if (open_directories == MAX_OPEN_DIRECTORIES)
/* We have too many directories open already.
Read the entire directory and then close it. */
dir_contents_file_exists_p (dc, 0);
}
}
/* Point the name-hashed entry for DIR at its contents data. */
dir->contents = dc;
hash_init (&dc->dirfiles, DIRFILE_BUCKETS,
dirfile_hash_1, dirfile_hash_2, dirfile_hash_cmp);
/* Keep track of how many directories are open. */
++open_directories;
if (open_directories == MAX_OPEN_DIRECTORIES)
/* We have too many directories open already.
Read the entire directory and then close it. */
dir_contents_file_exists_p (dc, 0);
}
}
@@ -834,7 +865,7 @@ file_exists_p (const char *name)
#ifdef HAVE_DOS_PATHS
/* d:/ and d: are *very* different... */
if (dirend < name + 3 && name[1] == ':' &&
(*dirend == '/' || *dirend == '\\' || *dirend == ':'))
(ISDIRSEP (*dirend) || *dirend == ':'))
dirend++;
#endif
p = alloca (dirend - name + 1);
@@ -910,7 +941,7 @@ file_impossible (const char *filename)
#ifdef HAVE_DOS_PATHS
/* d:/ and d: are *very* different... */
if (dirend < p + 3 && p[1] == ':' &&
(*dirend == '/' || *dirend == '\\' || *dirend == ':'))
(ISDIRSEP (*dirend) || *dirend == ':'))
dirend++;
#endif
cp = alloca (dirend - p + 1);
@@ -1008,7 +1039,7 @@ file_impossible_p (const char *filename)
#ifdef HAVE_DOS_PATHS
/* d:/ and d: are *very* different... */
if (dirend < filename + 3 && filename[1] == ':' &&
(*dirend == '/' || *dirend == '\\' || *dirend == ':'))
(ISDIRSEP (*dirend) || *dirend == ':'))
dirend++;
#endif
cp = alloca (dirend - filename + 1);
@@ -1069,6 +1100,9 @@ print_dir_data_base (void)
unsigned int impossible;
struct directory **dir_slot;
struct directory **dir_end;
#ifdef WINDOWS32
char buf[INTSTR_LENGTH + 1];
#endif
puts (_("\n# Directories\n"));
@@ -1084,24 +1118,19 @@ print_dir_data_base (void)
if (dir->contents == 0)
printf (_("# %s: could not be stat'd.\n"), dir->name);
else if (dir->contents->dirfiles.ht_vec == 0)
{
#ifdef WINDOWS32
printf (_("# %s (key %s, mtime %I64u): could not be opened.\n"),
dir->name, dir->contents->path_key,
(unsigned long long)dir->contents->mtime);
#else /* WINDOWS32 */
#ifdef VMS_INO_T
printf (_("# %s (device %d, inode [%d,%d,%d]): could not be opened.\n"),
dir->name, dir->contents->dev,
dir->contents->ino[0], dir->contents->ino[1],
dir->contents->ino[2]);
printf (_("# %s (key %s, mtime %s): could not be opened.\n"),
dir->name, dir->contents->path_key,
make_ulltoa ((unsigned long long)dir->contents->mtime, buf));
#elif defined(VMS_INO_T)
printf (_("# %s (device %d, inode [%d,%d,%d]): could not be opened.\n"),
dir->name, dir->contents->dev,
dir->contents->ino[0], dir->contents->ino[1],
dir->contents->ino[2]);
#else
printf (_("# %s (device %ld, inode %ld): could not be opened.\n"),
dir->name, (long int) dir->contents->dev,
(long int) dir->contents->ino);
printf (_("# %s (device %ld, inode %ld): could not be opened.\n"),
dir->name, (long) dir->contents->dev, (long) dir->contents->ino);
#endif
#endif /* WINDOWS32 */
}
else
{
unsigned int f = 0;
@@ -1123,21 +1152,18 @@ print_dir_data_base (void)
}
}
#ifdef WINDOWS32
printf (_("# %s (key %s, mtime %I64u): "),
printf (_("# %s (key %s, mtime %s): "),
dir->name, dir->contents->path_key,
(unsigned long long)dir->contents->mtime);
#else /* WINDOWS32 */
#ifdef VMS_INO_T
make_ulltoa ((unsigned long long)dir->contents->mtime, buf));
#elif defined(VMS_INO_T)
printf (_("# %s (device %d, inode [%d,%d,%d]): "),
dir->name, dir->contents->dev,
dir->contents->ino[0], dir->contents->ino[1],
dir->contents->ino[2]);
#else
printf (_("# %s (device %ld, inode %ld): "),
dir->name,
printf (_("# %s (device %ld, inode %ld): "), dir->name,
(long)dir->contents->dev, (long)dir->contents->ino);
#endif
#endif /* WINDOWS32 */
if (f == 0)
fputs (_("No"), stdout);
else
@@ -1286,13 +1312,12 @@ local_stat (const char *path, struct stat *buf)
/* Make sure the parent of "." exists and is a directory, not a
file. This is because 'stat' on Windows normalizes the argument
foo/. => foo without checking first that foo is a directory. */
if (plen > 1 && path[plen - 1] == '.'
&& (path[plen - 2] == '/' || path[plen - 2] == '\\'))
if (plen > 2 && path[plen - 1] == '.' && ISDIRSEP (path[plen - 2]))
{
char parent[MAXPATHLEN];
char parent[MAX_PATH+1];
strncpy (parent, path, plen - 2);
parent[plen - 2] = '\0';
strncpy (parent, path, MAX_PATH);
parent[MIN(plen - 2, MAX_PATH)] = '\0';
if (stat (parent, buf) < 0 || !_S_ISDIR (buf->st_mode))
return -1;
}

View File

@@ -1,5 +1,5 @@
/* Variable expansion functions for GNU Make.
Copyright (C) 1988-2019 Free Software Foundation, Inc.
Copyright (C) 1988-2022 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -12,15 +12,16 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
this program. If not, see <https://www.gnu.org/licenses/>. */
#include "makeint.h"
#include <assert.h>
#include "commands.h"
#include "debug.h"
#include "filedef.h"
#include "job.h"
#include "commands.h"
#include "variable.h"
#include "rule.h"
@@ -67,14 +68,14 @@ variable_buffer_output (char *ptr, const char *string, size_t length)
ptr = variable_buffer + offset;
}
memcpy (ptr, string, length);
return ptr + length;
return mempcpy (ptr, string, length);
}
/* Return a pointer to the beginning of the variable buffer. */
/* Return a pointer to the beginning of the variable buffer.
This is called from main() and it should never be null afterward. */
static char *
initialize_variable_output (void)
char *
initialize_variable_output ()
{
/* If we don't have a variable output buffer yet, get one. */
@@ -101,6 +102,29 @@ recursively_expand_for_file (struct variable *v, struct file *file)
struct variable_set_list *save = 0;
int set_reading = 0;
/* If we're expanding to put into the environment of a shell function then
ignore any recursion issues: for backward-compatibility we will use
the value of the environment variable we were started with. */
if (v->expanding && env_recursion)
{
size_t nl = strlen (v->name);
char **ep;
DB (DB_VERBOSE,
(_("%s:%lu: not recursively expanding %s to export to shell function\n"),
v->fileinfo.filenm, v->fileinfo.lineno, v->name));
/* We could create a hash for the original environment for speed, but a
reasonably written makefile shouldn't hit this situation... */
for (ep = environ; *ep != 0; ++ep)
if ((*ep)[nl] == '=' && strncmp (*ep, v->name, nl) == 0)
return xstrdup ((*ep) + nl + 1);
/* If there's nothing in the parent environment, use the empty string.
This isn't quite correct since the variable should not exist at all,
but getting that to work would be involved. */
return xstrdup ("");
}
/* Don't install a new location if this location is empty.
This can happen for command-line variables, builtin variables, etc. */
saved_varp = expanding_var;
@@ -207,7 +231,7 @@ variable_expand_string (char *line, const char *string, size_t length)
if (length == 0)
{
variable_buffer_output (o, "", 1);
return (variable_buffer);
return variable_buffer;
}
/* We need a copy of STRING: due to eval, it's possible that it will get

View File

@@ -1,5 +1,5 @@
/* Target file management for GNU Make.
Copyright (C) 1988-2019 Free Software Foundation, Inc.
Copyright (C) 1988-2022 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -12,7 +12,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
this program. If not, see <https://www.gnu.org/licenses/>. */
#include "makeint.h"
@@ -25,6 +25,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#include "variable.h"
#include "debug.h"
#include "hash.h"
#include "shuffle.h"
/* Remember whether snap_deps has been invoked: we need this to be sure we
@@ -62,6 +63,9 @@ static struct hash_table files;
/* Whether or not .SECONDARY with no prerequisites was given. */
static int all_secondary = 0;
/* Whether or not .NOTINTERMEDIATE with no prerequisites was given. */
static int no_intermediates = 0;
/* Access the hash table of all file records.
lookup_file given a name, return the struct file * for that name,
or nil if there is none.
@@ -104,20 +108,10 @@ lookup_file (const char *name)
while (name[0] == '<' && name[1] == '>' && name[2] != '\0')
name += 2;
#endif
while (name[0] == '.'
#ifdef HAVE_DOS_PATHS
&& (name[1] == '/' || name[1] == '\\')
#else
&& name[1] == '/'
#endif
&& name[2] != '\0')
while (name[0] == '.' && ISDIRSEP (name[1]) && name[2] != '\0')
{
name += 2;
while (*name == '/'
#ifdef HAVE_DOS_PATHS
|| *name == '\\'
#endif
)
while (ISDIRSEP (*name))
/* Skip following slashes: ".//foo" is "foo", not "/foo". */
++name;
}
@@ -270,14 +264,14 @@ rehash_file (struct file *from_file, const char *to_hname)
{
size_t l = strlen (from_file->name);
/* We have two sets of commands. We will go with the
one given in the rule explicitly mentioning this name,
one given in the rule found through directory search,
but give a message to let the user know what's going on. */
if (to_file->cmds->fileinfo.filenm != 0)
error (&from_file->cmds->fileinfo,
l + strlen (to_file->cmds->fileinfo.filenm) + INTSTR_LENGTH,
_("Recipe was specified for file '%s' at %s:%lu,"),
from_file->name, to_file->cmds->fileinfo.filenm,
to_file->cmds->fileinfo.lineno);
from_file->name, from_file->cmds->fileinfo.filenm,
from_file->cmds->fileinfo.lineno);
else
error (&from_file->cmds->fileinfo, l,
_("Recipe for file '%s' was found by implicit rule search,"),
@@ -288,7 +282,7 @@ rehash_file (struct file *from_file, const char *to_hname)
from_file->name, to_hname);
error (&from_file->cmds->fileinfo, l,
_("Recipe for '%s' will be ignored in favor of the one for '%s'."),
to_hname, from_file->name);
from_file->name, to_hname);
}
}
@@ -327,14 +321,19 @@ rehash_file (struct file *from_file, const char *to_hname)
#define MERGE(field) to_file->field |= from_file->field
MERGE (precious);
MERGE (loaded);
MERGE (tried_implicit);
MERGE (updating);
MERGE (updated);
MERGE (is_target);
MERGE (cmd_target);
MERGE (phony);
MERGE (loaded);
/* Don't merge intermediate because this file might be pre-existing */
MERGE (is_explicit);
MERGE (secondary);
MERGE (notintermediate);
MERGE (ignore_vpath);
MERGE (snapped);
#undef MERGE
to_file->builtin = 0;
@@ -386,7 +385,7 @@ remove_intermediates (int sig)
given on the command line, and it's either a -include makefile or
it's not precious. */
if (f->intermediate && (f->dontcare || !f->precious)
&& !f->secondary && !f->cmd_target)
&& !f->secondary && !f->notintermediate && !f->cmd_target)
{
int status;
if (f->update_status == us_none)
@@ -424,7 +423,11 @@ remove_intermediates (int sig)
}
}
if (status < 0)
perror_with_name ("unlink: ", f->name);
{
perror_with_name ("\nunlink: ", f->name);
/* Start printing over. */
doneany = 0;
}
}
}
}
@@ -442,8 +445,7 @@ remove_intermediates (int sig)
struct dep *
split_prereqs (char *p)
{
struct dep *new = PARSE_FILE_SEQ (&p, struct dep, MAP_PIPE, NULL,
PARSEFS_NONE);
struct dep *new = PARSE_FILE_SEQ (&p, struct dep, MAP_PIPE, NULL, PARSEFS_WAIT);
if (*p)
{
@@ -452,7 +454,7 @@ split_prereqs (char *p)
struct dep *ood;
++p;
ood = PARSE_SIMPLE_SEQ (&p, struct dep);
ood = PARSE_FILE_SEQ (&p, struct dep, MAP_NUL, NULL, PARSEFS_WAIT);
if (! new)
new = ood;
@@ -486,7 +488,6 @@ enter_prereqs (struct dep *deps, const char *stem)
if (stem)
{
const char *pattern = "%";
char *buffer = variable_expand ("");
struct dep *dp = deps, *dl = 0;
while (dp != 0)
@@ -506,14 +507,15 @@ enter_prereqs (struct dep *deps, const char *stem)
if (stem[0] == '\0')
{
memmove (percent, percent+1, strlen (percent));
o = variable_buffer_output (buffer, nm, strlen (nm) + 1);
o = variable_buffer_output (variable_buffer, nm,
strlen (nm) + 1);
}
else
o = patsubst_expand_pat (buffer, stem, pattern, nm,
o = patsubst_expand_pat (variable_buffer, stem, pattern, nm,
pattern+1, percent+1);
/* If the name expanded to the empty string, ignore it. */
if (buffer[0] == '\0')
if (variable_buffer[0] == '\0')
{
struct dep *df = dp;
if (dp == deps)
@@ -525,7 +527,8 @@ enter_prereqs (struct dep *deps, const char *stem)
}
/* Save the name. */
dp->name = strcache_add_len (buffer, o - buffer);
dp->name = strcache_add_len (variable_buffer,
o - variable_buffer);
}
dp->stem = stem;
dp->staticpattern = 1;
@@ -545,30 +548,29 @@ enter_prereqs (struct dep *deps, const char *stem)
d1->file = enter_file (d1->name);
d1->staticpattern = 0;
d1->name = 0;
if (!stem)
/* This file is explicitly mentioned as a prereq. */
d1->file->is_explicit = 1;
}
return deps;
}
/* Set the intermediate flag. */
static void
set_intermediate (const void *item)
{
struct file *f = (struct file *) item;
f->intermediate = 1;
}
/* Expand and parse each dependency line. */
static void
/* Expand and parse each dependency line.
For each dependency of the file, make the 'struct dep' point
at the appropriate 'struct file' (which may have to be created). */
void
expand_deps (struct file *f)
{
struct dep *d;
struct dep **dp;
const char *file_stem = f->stem;
const char *fstem;
int initialized = 0;
int changed_dep = 0;
f->updating = 0;
if (f->snapped)
return;
f->snapped = 1;
/* Walk through the dependencies. For any dependency that needs 2nd
expansion, expand it then insert the result into the list. */
@@ -578,7 +580,6 @@ expand_deps (struct file *f)
{
char *p;
struct dep *new, *next;
char *name = (char *)d->name;
if (! d->name || ! d->need_2nd_expansion)
{
@@ -588,16 +589,46 @@ expand_deps (struct file *f)
continue;
}
/* If it's from a static pattern rule, convert the patterns into
"$*" so they'll expand properly. */
/* If it's from a static pattern rule, convert the initial pattern in
each word to "$*" so they'll expand properly. */
if (d->staticpattern)
{
char *o = variable_expand ("");
o = subst_expand (o, name, "%", "$*", 1, 2, 0);
*o = '\0';
free (name);
d->name = name = xstrdup (variable_buffer);
d->staticpattern = 0;
const char *cs = d->name;
size_t nperc = 0;
/* Count the number of % in the string. */
while ((cs = strchr (cs, '%')) != NULL)
{
++nperc;
++cs;
}
if (nperc)
{
/* Allocate enough space to replace all % with $*. */
size_t slen = strlen (d->name) + nperc + 1;
const char *pcs = d->name;
char *name = xmalloc (slen);
char *s = name;
/* Substitute the first % in each word. */
cs = strchr (pcs, '%');
while (cs)
{
s = mempcpy (s, pcs, cs - pcs);
*(s++) = '$';
*(s++) = '*';
pcs = ++cs;
/* Find the first % after the next whitespace. */
cs = strchr (end_of_token (cs), '%');
}
strcpy (s, pcs);
free ((char*)d->name);
d->name = name;
}
}
/* We're going to do second expansion so initialize file variables for
@@ -609,54 +640,130 @@ expand_deps (struct file *f)
initialized = 1;
}
if (d->stem != 0)
f->stem = d->stem;
set_file_variables (f);
set_file_variables (f, d->stem ? d->stem : f->stem);
/* Perform second expansion. */
p = variable_expand_for_file (d->name, f);
if (d->stem != 0)
f->stem = file_stem;
/* At this point we don't need the name anymore: free it. */
free (name);
/* Free the un-expanded name. */
free ((char*)d->name);
/* Parse the prerequisites and enter them into the file database. */
new = enter_prereqs (split_prereqs (p), d->stem);
new = split_prereqs (p);
/* If there were no prereqs here (blank!) then throw this one out. */
if (new == 0)
{
*dp = d->next;
changed_dep = 1;
free_dep (d);
d = *dp;
continue;
}
/* Add newly parsed prerequisites. */
fstem = d->stem;
next = d->next;
changed_dep = 1;
free_dep (d);
*dp = new;
for (dp = &new->next, d = new->next; d != 0; dp = &d->next, d = d->next)
;
for (dp = &new, d = new; d != 0; dp = &d->next, d = d->next)
{
d->file = lookup_file (d->name);
if (d->file == 0)
d->file = enter_file (d->name);
d->name = 0;
d->stem = fstem;
if (!fstem)
/* This file is explicitly mentioned as a prereq. */
d->file->is_explicit = 1;
}
*dp = next;
d = *dp;
}
/* Shuffle mode assumes '->next' and '->shuf' links both traverse the same
dependencies (in different sequences). Regenerate '->shuf' so we don't
refer to stale data. */
if (changed_dep)
shuffle_deps_recursive (f->deps);
}
/* Reset the updating flag. */
/* Add extra prereqs to the file in question. */
struct dep *
expand_extra_prereqs (const struct variable *extra)
{
struct dep *d;
struct dep *prereqs = extra ? split_prereqs (variable_expand (extra->value)) : NULL;
for (d = prereqs; d; d = d->next)
{
d->file = lookup_file (d->name);
if (!d->file)
d->file = enter_file (d->name);
d->name = NULL;
d->ignore_automatic_vars = 1;
}
return prereqs;
}
/* Perform per-file snap operations. */
static void
reset_updating (const void *item)
snap_file (const void *item, void *arg)
{
struct file *f = (struct file *) item;
f->updating = 0;
struct file *f = (struct file*)item;
struct dep *prereqs = NULL;
/* If we're not doing second expansion then reset updating. */
if (!second_expansion)
f->updating = 0;
/* More specific setting has priority. */
/* If .SECONDARY is set with no deps, mark all targets as intermediate,
unless the target is a prereq of .NOTINTERMEDIATE. */
if (all_secondary && !f->notintermediate)
f->intermediate = 1;
/* If .NOTINTERMEDIATE is set with no deps, mark all targets as
notintermediate, unless the target is a prereq of .INTERMEDIATE. */
if (no_intermediates && !f->intermediate && !f->secondary)
f->notintermediate = 1;
/* If .EXTRA_PREREQS is set, add them as ignored by automatic variables. */
if (f->variables)
prereqs = expand_extra_prereqs (lookup_variable_in_set (STRING_SIZE_TUPLE(".EXTRA_PREREQS"), f->variables->set));
else if (f->is_target)
prereqs = copy_dep_chain (arg);
if (prereqs)
{
struct dep *d;
for (d = prereqs; d; d = d->next)
if (streq (f->name, dep_name (d)))
/* Skip circular dependencies. */
break;
if (d)
/* We broke early: must have found a circular dependency. */
free_dep_chain (prereqs);
else if (!f->deps)
f->deps = prereqs;
else
{
d = f->deps;
while (d->next)
d = d->next;
d->next = prereqs;
}
}
}
/* For each dependency of each file, make the 'struct dep' point
at the appropriate 'struct file' (which may have to be created).
Also mark the files depended on by .PRECIOUS, .PHONY, .SILENT,
/* Mark the files depended on by .PRECIOUS, .PHONY, .SILENT,
and various other special targets. */
void
@@ -670,40 +777,6 @@ snap_deps (void)
longer define new targets. */
snapped_deps = 1;
/* Perform second expansion and enter each dependency name as a file. We
must use hash_dump() here because within these loops we likely add new
files to the table, possibly causing an in-situ table expansion.
We only need to do this if second_expansion has been defined; if it
hasn't then all deps were expanded as the makefile was read in. If we
ever change make to be able to unset .SECONDARY_EXPANSION this will have
to change. */
if (second_expansion)
{
struct file **file_slot_0 = (struct file **) hash_dump (&files, 0, 0);
struct file **file_end = file_slot_0 + files.ht_fill;
struct file **file_slot;
const char *suffixes;
/* Expand .SUFFIXES: its prerequisites are used for $$* calc. */
f = lookup_file (".SUFFIXES");
suffixes = f ? f->name : 0;
for (; f != 0; f = f->prev)
expand_deps (f);
/* For every target that's not .SUFFIXES, expand its prerequisites. */
for (file_slot = file_slot_0; file_slot < file_end; file_slot++)
for (f = *file_slot; f != 0; f = f->prev)
if (f->name != suffixes)
expand_deps (f);
free (file_slot_0);
}
else
/* We're not doing second expansion, so reset updating. */
hash_map (&files, reset_updating);
/* Now manage all the special targets. */
for (f = lookup_file (".PRECIOUS"); f != 0; f = f->prev)
@@ -727,11 +800,32 @@ snap_deps (void)
f2->mtime_before_update = NONEXISTENT_MTIME;
}
for (f = lookup_file (".NOTINTERMEDIATE"); f != 0; f = f->prev)
/* Mark .NOTINTERMEDIATE deps as notintermediate files. */
if (f->deps)
for (d = f->deps; d != 0; d = d->next)
for (f2 = d->file; f2 != 0; f2 = f2->prev)
f2->notintermediate = 1;
/* .NOTINTERMEDIATE with no deps marks all files as notintermediate. */
else
no_intermediates = 1;
/* The same file connot be both .INTERMEDIATE and .NOTINTERMEDIATE.
However, it is possible for a file to be .INTERMEDIATE and also match a
.NOTINTERMEDIATE pattern. In that case, the intermediate file has
priority over the notintermediate pattern. This priority is enforced by
pattern_search. */
for (f = lookup_file (".INTERMEDIATE"); f != 0; f = f->prev)
/* Mark .INTERMEDIATE deps as intermediate files. */
for (d = f->deps; d != 0; d = d->next)
for (f2 = d->file; f2 != 0; f2 = f2->prev)
f2->intermediate = 1;
if (f2->notintermediate)
OS (fatal, NILF,
_("%s cannot be both .NOTINTERMEDIATE and .INTERMEDIATE"),
f2->name);
else
f2->intermediate = 1;
/* .INTERMEDIATE with no deps does nothing.
Marking all files as intermediates is useless since the goal targets
would be deleted after they are built. */
@@ -741,13 +835,19 @@ snap_deps (void)
if (f->deps)
for (d = f->deps; d != 0; d = d->next)
for (f2 = d->file; f2 != 0; f2 = f2->prev)
if (f2->notintermediate)
OS (fatal, NILF,
_("%s cannot be both .NOTINTERMEDIATE and .SECONDARY"),
f2->name);
else
f2->intermediate = f2->secondary = 1;
/* .SECONDARY with no deps listed marks *all* files that way. */
else
{
all_secondary = 1;
hash_map (&files, set_intermediate);
}
all_secondary = 1;
if (no_intermediates && all_secondary)
O (fatal, NILF,
_(".NOTINTERMEDIATE and .SECONDARY are mutually exclusive"));
f = lookup_file (".EXPORT_ALL_VARIABLES");
if (f != 0 && f->is_target)
@@ -777,7 +877,28 @@ snap_deps (void)
f = lookup_file (".NOTPARALLEL");
if (f != 0 && f->is_target)
not_parallel = 1;
{
struct dep *d2;
if (!f->deps)
not_parallel = 1;
else
/* Set a wait point between every prerequisite of each target. */
for (d = f->deps; d != NULL; d = d->next)
for (f2 = d->file; f2 != NULL; f2 = f2->prev)
if (f2->deps)
for (d2 = f2->deps->next; d2 != NULL; d2 = d2->next)
d2->wait_here = 1;
}
{
struct dep *prereqs = expand_extra_prereqs (lookup_variable (STRING_SIZE_TUPLE(".EXTRA_PREREQS")));
/* Perform per-file snap operations. */
hash_map_arg(&files, snap_file, prereqs);
free_dep_chain (prereqs);
}
#ifndef NO_MINUS_C_MINUS_O
/* If .POSIX was defined, remove OUTPUT_OPTION to comply. */
@@ -887,13 +1008,16 @@ file_timestamp_sprintf (char *p, FILE_TIMESTAMP ts)
struct tm *tm = localtime (&t);
if (tm)
sprintf (p, "%04d-%02d-%02d %02d:%02d:%02d",
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
{
intmax_t year = tm->tm_year;
sprintf (p, "%04" PRIdMAX "-%02d-%02d %02d:%02d:%02d",
year + 1900, tm->tm_mon + 1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
}
else if (t < 0)
sprintf (p, "%ld", (long) t);
sprintf (p, "%" PRIdMAX, (intmax_t) t);
else
sprintf (p, "%lu", (unsigned long) t);
sprintf (p, "%" PRIuMAX, (uintmax_t) t);
p += strlen (p);
/* Append nanoseconds as a fraction, but remove trailing zeros. We don't
@@ -919,17 +1043,17 @@ print_prereqs (const struct dep *deps)
/* Print all normal dependencies; note any order-only deps. */
for (; deps != 0; deps = deps->next)
if (! deps->ignore_mtime)
printf (" %s", dep_name (deps));
printf (" %s%s", deps->wait_here ? ".WAIT " : "", dep_name (deps));
else if (! ood)
ood = deps;
/* Print order-only deps, if we have any. */
if (ood)
{
printf (" | %s", dep_name (ood));
printf (" | %s%s", ood->wait_here ? ".WAIT " : "", dep_name (ood));
for (ood = ood->next; ood != 0; ood = ood->next)
if (ood->ignore_mtime)
printf (" %s", dep_name (ood));
printf (" %s%s", ood->wait_here ? ".WAIT " : "", dep_name (ood));
}
putchar ('\n');
@@ -983,6 +1107,10 @@ print_file (const void *item)
printf (_("# Implicit/static pattern stem: '%s'\n"), f->stem);
if (f->intermediate)
puts (_("# File is an intermediate prerequisite."));
if (f->notintermediate)
puts (_("# File is a prerequisite of .NOTINTERMEDIATE."));
if (f->secondary)
puts (_("# File is secondary (prerequisite of .SECONDARY)."));
if (f->also_make != 0)
{
const struct dep *d;
@@ -1130,8 +1258,7 @@ build_target_list (char *value)
p = &value[off];
}
memcpy (p, f->name, l);
p += l;
p = mempcpy (p, f->name, l);
*(p++) = ' ';
}
*(p-1) = '\0';

View File

@@ -1,5 +1,5 @@
/* Definition of target file data structures for GNU Make.
Copyright (C) 1988-2019 Free Software Foundation, Inc.
Copyright (C) 1988-2022 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -12,7 +12,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
this program. If not, see <https://www.gnu.org/licenses/>. */
/* Structure that represents the info on one file
@@ -21,6 +21,11 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#include "hash.h"
struct commands;
struct dep;
struct variable;
struct variable_set_list;
struct file
{
const char *name;
@@ -79,6 +84,7 @@ struct file
unsigned int builtin:1; /* True if the file is a builtin rule. */
unsigned int precious:1; /* Non-0 means don't delete file on quit */
unsigned int loaded:1; /* True if the file is a loaded object. */
unsigned int unloaded:1; /* True if this loaded object was unloaded. */
unsigned int low_resolution_time:1; /* Nonzero if this file's time stamp
has only one-second resolution. */
unsigned int tried_implicit:1; /* Nonzero if have searched
@@ -91,8 +97,11 @@ struct file
unsigned int phony:1; /* Nonzero if this is a phony file
i.e., a prerequisite of .PHONY. */
unsigned int intermediate:1;/* Nonzero if this is an intermediate file. */
unsigned int is_explicit:1; /* Nonzero if explicitly mentioned. */
unsigned int secondary:1; /* Nonzero means remove_intermediates should
not delete it. */
unsigned int notintermediate:1; /* Nonzero means a file is a prereq to
.NOTINTERMEDIATE. */
unsigned int dontcare:1; /* Nonzero if no complaint is to be made if
this target cannot be remade. */
unsigned int ignore_vpath:1;/* Nonzero if we threw out VPATH name. */
@@ -100,6 +109,10 @@ struct file
pattern-specific variables. */
unsigned int no_diag:1; /* True if the file failed to update and no
diagnostics has been issued (dontcare). */
unsigned int was_shuffled:1; /* Did we already shuffle 'deps'? used when
--shuffle passes through the graph. */
unsigned int snapped:1; /* True if the deps of this file have been
secondary expanded. */
};
@@ -110,6 +123,8 @@ struct file *lookup_file (const char *name);
struct file *enter_file (const char *name);
struct dep *split_prereqs (char *prereqstr);
struct dep *enter_prereqs (struct dep *prereqs, const char *stem);
void expand_deps (struct file *f);
struct dep *expand_extra_prereqs (const struct variable *extra);
void remove_intermediates (int sig);
void snap_deps (void);
void rename_file (struct file *file, const char *name);
@@ -197,6 +212,8 @@ FILE_TIMESTAMP f_mtime (struct file *file, int search);
<< FILE_TIMESTAMP_LO_BITS) \
+ ORDINARY_MTIME_MIN + FILE_TIMESTAMPS_PER_S - 1)
#define is_ordinary_mtime(_t) ((_t) >= ORDINARY_MTIME_MIN && (_t) <= ORDINARY_MTIME_MAX)
/* Modtime value to use for 'infinitely new'. We used to get the current time
from the system and use that whenever we wanted 'new'. But that causes
trouble when the machine running make and the machine holding a file have

File diff suppressed because it is too large Load Diff

View File

@@ -3,7 +3,7 @@ NOTE: getopt is now part of the C library, so if you don't know what
"Keep this file name-space clean" means, talk to drepper@gnu.org
before changing it!
Copyright (C) 1987-2019 Free Software Foundation, Inc.
Copyright (C) 1987-2022 Free Software Foundation, Inc.
NOTE: The canonical source of this file is maintained with the GNU C Library.
Bugs can be reported to bug-glibc@gnu.org.
@@ -18,7 +18,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
this program. If not, see <https://www.gnu.org/licenses/>. */
/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
Ditto for AIX 3.2 and <stdlib.h>. */

View File

@@ -1,5 +1,5 @@
/* Declarations for getopt.
Copyright (C) 1989-2019 Free Software Foundation, Inc.
Copyright (C) 1989-2022 Free Software Foundation, Inc.
NOTE: The canonical source of this file is maintained with the GNU C Library.
Bugs can be reported to bug-glibc@gnu.org.
@@ -14,7 +14,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
this program. If not, see <https://www.gnu.org/licenses/>. */
#ifndef _GETOPT_H
#define _GETOPT_H 1

View File

@@ -1,5 +1,5 @@
/* getopt_long and getopt_long_only entry points for GNU getopt.
Copyright (C) 1987-1994, 1996-2019 Free Software Foundation, Inc.
Copyright (C) 1987-1994, 1996-2022 Free Software Foundation, Inc.
NOTE: The canonical source of this file is maintained with the GNU C Library.
Bugs can be reported to bug-glibc@gnu.org.
@@ -14,7 +14,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
this program. If not, see <https://www.gnu.org/licenses/>. */
#ifdef HAVE_CONFIG_H
#include <config.h>

View File

@@ -1,5 +1,5 @@
/* Convenience header for conditional use of GNU <libintl.h>.
Copyright (C) 1995-2019 Free Software Foundation, Inc.
Copyright (C) 1995-2022 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -12,7 +12,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
this program. If not, see <https://www.gnu.org/licenses/>. */
#ifndef _LIBGETTEXT_H
#define _LIBGETTEXT_H 1

View File

@@ -1,5 +1,5 @@
;; Contents of the (gnu make) Guile module
;; Copyright (C) 2011-2019 Free Software Foundation, Inc.
;; Copyright (C) 2011-2022 Free Software Foundation, Inc.
;; This file is part of GNU Make.
;;
;; GNU Make is free software; you can redistribute it and/or modify it under
@@ -13,7 +13,7 @@
;; details.
;;
;; You should have received a copy of the GNU General Public License along
;; with this program. If not, see <http://www.gnu.org/licenses/>.
;; with this program. If not, see <https://www.gnu.org/licenses/>.
(define (to-string-maybe x)
(cond

View File

@@ -1,7 +1,7 @@
/* External interfaces usable by dynamic objects loaded into GNU Make.
--THIS API IS A "TECHNOLOGY PREVIEW" ONLY. IT IS NOT A STABLE INTERFACE--
Copyright (C) 2013-2019 Free Software Foundation, Inc.
Copyright (C) 2013-2022 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -14,7 +14,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
this program. If not, see <https://www.gnu.org/licenses/>. */
#ifndef _GNUMAKE_H_
#define _GNUMAKE_H_

View File

@@ -1,5 +1,5 @@
/* GNU Guile interface for GNU Make.
Copyright (C) 2011-2019 Free Software Foundation, Inc.
Copyright (C) 2011-2022 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -12,7 +12,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
this program. If not, see <https://www.gnu.org/licenses/>. */
#include "makeint.h"

View File

@@ -12,10 +12,11 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
this program. If not, see <https://www.gnu.org/licenses/>. */
#include "makeint.h"
#include "hash.h"
#include <assert.h>
#define CALLOC(t, n) ((t *) xcalloc (sizeof (t) * (n)))
#define MALLOC(t, n) ((t *) xmalloc (sizeof (t) * (n)))
@@ -43,11 +44,11 @@ hash_init (struct hash_table *ht, unsigned long size,
{
ht->ht_size = round_up_2 (size);
ht->ht_empty_slots = ht->ht_size;
ht->ht_vec = (void**) CALLOC (struct token *, ht->ht_size);
ht->ht_vec = CALLOC (void *, ht->ht_size);
if (ht->ht_vec == 0)
{
fprintf (stderr, _("can't allocate %lu bytes for hash table: memory exhausted"),
ht->ht_size * (unsigned long) sizeof (struct token *));
ht->ht_size * (unsigned long) sizeof (void *));
exit (MAKE_TROUBLE);
}
@@ -259,7 +260,7 @@ hash_rehash (struct hash_table *ht)
ht->ht_capacity = ht->ht_size - (ht->ht_size >> 4);
}
ht->ht_rehashes++;
ht->ht_vec = (void **) CALLOC (struct token *, ht->ht_size);
ht->ht_vec = CALLOC (void *, ht->ht_size);
for (ovp = old_vec; ovp < &old_vec[old_ht_size]; ovp++)
{
@@ -364,7 +365,8 @@ round_up_2 (unsigned long n)
r += val; \
} while(0);
unsigned jhash(unsigned const char *k, int length)
unsigned int
jhash(unsigned const char *k, int length)
{
unsigned int a, b, c;
@@ -408,12 +410,16 @@ unsigned jhash(unsigned const char *k, int length)
return c;
}
#define UINTSZ sizeof (unsigned int)
#ifdef WORDS_BIGENDIAN
/* The ifs are ordered from the first byte in memory to the last. */
#define sum_up_to_nul(r, p, flag) \
#define sum_up_to_nul(r, p, plen, flag) \
do { \
unsigned int val; \
memcpy(&val, (p), 4); \
unsigned int val = 0; \
size_t pn = (plen); \
size_t n = pn < UINTSZ ? pn : UINTSZ; \
memcpy (&val, (p), n); \
if ((val & 0xFF000000) == 0) \
flag = 1; \
else if ((val & 0xFF0000) == 0) \
@@ -427,51 +433,60 @@ unsigned jhash(unsigned const char *k, int length)
/* First detect the presence of zeroes. If there is none, we can
sum the 4 bytes directly. Otherwise, the ifs are ordered as in the
big endian case, from the first byte in memory to the last. */
#define sum_up_to_nul(r, p, flag) \
do { \
unsigned int val; \
unsigned int zeroes; \
memcpy(&val, (p), 4); \
zeroes = ((val - 0x01010101) & ~val); \
if (!(zeroes & 0x80808080)) \
r += val; \
else if ((val & 0xFF) == 0) \
flag = 1; \
else if ((val & 0xFF00) == 0) \
r += val & 0xFF, flag = 1; \
else if ((val & 0xFF0000) == 0) \
r += val & 0xFFFF, flag = 1; \
else \
r += val, flag = 1; \
#define sum_up_to_nul(r, p, plen, flag) \
do { \
unsigned int val = 0; \
size_t pn = (plen); \
size_t n = pn < UINTSZ ? pn : UINTSZ; \
memcpy (&val, (p), n); \
flag = ((val - 0x01010101) & ~val) & 0x80808080; \
if (!flag) \
r += val; \
else if (val & 0xFF) \
{ \
if ((val & 0xFF00) == 0) \
r += val & 0xFF; \
else if ((val & 0xFF0000) == 0) \
r += val & 0xFFFF; \
else \
r += val; \
} \
} while (0)
#endif
/* This function performs magic which is correct but causes ASAN heartburn
when we pass in a global constant string (at least). */
__attribute__((no_sanitize_address))
unsigned jhash_string(unsigned const char *k)
unsigned int
jhash_string(unsigned const char *k)
{
unsigned int a, b, c;
unsigned int have_nul = 0;
unsigned const char *start = k;
size_t klen = strlen ((const char*)k);
/* Set up the internal state */
a = b = c = JHASH_INITVAL;
/* All but the last block: affect some 32 bits of (a,b,c) */
for (;;) {
sum_up_to_nul(a, k, have_nul);
sum_up_to_nul(a, k, klen, have_nul);
if (have_nul)
break;
k += 4;
sum_up_to_nul(b, k, have_nul);
k += UINTSZ;
assert (klen >= UINTSZ);
klen -= UINTSZ;
sum_up_to_nul(b, k, klen, have_nul);
if (have_nul)
break;
k += 4;
sum_up_to_nul(c, k, have_nul);
k += UINTSZ;
assert (klen >= UINTSZ);
klen -= UINTSZ;
sum_up_to_nul(c, k, klen, have_nul);
if (have_nul)
break;
k += 4;
k += UINTSZ;
assert (klen >= UINTSZ);
klen -= UINTSZ;
jhash_mix(a, b, c);
}

View File

@@ -12,7 +12,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
this program. If not, see <https://www.gnu.org/licenses/>. */
#ifndef _hash_h_
#define _hash_h_
@@ -56,9 +56,9 @@ struct hash_table
typedef int (*qsort_cmp_t) __P((void const *, void const *));
void hash_init __P((struct hash_table *ht, unsigned long size,
hash_func_t hash_1, hash_func_t hash_2, hash_cmp_func_t hash_cmp));
hash_func_t hash_1, hash_func_t hash_2, hash_cmp_func_t hash_cmp));
void hash_load __P((struct hash_table *ht, void *item_table,
unsigned long cardinality, unsigned long size));
unsigned long cardinality, unsigned long size));
void **hash_find_slot __P((struct hash_table *ht, void const *key));
void *hash_find_item __P((struct hash_table *ht, void const *key));
void *hash_insert __P((struct hash_table *ht, const void *item));
@@ -154,7 +154,7 @@ extern void *hash_deleted_item;
#define ISTRING_HASH_1(KEY, RESULT) do { \
unsigned char const *_key_ = (unsigned char const *) (KEY) - 1; \
while (*++_key_) \
(RESULT) += ((isupper (*_key_) ? tolower (*_key_) : *_key_) << (_key_[1] & 0xf)); \
(RESULT) += (tolower (*_key_) << (_key_[1] & 0xf)); \
} while (0)
#define return_ISTRING_HASH_1(KEY) do { \
unsigned long _result_ = 0; \
@@ -165,7 +165,7 @@ extern void *hash_deleted_item;
#define ISTRING_HASH_2(KEY, RESULT) do { \
unsigned char const *_key_ = (unsigned char const *) (KEY) - 1; \
while (*++_key_) \
(RESULT) += ((isupper (*_key_) ? tolower (*_key_) : *_key_) << (_key_[1] & 0x7)); \
(RESULT) += (tolower (*_key_) << (_key_[1] & 0x7)); \
} while (0)
#define return_ISTRING_HASH_2(KEY) do { \
unsigned long _result_ = 0; \

View File

@@ -1,5 +1,5 @@
/* Implicit rule searching for GNU Make.
Copyright (C) 1988-2019 Free Software Foundation, Inc.
Copyright (C) 1988-2022 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -12,7 +12,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
this program. If not, see <https://www.gnu.org/licenses/>. */
#include "makeint.h"
#include "filedef.h"
@@ -22,9 +22,12 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#include "variable.h"
#include "job.h" /* struct child, used inside commands.h */
#include "commands.h" /* set_file_variables */
#include "shuffle.h"
#include <assert.h>
static int pattern_search (struct file *file, int archive,
unsigned int depth, unsigned int recursions);
unsigned int depth, unsigned int recursions,
int allow_compat_rules);
/* For a FILE which has no commands specified, try to figure out some
from the implicit pattern rules.
@@ -42,7 +45,7 @@ try_implicit_rule (struct file *file, unsigned int depth)
(the archive search omits the archive name), it is more specific and
should come first. */
if (pattern_search (file, 0, depth, 0))
if (pattern_search (file, 0, depth, 0, 0))
return 1;
#ifndef NO_ARCHIVES
@@ -52,8 +55,11 @@ try_implicit_rule (struct file *file, unsigned int depth)
{
DBF (DB_IMPLICIT,
_("Looking for archive-member implicit rule for '%s'.\n"));
if (pattern_search (file, 1, depth, 0))
if (pattern_search (file, 1, depth, 0, 0))
return 1;
DBS (DB_IMPLICIT,
(_("No archive-member implicit rule found for '%s'.\n"),
file->name));
}
#endif
@@ -152,6 +158,9 @@ struct patdeps
const char *pattern;
struct file *file;
unsigned int ignore_mtime : 1;
unsigned int ignore_automatic_vars : 1;
unsigned int is_explicit : 1;
unsigned int wait_here : 1;
};
/* This structure stores information about pattern rules that we need
@@ -199,7 +208,8 @@ stemlen_compare (const void *v1, const void *v2)
static int
pattern_search (struct file *file, int archive,
unsigned int depth, unsigned int recursions)
unsigned int depth, unsigned int recursions,
int allow_compat_rules)
{
/* Filename we are searching for a rule for. */
const char *filename = archive ? strchr (file->name, '(') : file->name;
@@ -220,8 +230,13 @@ pattern_search (struct file *file, int archive,
struct patdeps *deplist = xmalloc (max_deps * sizeof (struct patdeps));
struct patdeps *pat = deplist;
/* Names of possible dependencies are constructed in this buffer. */
char *depname = alloca (namelen + max_pattern_dep_length);
/* Names of possible dependencies are constructed in this buffer.
We may replace % by $(*F) for second expansion, increasing the length. */
size_t deplen = namelen + max_pattern_dep_length + 4;
char *depname = alloca (deplen);
#ifndef NDEBUG
char *dend = depname + deplen;
#endif
/* The start and length of the stem of FILENAME for the current rule. */
const char *stem = 0;
@@ -249,6 +264,7 @@ pattern_search (struct file *file, int archive,
int specific_rule_matched = 0;
unsigned int ri; /* uninit checks OK */
int found_compat_rule = 0;
struct rule *rule;
char *pathdir = NULL;
@@ -265,7 +281,7 @@ pattern_search (struct file *file, int archive,
/* Set LASTSLASH to point at the last slash in FILENAME
but not counting any slash at the end. (foo/bar/ counts as
bar/ in directory foo/, not empty in directory foo/bar/.) */
lastslash = strrchr (filename, '/');
lastslash = memrchr (filename, '/', namelen - 1);
#ifdef VMS
if (lastslash == NULL)
lastslash = strrchr (filename, ']');
@@ -278,18 +294,16 @@ pattern_search (struct file *file, int archive,
/* Handle backslashes (possibly mixed with forward slashes)
and the case of "d:file". */
{
char *bslash = strrchr (filename, '\\');
char *bslash = memrchr (filename, '\\', namelen - 1);
if (lastslash == 0 || bslash > lastslash)
lastslash = bslash;
if (lastslash == 0 && filename[0] && filename[1] == ':')
lastslash = filename + 1;
}
#endif
if (lastslash != 0 && lastslash[1] == '\0')
lastslash = 0;
}
pathlen = lastslash - filename + 1;
pathlen = lastslash ? lastslash - filename + 1 : 0;
/* First see which pattern rules match this target and may be considered.
Put them in TRYRULES. */
@@ -308,7 +322,9 @@ pattern_search (struct file *file, int archive,
don't use it here. */
if (rule->in_use)
{
DBS (DB_IMPLICIT, (_("Avoiding implicit rule recursion.\n")));
DBS (DB_IMPLICIT,
(_("Avoiding implicit rule recursion for rule '%s'.\n"),
get_rule_defn (rule)));
continue;
}
@@ -431,6 +447,8 @@ pattern_search (struct file *file, int archive,
for (intermed_ok = 0; intermed_ok < 2; ++intermed_ok)
{
pat = deplist;
if (intermed_ok)
DBS (DB_IMPLICIT, (_("Trying harder.\n")));
/* Try each pattern rule till we find one that applies. If it does,
expand its dependencies (as substituted) and chain them in DEPS. */
@@ -443,7 +461,6 @@ pattern_search (struct file *file, int archive,
unsigned int deps_found = 0;
/* NPTR points to the part of the prereq we haven't processed. */
const char *nptr = 0;
const char *dir = NULL;
int order_only = 0;
unsigned int matches;
@@ -478,30 +495,38 @@ pattern_search (struct file *file, int archive,
memcpy (pathdir, filename, pathlen);
pathdir[pathlen] = '\0';
}
dir = pathdir;
}
if (stemlen > GET_PATH_MAX)
DBS (DB_IMPLICIT,
(_("Trying pattern rule '%s' with stem '%.*s'.\n"),
get_rule_defn (rule), (int) stemlen, stem));
if (stemlen + (check_lastslash ? pathlen : 0) > GET_PATH_MAX)
{
DBS (DB_IMPLICIT, (_("Stem too long: '%.*s'.\n"),
DBS (DB_IMPLICIT, (_("Stem too long: '%s%.*s'.\n"),
check_lastslash ? pathdir : "",
(int) stemlen, stem));
continue;
}
DBS (DB_IMPLICIT, (_("Trying pattern rule with stem '%.*s'.\n"),
(int) stemlen, stem));
strncpy (stem_str, stem, stemlen);
stem_str[stemlen] = '\0';
if (!check_lastslash)
{
memcpy (stem_str, stem, stemlen);
stem_str[stemlen] = '\0';
}
else
{
/* We want to prepend the directory from
the original FILENAME onto the stem. */
memcpy (stem_str, filename, pathlen);
memcpy (stem_str + pathlen, stem, stemlen);
stem_str[pathlen + stemlen] = '\0';
}
/* If there are no prerequisites, then this rule matches. */
if (rule->deps == 0)
break;
/* Temporary assign STEM to file->stem (needed to set file
variables below). */
file->stem = stem_str;
/* Mark this rule as in use so a recursive pattern_search won't try
to use it. */
rule->in_use = 1;
@@ -516,7 +541,6 @@ pattern_search (struct file *file, int archive,
while (1)
{
struct dep *dl, *d;
char *p;
/* If we're out of name to parse, start the next prereq. */
if (! nptr)
@@ -530,31 +554,33 @@ pattern_search (struct file *file, int archive,
/* If we don't need a second expansion, just replace the %. */
if (! dep->need_2nd_expansion)
{
p = strchr (nptr, '%');
if (p == 0)
char *p;
int is_explicit = 1;
const char *cp = strchr (nptr, '%');
if (cp == 0)
strcpy (depname, nptr);
else
{
char *o = depname;
if (check_lastslash)
{
memcpy (o, filename, pathlen);
o += pathlen;
}
memcpy (o, nptr, p - nptr);
o += p - nptr;
memcpy (o, stem_str, stemlen);
o += stemlen;
strcpy (o, p + 1);
o = mempcpy (o, filename, pathlen);
o = mempcpy (o, nptr, cp - nptr);
o = mempcpy (o, stem, stemlen);
strcpy (o, cp + 1);
is_explicit = 0;
}
/* Parse the expanded string. It might have wildcards. */
p = depname;
dl = PARSE_SIMPLE_SEQ (&p, struct dep);
dl = PARSE_FILE_SEQ (&p, struct dep, MAP_NUL, NULL,
PARSEFS_ONEWORD|PARSEFS_WAIT);
for (d = dl; d != NULL; d = d->next)
{
++deps_found;
d->ignore_mtime = dep->ignore_mtime;
d->ignore_automatic_vars = dep->ignore_automatic_vars;
d->wait_here |= dep->wait_here;
d->is_explicit = is_explicit;
}
/* We've used up this dep, so next time get a new one. */
@@ -574,17 +600,22 @@ pattern_search (struct file *file, int archive,
{
int add_dir = 0;
size_t len;
const char *end;
struct dep **dptr;
int is_explicit;
const char *cp;
char *p;
nptr = get_next_word (nptr, &len);
if (nptr == 0)
continue;
end = nptr + len;
/* See this is a transition to order-only prereqs. */
/* See if this is a transition to order-only prereqs. */
if (! order_only && len == 1 && nptr[0] == '|')
{
order_only = 1;
nptr += len;
nptr = end;
continue;
}
@@ -594,45 +625,81 @@ pattern_search (struct file *file, int archive,
again. This is not good if you have certain characters
in your stem (like $).
Instead, we will replace % with $* and allow the second
expansion to take care of it for us. This way (since $*
is a simple variable) there won't be additional
re-expansion of the stem. */
Instead, we will replace % with $* or $(*F) and allow the
second expansion to take care of it for us. This way
(since $* and $(*F) are simple variables) there won't be
additional re-expansion of the stem. */
p = lindex (nptr, nptr + len, '%');
if (p == 0)
cp = lindex (nptr, end, '%');
if (cp == 0)
{
memcpy (depname, nptr, len);
depname[len] = '\0';
is_explicit = 1;
}
else
{
size_t i = p - nptr;
memcpy (depname, nptr, i);
memcpy (depname + i, "$*", 2);
memcpy (depname + i + 2, p + 1, len - i - 1);
depname[len + 2 - 1] = '\0';
/* Go through all % between NPTR and END.
Copy contents of [NPTR, END) to depname, with the
first % after NPTR and then each first % after white
space replaced with $* or $(*F). depname has enough
room to substitute each % with $(*F). */
char *o = depname;
if (check_lastslash)
add_dir = 1;
is_explicit = 0;
for (;;)
{
size_t i = cp - nptr;
assert (o + i < dend);
o = mempcpy (o, nptr, i);
if (check_lastslash)
{
add_dir = 1;
assert (o + 5 < dend);
o = mempcpy (o, "$(*F)", 5);
}
else
{
assert (o + 2 < dend);
o = mempcpy (o, "$*", 2);
}
assert (o < dend);
++cp;
assert (cp <= end);
nptr = cp;
if (nptr == end)
break;
/* Skip the rest of this word then find the next %.
No need to worry about order-only, or nested
functions: NPTR went though get_next_word. */
while (cp < end && ! END_OF_TOKEN (*cp))
++cp;
cp = lindex (cp, end, '%');
if (cp == 0)
break;
}
len = end - nptr;
memcpy (o, nptr, len);
o[len] = '\0';
}
/* Set up for the next word. */
nptr += len;
nptr = end;
/* Initialize and set file variables if we haven't already
done so. */
if (!file_vars_initialized)
{
initialize_file_variables (file, 0);
set_file_variables (file);
set_file_variables (file, stem_str);
file_vars_initialized = 1;
}
/* Update the stem value in $* for this rule. */
else if (!file_variables_set)
{
define_variable_for_file (
"*", 1, file->stem, o_automatic, 0, file);
"*", 1, stem_str, o_automatic, 0, file);
file_variables_set = 1;
}
@@ -646,7 +713,8 @@ pattern_search (struct file *file, int archive,
/* Parse the expanded string. */
struct dep *dp = PARSE_FILE_SEQ (&p, struct dep,
order_only ? MAP_NUL : MAP_PIPE,
add_dir ? dir : NULL, PARSEFS_NONE);
add_dir ? pathdir : NULL,
PARSEFS_WAIT);
*dptr = dp;
for (d = dp; d != NULL; d = d->next)
@@ -654,6 +722,7 @@ pattern_search (struct file *file, int archive,
++deps_found;
if (order_only)
d->ignore_mtime = 1;
d->is_explicit = is_explicit;
dptr = &d->next;
}
@@ -684,8 +753,10 @@ pattern_search (struct file *file, int archive,
/* Go through the nameseq and handle each as a prereq name. */
for (d = dl; d != 0; d = d->next)
{
struct dep *expl_d;
struct file *df;
int is_rule = d->name == dep_name (dep);
int explicit = 0;
struct dep *dp = 0;
if (file_impossible_p (d->name))
{
@@ -694,9 +765,11 @@ pattern_search (struct file *file, int archive,
second pass either since we know that will fail. */
DBS (DB_IMPLICIT,
(is_rule
? _("Rejecting impossible rule prerequisite '%s'.\n")
: _("Rejecting impossible implicit prerequisite '%s'.\n"),
d->name));
? _("Rejecting rule '%s' due to impossible rule"
" prerequisite '%s'.\n")
: _("Rejecting rule '%s' due to impossible implicit"
" prerequisite '%s'.\n"),
get_rule_defn (rule), d->name));
tryrules[ri].rule = 0;
failed = 1;
@@ -705,41 +778,87 @@ pattern_search (struct file *file, int archive,
memset (pat, '\0', sizeof (struct patdeps));
pat->ignore_mtime = d->ignore_mtime;
pat->ignore_automatic_vars = d->ignore_automatic_vars;
pat->wait_here = d->wait_here;
pat->is_explicit = d->is_explicit;
DBS (DB_IMPLICIT,
(is_rule
? _("Trying rule prerequisite '%s'.\n")
: _("Trying implicit prerequisite '%s'.\n"), d->name));
/* If this prereq is also explicitly mentioned for FILE,
skip all tests below since it must be built no matter
which implicit rule we choose. */
df = lookup_file (d->name);
for (expl_d = file->deps; expl_d != 0; expl_d = expl_d->next)
if (streq (dep_name (expl_d), d->name))
break;
if (expl_d != 0)
if (df && df->is_explicit)
pat->is_explicit = 1;
/* If we found a file for the dep, set its intermediate flag.
df->is_explicit is set when the dep file is mentioned
explicitly on some other rule. d->is_explicit is set when
the dep file is mentioned explicitly on this rule. E.g.:
%.x : %.y ; ...
then:
one.x:
one.y: # df->is_explicit
vs.
one.x: one.y # d->is_explicit
*/
if (df && !df->is_explicit && !d->is_explicit)
df->intermediate = 1;
/* If the pattern prereq is also explicitly mentioned for
FILE, skip all tests below since it must be built no
matter which implicit rule we choose. */
if (df && df->is_target)
/* This prerequisite is mentioned explicitly as a target of
some rule. */
explicit = 1;
else
for (dp = file->deps; dp != 0; dp = dp->next)
if (streq (d->name, dep_name (dp)))
break;
/* If dp is set, this prerequisite is mentioned explicitly as
a prerequisite of the current target. */
if (explicit || dp)
{
(pat++)->name = d->name;
DBS (DB_IMPLICIT, (_("'%s' ought to exist.\n"), d->name));
continue;
}
/* The DEP->changed flag says that this dependency resides
in a nonexistent directory. So we normally can skip
looking for the file. However, if CHECK_LASTSLASH is
set, then the dependency file we are actually looking for
is in a different directory (the one gotten by prepending
FILENAME's directory), so it might actually exist. */
/* @@ dep->changed check is disabled. */
if (lookup_file (d->name) != 0
/*|| ((!dep->changed || check_lastslash) && */
|| file_exists_p (d->name))
if (file_exists_p (d->name))
{
(pat++)->name = d->name;
DBS (DB_IMPLICIT, (_("Found '%s'.\n"), d->name));
continue;
}
if (df && allow_compat_rules)
{
(pat++)->name = d->name;
DBS (DB_IMPLICIT,
(_("Using compatibility rule '%s' due to '%s'.\n"),
get_rule_defn (rule), d->name));
continue;
}
if (df)
{
/* This prerequisite is mentioned explicitly as a
prerequisite on some rule, but it is not a
prerequisite of the current target. Therefore, this
prerequisite does not qualify as ought-to-exist. Keep
note of this rule and continue the search. If a more
suitable rule is not found, then use this rule. */
DBS (DB_IMPLICIT,
(_("Prerequisite '%s' of rule '%s' does not qualify"
" as ought to exist.\n"),
d->name, get_rule_defn (rule)));
found_compat_rule = 1;
}
/* This code, given FILENAME = "lib/foo.o", dependency name
"lib/foo.c", and VPATH=src, searches for
"src/lib/foo.c". */
@@ -748,7 +867,7 @@ pattern_search (struct file *file, int archive,
if (vname)
{
DBS (DB_IMPLICIT,
(_("Found prerequisite '%s' as VPATH '%s'\n"),
(_("Found prerequisite '%s' as VPATH '%s'.\n"),
d->name, vname));
(pat++)->name = d->name;
continue;
@@ -756,13 +875,15 @@ pattern_search (struct file *file, int archive,
}
/* We could not find the file in any place we should look.
Try to make this dependency as an intermediate file, but
Look for an implicit rule to make this dependency, but
only on the second pass. */
if (intermed_ok)
{
DBS (DB_IMPLICIT,
(_("Looking for a rule with intermediate file '%s'.\n"),
(d->is_explicit || (df && df->is_explicit)
? _("Looking for a rule with explicit file '%s'.\n")
: _("Looking for a rule with intermediate file '%s'.\n"),
d->name));
if (int_file == 0)
@@ -773,7 +894,8 @@ pattern_search (struct file *file, int archive,
if (pattern_search (int_file,
0,
depth + 1,
recursions + 1))
recursions + 1,
allow_compat_rules))
{
pat->pattern = int_file->name;
int_file->name = d->name;
@@ -790,11 +912,24 @@ pattern_search (struct file *file, int archive,
free_variable_set (int_file->variables);
if (int_file->pat_variables)
free_variable_set (int_file->pat_variables);
file_impossible (d->name);
/* Keep prerequisites explicitly mentioned on unrelated
rules as "possible" to let compatibility search find
such prerequisites. */
if (df == 0)
file_impossible (d->name);
}
/* A dependency of this rule does not exist. Therefore, this
rule fails. */
if (intermed_ok)
DBS (DB_IMPLICIT,
(_("Rejecting rule '%s' "
"due to impossible prerequisite '%s'.\n"),
get_rule_defn (rule), d->name));
else
DBS (DB_IMPLICIT, (_("Not found '%s'.\n"), d->name));
failed = 1;
break;
}
@@ -806,10 +941,6 @@ pattern_search (struct file *file, int archive,
break;
}
/* Reset the stem in FILE. */
file->stem = 0;
/* This rule is no longer 'in use' for recursive searches. */
rule->in_use = 0;
@@ -861,24 +992,24 @@ pattern_search (struct file *file, int archive,
struct file *imf = pat->file;
struct file *f = lookup_file (imf->name);
/* We don't want to delete an intermediate file that happened
to be a prerequisite of some (other) target. Mark it as
secondary. We don't want it to be precious as that disables
DELETE_ON_ERROR etc. */
if (f != 0)
f->secondary = 1;
else
if (!f)
f = enter_file (imf->name);
f->deps = imf->deps;
f->cmds = imf->cmds;
f->stem = imf->stem;
f->variables = imf->variables;
/* Setting target specific variables for a file causes the file to be
entered to the database as a prerequisite. Implicit search then
treats this file as explicitly mentioned. Preserve target specific
variables of this file. */
merge_variable_set_lists(&f->variables, imf->variables);
f->pat_variables = imf->pat_variables;
f->pat_searched = imf->pat_searched;
f->also_make = imf->also_make;
f->is_target = 1;
f->intermediate = 1;
f->is_explicit |= imf->is_explicit || pat->is_explicit;
f->notintermediate |= imf->notintermediate;
f->intermediate |= !f->is_explicit && !f->notintermediate;
f->tried_implicit = 1;
imf = lookup_file (pat->pattern);
@@ -895,6 +1026,9 @@ pattern_search (struct file *file, int archive,
dep = alloc_dep ();
dep->ignore_mtime = pat->ignore_mtime;
dep->is_explicit = pat->is_explicit;
dep->ignore_automatic_vars = pat->ignore_automatic_vars;
dep->wait_here = pat->wait_here;
s = strcache_add (pat->name);
if (recursions)
dep->name = s;
@@ -920,8 +1054,14 @@ pattern_search (struct file *file, int archive,
dep->next = file->deps;
file->deps = dep;
/* The file changed its dependencies; schedule the shuffle. */
file->was_shuffled = 0;
}
if (!file->was_shuffled)
shuffle_deps_recursive (file->deps);
if (!tryrules[foundrule].checked_lastslash)
{
/* Always allocate new storage, since STEM might be on the stack for an
@@ -931,27 +1071,28 @@ pattern_search (struct file *file, int archive,
}
else
{
size_t dirlen = (lastslash + 1) - filename;
char *sp;
/* We want to prepend the directory from
the original FILENAME onto the stem. */
fullstemlen = dirlen + stemlen;
sp = alloca (fullstemlen + 1);
memcpy (sp, filename, dirlen);
memcpy (sp + dirlen, stem, stemlen);
sp[fullstemlen] = '\0';
file->stem = strcache_add (sp);
fullstemlen = pathlen + stemlen;
memcpy (stem_str, filename, pathlen);
memcpy (stem_str + pathlen, stem, stemlen);
stem_str[fullstemlen] = '\0';
file->stem = strcache_add (stem_str);
}
file->cmds = rule->cmds;
file->is_target = 1;
/* Set precious flag. */
/* Set precious and notintermediate flags. */
{
struct file *f = lookup_file (rule->targets[tryrules[foundrule].matches]);
if (f && f->precious)
file->precious = 1;
if (f)
{
if (f->precious)
file->precious = 1;
if (f->notintermediate)
file->notintermediate = 1;
}
}
/* If this rule builds other targets, too, put the others into FILE's
@@ -967,11 +1108,9 @@ pattern_search (struct file *file, int archive,
struct dep *new = alloc_dep ();
/* GKM FIMXE: handle '|' here too */
memcpy (p, rule->targets[ri],
rule->suffixes[ri] - rule->targets[ri] - 1);
p += rule->suffixes[ri] - rule->targets[ri] - 1;
memcpy (p, file->stem, fullstemlen);
p += fullstemlen;
p = mempcpy (p, rule->targets[ri],
rule->suffixes[ri] - rule->targets[ri] - 1);
p = mempcpy (p, file->stem, fullstemlen);
memcpy (p, rule->suffixes[ri],
rule->lens[ri] - (rule->suffixes[ri] - rule->targets[ri])+1);
new->name = strcache_add (nm);
@@ -980,8 +1119,13 @@ pattern_search (struct file *file, int archive,
/* Set precious flag. */
f = lookup_file (rule->targets[ri]);
if (f && f->precious)
new->file->precious = 1;
if (f)
{
if (f->precious)
new->file->precious = 1;
if (f->notintermediate)
new->file->notintermediate = 1;
}
/* Set the is_target flag so that this file is not treated as
intermediate by the pattern rule search algorithm and
@@ -995,5 +1139,21 @@ pattern_search (struct file *file, int archive,
free (tryrules);
free (deplist);
return rule != 0;
if (rule)
{
DBS (DB_IMPLICIT, (_("Found implicit rule '%s' for '%s'.\n"),
get_rule_defn (rule), filename));
return 1;
}
if (found_compat_rule)
{
DBS (DB_IMPLICIT, (_("Searching for a compatibility rule for '%s'.\n"),
filename));
assert (allow_compat_rules == 0);
return pattern_search (file, archive, depth, recursions, 1);
}
DBS (DB_IMPLICIT, (_("No implicit rule found for '%s'.\n"), filename));
return 0;
}

343
src/job.c
View File

@@ -1,5 +1,5 @@
/* Job execution and handling for GNU Make.
Copyright (C) 1988-2019 Free Software Foundation, Inc.
Copyright (C) 1988-2022 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -12,7 +12,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
this program. If not, see <https://www.gnu.org/licenses/>. */
#include "makeint.h"
@@ -25,11 +25,13 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#include "commands.h"
#include "variable.h"
#include "os.h"
#include "dep.h"
#include "shuffle.h"
/* Default shell to use. */
#ifdef WINDOWS32
# ifdef HAVE_STRINGS_H
# include <strings.h> /* for strcasecmp, strncasecmp */
# include <strings.h> /* for strcasecmp, strncasecmp */
# endif
# include <windows.h>
@@ -121,6 +123,10 @@ static void vmsWaitForChildren (int *);
# include <process.h>
#endif
#if defined (HAVE_FCNTL_H)
# include <fcntl.h>
#endif
#if defined (HAVE_SYS_WAIT_H) || defined (HAVE_UNION_WAIT)
# include <sys/wait.h>
#endif
@@ -198,6 +204,14 @@ int getgid ();
# endif
#endif
#if HAVE_SYS_LOADAVG_H
# include <sys/loadavg.h>
#endif
#if HAVE_DECL_GETLOADAVG == 0
int getloadavg (double loadavg[], int nelem);
#endif
/* Different systems have different requirements for pid_t.
Plus we have to support gettext string translation... Argh. */
static const char *
@@ -214,10 +228,6 @@ pid2str (pid_t pid)
return pidstring;
}
#ifndef HAVE_GETLOADAVG
int getloadavg (double loadavg[], int nelem);
#endif
static void free_child (struct child *);
static void start_job_command (struct child *child);
static int load_too_high (void);
@@ -272,7 +282,7 @@ create_batch_file (char const *base, int unixy, int *fd)
{
const char *const ext = unixy ? "sh" : "bat";
const char *error_string = NULL;
char temp_path[MAXPATHLEN]; /* need to know its length */
char temp_path[MAX_PATH+1]; /* need to know its length */
unsigned path_size = GetTempPath (sizeof temp_path, temp_path);
int path_is_dot = 0;
/* The following variable is static so we won't try to reuse a name
@@ -367,7 +377,7 @@ create_batch_file (char const *base, int unixy, int *fd)
*fd = -1;
if (error_string == NULL)
error_string = _("Cannot create a temporary file\n");
error_string = _("Cannot create a temporary file");
O (fatal, NILF, error_string);
/* not reached */
@@ -405,7 +415,8 @@ _is_unixy_shell (const char *path)
else if (!name) /* name and p must be 0 */
name = path;
if (*name == '/' || *name == '\\') name++;
if (ISDIRSEP (*name))
name++;
i = 0;
while (known_os2shells[i] != NULL)
@@ -428,38 +439,30 @@ is_bourne_compatible_shell (const char *path)
static const char *unix_shells[] = {
"sh",
"bash",
"dash",
"ksh",
"rksh",
"zsh",
"ash",
"dash",
NULL
};
const char **s;
/* find the rightmost '/' or '\\' */
const char *name = strrchr (path, '/');
char *p = strrchr (path, '\\');
/* find the last directory separator, or the beginning of the string. */
const char *cp = path + strlen (path);
if (name && p) /* take the max */
name = (name > p) ? name : p;
else if (p) /* name must be 0 */
name = p;
else if (!name) /* name and p must be 0 */
name = path;
if (*name == '/' || *name == '\\')
++name;
while (cp > path && !ISDIRSEP (cp[-1]))
--cp;
/* this should be able to deal with extensions on Windows-like systems */
for (s = unix_shells; *s != NULL; ++s)
{
#if defined(WINDOWS32) || defined(__MSDOS__)
size_t len = strlen (*s);
if ((strlen (name) >= len && STOP_SET (name[len], MAP_DOT|MAP_NUL))
&& strncasecmp (name, *s, len) == 0)
if ((strlen (cp) >= len && STOP_SET (cp[len], MAP_DOT|MAP_NUL))
&& strncasecmp (cp, *s, len) == 0)
#else
if (strcmp (name, *s) == 0)
if (strcmp (cp, *s) == 0)
#endif
return 1; /* a known unix-style shell */
}
@@ -504,7 +507,7 @@ block_sigs ()
static void
unblock_sigs ()
{
sigsetmask (siggetmask (0) & ~fatal_signal_mask)
sigsetmask (siggetmask () & ~fatal_signal_mask);
}
void
@@ -539,6 +542,7 @@ child_error (struct child *child,
const struct file *f = child->file;
const floc *flocp = &f->cmds->fileinfo;
const char *nm;
const char *smode;
size_t l;
if (ignored && run_silent)
@@ -557,28 +561,36 @@ child_error (struct child *child,
nm = _("<builtin>");
else
{
/* We can't use the standard <FILE>:<LINENO> syntax here because
Emacs misinterprets it and matches a bogus filename in the compile
buffer. */
char *a = alloca (strlen (flocp->filenm) + 6 + INTSTR_LENGTH + 1);
sprintf (a, "%s;%lu", flocp->filenm, flocp->lineno + flocp->offset);
sprintf (a, "%s:%lu", flocp->filenm, flocp->lineno + flocp->offset);
nm = a;
}
l = strlen (pre) + strlen (nm) + strlen (f->name) + strlen (post);
smode = shuffle_get_mode ();
if (smode)
{
#define SHUFFLE_PREFIX " shuffle="
char *a = alloca (CSTRLEN(SHUFFLE_PREFIX) + strlen (smode) + 1);
sprintf (a, SHUFFLE_PREFIX "%s", smode);
smode = a;
l += strlen (smode);
#undef SHUFFLE_PREFIX
}
OUTPUT_SET (&child->output);
show_goal_error ();
if (exit_sig == 0)
error (NILF, l + INTSTR_LENGTH,
_("%s[%s: %s] Error %d%s"), pre, nm, f->name, exit_code, post);
error (NILF, l + INTSTR_LENGTH, _("%s[%s: %s] Error %d%s%s"),
pre, nm, f->name, exit_code, post, smode ? smode : "");
else
{
const char *s = strsignal (exit_sig);
error (NILF, l + strlen (s) + strlen (dump),
"%s[%s: %s] %s%s%s", pre, nm, f->name, s, dump, post);
error (NILF, l + strlen (s) + strlen (dump), "%s[%s: %s] %s%s%s%s",
pre, nm, f->name, s, dump, post, smode ? smode : "");
}
OUTPUT_UNSET ();
@@ -598,7 +610,7 @@ child_error (struct child *child,
static unsigned int dead_children = 0;
RETSIGTYPE
void
child_handler (int sig UNUSED)
{
++dead_children;
@@ -724,9 +736,6 @@ reap_children (int block, int err)
else if (pid < 0)
{
/* A remote status command failed miserably. Punt. */
#if !defined(__MSDOS__) && !defined(_AMIGA) && !defined(WINDOWS32)
remote_status_lose:
#endif
pfatal_with_name ("remote_status");
}
else
@@ -782,8 +791,9 @@ reap_children (int block, int err)
/* Now try a blocking wait for a remote child. */
pid = remote_status (&exit_code, &exit_sig, &coredump, 1);
if (pid < 0)
goto remote_status_lose;
else if (pid == 0)
pfatal_with_name ("remote_status");
if (pid == 0)
/* No remote children either. Finally give up. */
break;
@@ -879,6 +889,9 @@ reap_children (int block, int err)
#endif /* WINDOWS32 */
}
/* Some child finished: increment the command count. */
++command_count;
/* Check if this is the child of the 'shell' function. */
if (!remote && pid == shell_function_pid)
{
@@ -924,7 +937,7 @@ reap_children (int block, int err)
to fork/exec but I don't want to bother with that. Just do the
best we can. */
EINTRLOOP(r, stat(c->cmd_name, &st));
EINTRLOOP(r, stat (c->cmd_name, &st));
if (r < 0)
e = strerror (errno);
else if (S_ISDIR(st.st_mode) || !(st.st_mode & S_IXUSR))
@@ -1010,12 +1023,10 @@ reap_children (int block, int err)
}
else
{
#ifndef NO_OUTPUT_SYNC
/* If we're sync'ing per line, write the previous line's
output before starting the next one. */
if (output_sync == OUTPUT_SYNC_LINE)
output_dump (&c->output);
#endif
/* Check again whether to start remotely.
Whether or not we want to changes over time.
Also, start_remote_job may need state set up
@@ -1046,10 +1057,8 @@ reap_children (int block, int err)
/* When we get here, all the commands for c->file are finished. */
#ifndef NO_OUTPUT_SYNC
/* Synchronize any remaining parallel output. */
output_dump (&c->output);
#endif
/* At this point c->file->update_status is success or failed. But
c->file->command_state is still cs_running if all the commands
@@ -1073,12 +1082,12 @@ reap_children (int block, int err)
{
DB (DB_JOBS, (_("Removing child %p PID %s%s from chain.\n"),
c, pid2str (c->pid), c->remote ? _(" (remote)") : ""));
/* There is now another slot open. */
if (job_slots_used > 0)
--job_slots_used;
}
/* There is now another slot open. */
if (job_slots_used > 0)
job_slots_used -= c->jobslot;
/* Remove the child from the chain and free it. */
if (lastc == 0)
children = c->next;
@@ -1105,13 +1114,27 @@ reap_children (int block, int err)
/* Free the storage allocated for CHILD. */
void
free_childbase (struct childbase *child)
{
if (child->environment != 0)
{
char **ep = child->environment;
while (*ep != 0)
free (*ep++);
free (child->environment);
}
free (child->cmd_name);
}
static void
free_child (struct child *child)
{
output_close (&child->output);
if (!jobserver_tokens)
ONS (fatal, NILF, "INTERNAL: Freeing child %p (%s) but no tokens left!\n",
ONS (fatal, NILF, "INTERNAL: Freeing child %p (%s) but no tokens left",
child, child->file->name);
/* If we're using the jobserver and this child is not the only outstanding
@@ -1137,15 +1160,8 @@ free_child (struct child *child)
free (child->command_lines);
}
if (child->environment != 0)
{
char **ep = child->environment;
while (*ep != 0)
free (*ep++);
free (child->environment);
}
free_childbase ((struct childbase*)child);
free (child->cmd_name);
free (child);
}
@@ -1335,15 +1351,13 @@ start_job_command (struct child *child)
OUTPUT_SET (&child->output);
#ifndef NO_OUTPUT_SYNC
if (! child->output.syncout)
/* We don't want to sync this command: to avoid misordered
output ensure any already-synced content is written. */
output_dump (&child->output);
#endif
/* Print the command if appropriate. */
if (just_print_flag || trace_flag
if (just_print_flag || ISDB (DB_PRINT)
|| (!(flags & COMMANDS_SILENT) && !run_silent))
OS (message, 0, "%s", p);
@@ -1411,7 +1425,7 @@ start_job_command (struct child *child)
#ifndef _AMIGA
/* Set up the environment for the child. */
if (child->environment == 0)
child->environment = target_environment (child->file);
child->environment = target_environment (child->file, child->recursive);
#endif
#if !defined(__MSDOS__) && !defined(_AMIGA) && !defined(WINDOWS32)
@@ -1443,9 +1457,6 @@ start_job_command (struct child *child)
#endif /* !VMS */
{
/* Fork the child process. */
char **parent_environ;
run_local:
block_sigs ();
@@ -1456,14 +1467,11 @@ start_job_command (struct child *child)
#else
parent_environ = environ;
jobserver_pre_child (flags & COMMANDS_RECURSE);
child->pid = child_execute_job ((struct childbase *)child,
child->good_stdin, argv);
environ = parent_environ; /* Restore value child may have clobbered. */
jobserver_post_child (flags & COMMANDS_RECURSE);
#endif /* !VMS */
@@ -1486,7 +1494,7 @@ start_job_command (struct child *child)
char *cmdline = argv[0];
/* We don't have a way to pass environment to 'system',
so we need to save and restore ours, sigh... */
char **parent_environ = environ;
char **parent_env = environ;
environ = child->environment;
@@ -1501,7 +1509,7 @@ start_job_command (struct child *child)
dos_command_running = 1;
proc_return = system (cmdline);
environ = parent_environ;
environ = parent_env;
execute_by_shell = 0; /* for the next time */
}
else
@@ -1541,8 +1549,8 @@ start_job_command (struct child *child)
{
HANDLE hPID;
char* arg0;
int outfd = FD_STDOUT;
int errfd = FD_STDERR;
int outfd = -1;
int errfd = -1;
/* make UNC paths safe for CreateProcess -- backslash format */
arg0 = argv[0];
@@ -1554,7 +1562,6 @@ start_job_command (struct child *child)
/* make sure CreateProcess() has Path it needs */
sync_Path_environment ();
#ifndef NO_OUTPUT_SYNC
/* Divert child output if output_sync in use. */
if (child->output.syncout)
{
@@ -1563,9 +1570,7 @@ start_job_command (struct child *child)
if (child->output.err >= 0)
errfd = child->output.err;
}
#else
outfd = errfd = -1;
#endif
hPID = process_easy (argv, child->environment, outfd, errfd);
if (hPID != INVALID_HANDLE_VALUE)
@@ -1647,6 +1652,8 @@ start_waiting_job (struct child *c)
c->remote ? _(" (remote)") : ""));
/* One more job slot is in use. */
++job_slots_used;
assert (c->jobslot == 0);
c->jobslot = 1;
}
children = c;
unblock_sigs ();
@@ -1865,7 +1872,7 @@ new_job (struct file *file)
/* There must be at least one child already, or we have no business
waiting for a token. */
if (!children)
O (fatal, NILF, "INTERNAL: no children as we go to sleep on read\n");
O (fatal, NILF, "INTERNAL: no children as we go to sleep on read");
/* Get a token. */
got_token = jobserver_acquire (waiting_jobs != NULL);
@@ -1884,7 +1891,7 @@ new_job (struct file *file)
/* Trace the build.
Use message here so that changes to working directories are logged. */
if (trace_flag)
if (ISDB (DB_WHY))
{
char *newer = allocated_variable_expand_for_file ("$?", c->file);
const char *nm;
@@ -1898,12 +1905,9 @@ new_job (struct file *file)
nm = n;
}
if (newer[0] == '\0')
OSS (message, 0,
_("%s: target '%s' does not exist"), nm, c->file->name);
else
OSSS (message, 0,
_("%s: update target '%s' due to: %s"), nm, c->file->name, newer);
OSSS (message, 0,
_("%s: update target '%s' due to: %s"), nm, c->file->name,
newer[0] == '\0' ? _("target does not exist") : newer);
free (newer);
}
@@ -1951,12 +1955,13 @@ job_next_command (struct child *child)
On systems which provide /proc/loadavg (e.g., Linux), we use an idea
provided by Sven C. Dack <sven.c.dack@sky.com>: retrieve the current number
of processes the kernel is running and, if it's greater than the requested
load we don't allow another job to start. We allow a job to start with
equal processes since one of those will be for make itself, which will then
pause waiting for jobs to clear.
of runnable processes, if it's greater than the requested load we don't
allow another job to start. We allow a job to start with equal processes
since one of those will be for make itself, which will then pause waiting
for jobs to clear.
Otherwise, we obtain the system load average and compare that.
If /proc/loadavg is not available for some reason, we obtain the system
load average and compare that.
The system load average is only recomputed once every N (N>=1) seconds.
However, a very parallel make can easily start tens or even hundreds of
@@ -2010,6 +2015,7 @@ load_too_high (void)
static double last_sec;
static time_t last_now;
static int proc_fd = -2;
double load, guess;
time_t now;
@@ -2066,8 +2072,8 @@ load_too_high (void)
if (p && ISDIGIT(p[1]))
{
int cnt = atoi (p+1);
DB (DB_JOBS, ("Running: system = %d / make = %u (max requested = %f)\n",
unsigned int cnt = make_toui (p+1, NULL);
DB (DB_JOBS, ("Running: system = %u / make = %u (max requested = %f)\n",
cnt, job_slots_used, max_load_average));
return (double)cnt > max_load_average;
}
@@ -2085,7 +2091,7 @@ load_too_high (void)
}
/* Find the real system load average. */
make_access ();
errno = 0;
if (getloadavg (&load, 1) != 1)
{
static int lossage = -1;
@@ -2102,7 +2108,6 @@ load_too_high (void)
lossage = errno;
load = 0;
}
user_access ();
/* If we're in a new second zero the counter and correct the backlog
value. Only keep the backlog for one extra second; after that it's 0. */
@@ -2187,7 +2192,7 @@ child_execute_job (struct childbase *child, int good_stdin, char **argv)
{
save_fdin = dup (FD_STDIN);
if (save_fdin < 0)
O (fatal, NILF, _("no more file handles: could not duplicate stdin\n"));
O (fatal, NILF, _("no more file handles: could not duplicate stdin"));
fd_noinherit (save_fdin);
dup2 (fdin, FD_STDIN);
@@ -2199,7 +2204,7 @@ child_execute_job (struct childbase *child, int good_stdin, char **argv)
save_fdout = dup (FD_STDOUT);
if (save_fdout < 0)
O (fatal, NILF,
_("no more file handles: could not duplicate stdout\n"));
_("no more file handles: could not duplicate stdout"));
fd_noinherit (save_fdout);
dup2 (fdout, FD_STDOUT);
@@ -2213,7 +2218,7 @@ child_execute_job (struct childbase *child, int good_stdin, char **argv)
save_fderr = dup (FD_STDERR);
if (save_fderr < 0)
O (fatal, NILF,
_("no more file handles: could not duplicate stderr\n"));
_("no more file handles: could not duplicate stderr"));
fd_noinherit (save_fderr);
}
@@ -2228,7 +2233,7 @@ child_execute_job (struct childbase *child, int good_stdin, char **argv)
if (save_fdin >= 0)
{
if (dup2 (save_fdin, FD_STDIN) != FD_STDIN)
O (fatal, NILF, _("Could not restore stdin\n"));
O (fatal, NILF, _("Could not restore stdin"));
else
close (save_fdin);
}
@@ -2236,7 +2241,7 @@ child_execute_job (struct childbase *child, int good_stdin, char **argv)
if (save_fdout >= 0)
{
if (dup2 (save_fdout, FD_STDOUT) != FD_STDOUT)
O (fatal, NILF, _("Could not restore stdout\n"));
O (fatal, NILF, _("Could not restore stdout"));
else
close (save_fdout);
}
@@ -2244,7 +2249,7 @@ child_execute_job (struct childbase *child, int good_stdin, char **argv)
if (save_fderr >= 0)
{
if (dup2 (save_fderr, FD_STDERR) != FD_STDERR)
O (fatal, NILF, _("Could not restore stderr\n"));
O (fatal, NILF, _("Could not restore stderr"));
else
close (save_fderr);
}
@@ -2266,7 +2271,7 @@ child_execute_job (struct childbase *child, int good_stdin, char **argv)
const int fdin = good_stdin ? FD_STDIN : get_bad_stdin ();
int fdout = FD_STDOUT;
int fderr = FD_STDERR;
pid_t pid;
pid_t pid = -1;
int r;
#if defined(USE_POSIX_SPAWN)
char *cmd;
@@ -2286,9 +2291,16 @@ child_execute_job (struct childbase *child, int good_stdin, char **argv)
#if !defined(USE_POSIX_SPAWN)
pid = vfork();
if (pid != 0)
return pid;
{
/* The child may clobber environ so remember ours and restore it. */
char **parent_env = environ;
pid = vfork ();
if (pid != 0)
{
environ = parent_env;
return pid;
}
}
/* We are the child. */
unblock_all_sigs ();
@@ -2310,6 +2322,7 @@ child_execute_job (struct childbase *child, int good_stdin, char **argv)
/* Run the command. */
exec_command (argv, child->environment);
_exit (127);
#else /* USE_POSIX_SPAWN */
@@ -2351,8 +2364,8 @@ child_execute_job (struct childbase *child, int good_stdin, char **argv)
if ((r = posix_spawn_file_actions_adddup2 (&fa, fderr, FD_STDERR)) != 0)
goto cleanup;
/* Be the user, permanently. */
flags |= POSIX_SPAWN_RESETIDS;
/* We can't use the POSIX_SPAWN_RESETIDS flag: when make is invoked under
restrictive environments like unshare it will fail with EINVAL. */
/* Apply the spawn flags. */
if ((r = posix_spawnattr_setflags (&attr, flags)) != 0)
@@ -2371,7 +2384,19 @@ child_execute_job (struct childbase *child, int good_stdin, char **argv)
break;
}
cmd = (char *)find_in_given_path (argv[0], p, 0);
/* execvp() will use a default PATH if none is set; emulate that. */
if (p == NULL)
{
size_t l = confstr (_CS_PATH, NULL, 0);
if (l)
{
char *dp = alloca (l);
confstr (_CS_PATH, dp, l);
p = dp;
}
}
cmd = (char *)find_in_given_path (argv[0], p, NULL, 0);
}
if (!cmd)
@@ -2397,7 +2422,7 @@ child_execute_job (struct childbase *child, int good_stdin, char **argv)
for (pp = argv; *pp != NULL; ++pp)
++l;
nargv = xmalloc (sizeof (char *) * (l + 2));
nargv = xmalloc (sizeof (char *) * (l + 3));
nargv[0] = (char *)default_shell;
nargv[1] = cmd;
memcpy (&nargv[2], &argv[1], sizeof (char *) * l);
@@ -2441,12 +2466,7 @@ child_execute_job (struct childbase *child, int good_stdin, char **argv)
/* Replace the current process with one running the command in ARGV,
with environment ENVP. This function does not return. */
/* EMX: This function returns the pid of the child process. */
# ifdef __EMX__
pid_t
# else
void
# endif
exec_command (char **argv, char **envp)
{
#ifdef VMS
@@ -2513,17 +2533,12 @@ exec_command (char **argv, char **envp)
}
}
/* return child's exit code as our exit code */
/* Use the child's exit code as our exit code */
exit (exit_code);
#else /* !WINDOWS32 */
# ifdef __EMX__
pid_t pid;
# endif
/* Be the user, permanently. */
child_access ();
pid_t pid = -1;
# ifdef __EMX__
/* Run the program. */
@@ -2536,7 +2551,9 @@ exec_command (char **argv, char **envp)
errno = ENOEXEC;
# else
/* Run the program. */
/* Run the program. Don't use execvpe() as we want the search for argv[0]
to use the new PATH, but execvpe() searches before resetting PATH. */
environ = envp;
execvp (argv[0], argv);
@@ -2619,11 +2636,7 @@ exec_command (char **argv, char **envp)
break;
}
# ifdef __EMX__
return pid;
# else
_exit (127);
# endif
#endif /* !WINDOWS32 */
#endif /* !VMS */
}
@@ -2646,8 +2659,8 @@ void clean_tmp (void)
avoid using a shell. This routine handles only ' quoting, and " quoting
when no backslash, $ or ' characters are seen in the quotes. Starting
quotes may be escaped with a backslash. If any of the characters in
sh_chars is seen, or any of the builtin commands listed in sh_cmds
is the first word of a line, the shell is used.
sh_chars is seen, or any of the builtin commands listed in sh_cmds is the
first word of a line, the shell is used.
If RESTP is not NULL, *RESTP is set to point to the first newline in LINE.
If *RESTP is NULL, newlines will be ignored.
@@ -2655,10 +2668,14 @@ void clean_tmp (void)
SHELL is the shell to use, or nil to use the default shell.
IFS is the value of $IFS, or nil (meaning the default).
FLAGS is the value of lines_flags for this command line. It is
used in the WINDOWS32 port to check whether + or $(MAKE) were found
in this command line, in which case the effect of just_print_flag
is overridden. */
FLAGS is the value of lines_flags for this command line. It is used in the
WINDOWS32 port to check whether + or $(MAKE) were found in this command
line, in which case the effect of just_print_flag is overridden.
The returned value is either NULL if the line was empty, or else a pointer
to an array of strings. The fist pointer points to the memory used by all
the strings, so to free you free the 0'th element then the returned pointer
(see the FREE_ARGV macro). */
static char **
construct_command_argv_internal (char *line, char **restp, const char *shell,
@@ -2744,7 +2761,7 @@ construct_command_argv_internal (char *line, char **restp, const char *shell,
/* We used to have a double quote (") in sh_chars_dos[] below, but
that caused any command line with quoted file names be run
through a temporary batch file, which introduces command-line
limit of 4K charcaters imposed by cmd.exe. Since CreateProcess
limit of 4K characters imposed by cmd.exe. Since CreateProcess
can handle quoted file names just fine, removing the quote lifts
the limit from a very frequent use case, because using quoted
file names is commonplace on MS-Windows. */
@@ -2775,9 +2792,10 @@ construct_command_argv_internal (char *line, char **restp, const char *shell,
#else /* must be UNIX-ish */
static const char *sh_chars = "#;\"*?[]&|<>(){}$`^~!";
static const char *sh_cmds[] =
{ ".", ":", "break", "case", "cd", "command", "continue", "eval", "exec",
"exit", "export", "for", "if", "login", "logout", "read", "readonly",
"set", "shift", "switch", "test", "times", "trap", "ulimit", "umask",
{ ".", ":", "alias", "bg", "break", "case", "cd", "command", "continue",
"eval", "exec", "exit", "export", "fc", "fg", "for", "getopts", "hash",
"if", "jobs", "login", "logout", "read", "readonly", "return", "set",
"shift", "test", "times", "trap", "type", "ulimit", "umask", "unalias",
"unset", "wait", "while", 0 };
# ifdef HAVE_DOS_PATHS
@@ -3028,8 +3046,7 @@ construct_command_argv_internal (char *line, char **restp, const char *shell,
}
else
#endif
if (p[1] != '\\' && p[1] != '\''
&& !ISSPACE (p[1])
if (p[1] != '\\' && p[1] != '\'' && !ISSPACE (p[1])
&& strchr (sh_chars_sh, p[1]) == 0)
/* back up one notch, to copy the backslash */
--p;
@@ -3347,25 +3364,44 @@ construct_command_argv_internal (char *line, char **restp, const char *shell,
#endif /* WINDOWS32 */
/* Create an argv list for the shell command line. */
{
int n = 0;
int n = 1;
char *nextp;
new_argv = xmalloc ((4 + sflags_len/2) * sizeof (char *));
new_argv[n++] = xstrdup (shell);
nextp = new_argv[0] = xmalloc (shell_len + sflags_len + line_len + 3);
nextp = mempcpy (nextp, shell, shell_len + 1);
/* Chop up the shellflags (if any) and assign them. */
if (! shellflags)
new_argv[n++] = xstrdup ("");
{
new_argv[n++] = nextp;
*(nextp++) = '\0';
}
else
{
const char *s = shellflags;
char *t;
size_t len;
while ((t = find_next_token (&s, &len)) != 0)
new_argv[n++] = xstrndup (t, len);
/* Parse shellflags using construct_command_argv_internal to
handle quotes. */
char **argv;
char *f = alloca (sflags_len + 1);
memcpy (f, shellflags, sflags_len + 1);
argv = construct_command_argv_internal (f, 0, 0, 0, 0, flags, 0);
if (argv)
{
char **a;
for (a = argv; *a; ++a)
{
new_argv[n++] = nextp;
nextp = stpcpy (nextp, *a) + 1;
}
free (argv[0]);
free (argv);
}
}
/* Set the command to invoke. */
new_argv[n++] = line;
new_argv[n++] = nextp;
memcpy(nextp, line, line_len + 1);
new_argv[n++] = NULL;
}
return new_argv;
@@ -3386,9 +3422,10 @@ construct_command_argv_internal (char *line, char **restp, const char *shell,
}
*(ap++) = ' ';
if (shellflags)
memcpy (ap, shellflags, sflags_len);
ap += sflags_len;
*(ap++) = ' ';
{
ap = mempcpy (ap, shellflags, sflags_len);
*(ap++) = ' ';
}
#ifdef WINDOWS32
command_ptr = ap;
#endif
@@ -3433,8 +3470,7 @@ construct_command_argv_internal (char *line, char **restp, const char *shell,
else if (unixy_shell && strneq (p, "...", 3))
{
/* The case of '...' wildcard again. */
strcpy (ap, "\\.\\.\\");
ap += 5;
ap = stpcpy (ap, "\\.\\.\\");
p += 2;
}
#endif
@@ -3450,7 +3486,7 @@ construct_command_argv_internal (char *line, char **restp, const char *shell,
#ifdef WINDOWS32
/* Some shells do not work well when invoked as 'sh -c xxx' to run a
command line (e.g. Cygnus GNUWIN32 sh.exe on WIN32 systems). In these
command line (e.g. Cygnus GNUWIN32 sh.exe on W32 systems). In these
cases, run commands via a script file. */
if (just_print_flag && !(flags & COMMANDS_RECURSE))
{
@@ -3658,8 +3694,7 @@ construct_command_argv (char *line, char **restp, struct file *file,
performed) and if shell is an absolute path without drive letter,
try whether it exists e.g.: if "/bin/sh" does not exist use
"$UNIXROOT/bin/sh" instead. */
if (unixroot && shell && strcmp (shell, last_shell) != 0
&& (shell[0] == '/' || shell[0] == '\\'))
if (unixroot && shell && ISDIRSEP (shell[0]) && !streq (shell, last_shell))
{
/* trying a new shell, check whether it exists */
size_t size = strlen (shell);

View File

@@ -1,5 +1,5 @@
/* Definitions for managing subprocesses in GNU Make.
Copyright (C) 1992-2019 Free Software Foundation, Inc.
Copyright (C) 1992-2022 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -12,7 +12,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
this program. If not, see <https://www.gnu.org/licenses/>. */
#include "output.h"
@@ -29,7 +29,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#endif
#define CHILDBASE \
char *cmd_name; /* Alloced copy of command run. */ \
char *cmd_name; /* Allocated copy of command run. */ \
char **environment; /* Environment for commands. */ \
VMSCHILD \
struct output output /* Output for this child. */
@@ -61,17 +61,19 @@ struct child
unsigned int good_stdin:1; /* Nonzero if this child has a good stdin. */
unsigned int deleted:1; /* Nonzero if targets have been deleted. */
unsigned int recursive:1; /* Nonzero for recursive command ('+' etc.) */
unsigned int jobslot:1; /* Nonzero if it's reserved a job slot. */
unsigned int dontcare:1; /* Saved dontcare flag. */
};
extern struct child *children;
/* A signal handler for SIGCHLD, if needed. */
RETSIGTYPE child_handler (int sig);
void child_handler (int sig);
int is_bourne_compatible_shell(const char *path);
void new_job (struct file *file);
void reap_children (int block, int err);
void start_waiting_jobs (void);
void free_childbase (struct childbase* child);
char **construct_command_argv (char *line, char **restp, struct file *file,
int cmd_flags, char** batch_file);
@@ -79,11 +81,9 @@ char **construct_command_argv (char *line, char **restp, struct file *file,
pid_t child_execute_job (struct childbase *child, int good_stdin, char **argv);
#ifdef _AMIGA
void exec_command (char **argv) __attribute__ ((noreturn));
#elif defined(__EMX__)
int exec_command (char **argv, char **envp);
void exec_command (char **argv) NORETURN;
#else
void exec_command (char **argv, char **envp) __attribute__ ((noreturn));
pid_t exec_command (char **argv, char **envp);
#endif
void unblock_all_sigs (void);

View File

@@ -1,5 +1,5 @@
/* Loading dynamic objects for GNU Make.
Copyright (C) 2012-2019 Free Software Foundation, Inc.
Copyright (C) 2012-2022 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -12,7 +12,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
this program. If not, see <https://www.gnu.org/licenses/>. */
#include "makeint.h"
@@ -84,12 +84,14 @@ load_object (const floc *flocp, int noerror, const char *ldname,
{
const char *err = dlerror ();
if (noerror)
DB (DB_BASIC, ("%s", err));
DB (DB_BASIC, ("%s\n", err));
else
OS (error, flocp, "%s", err);
return NULL;
}
DB (DB_VERBOSE, (_("Loaded shared object %s\n"), ldname));
/* Assert that the GPL license symbol is defined. */
symp = (load_func_t) dlsym (dlp, "plugin_is_GPL_compatible");
if (! symp)
@@ -119,19 +121,19 @@ load_object (const floc *flocp, int noerror, const char *ldname,
}
int
load_file (const floc *flocp, const char **ldname, int noerror)
load_file (const floc *flocp, struct file *file, int noerror)
{
size_t nmlen = strlen (*ldname);
const char *ldname = file->name;
size_t nmlen = strlen (ldname);
char *new = alloca (nmlen + CSTRLEN (SYMBOL_EXTENSION) + 1);
char *symname = NULL;
char *loaded;
const char *fp;
int r;
load_func_t symp;
/* Break the input into an object file name and a symbol name. If no symbol
name was provided, compute one from the object file name. */
fp = strchr (*ldname, '(');
fp = strchr (ldname, '(');
if (fp)
{
const char *ep;
@@ -142,16 +144,16 @@ load_file (const floc *flocp, const char **ldname, int noerror)
ep = strchr (fp+1, ')');
if (ep && ep[1] == '\0')
{
size_t l = fp - *ldname;;
size_t l = fp - ldname;
++fp;
if (fp == ep)
OS (fatal, flocp, _("Empty symbol name for load: %s"), *ldname);
OS (fatal, flocp, _("Empty symbol name for load: %s"), ldname);
/* Make a copy of the ldname part. */
memcpy (new, *ldname, l);
memcpy (new, ldname, l);
new[l] = '\0';
*ldname = new;
ldname = new;
nmlen = l;
/* Make a copy of the symbol name part. */
@@ -161,22 +163,22 @@ load_file (const floc *flocp, const char **ldname, int noerror)
}
}
/* Add this name to the string cache so it can be reused later. */
*ldname = strcache_add (*ldname);
/* Make sure this name is in the string cache. */
ldname = file->name = strcache_add (ldname);
/* If this object has been loaded, we're done. */
loaded = allocated_variable_expand ("$(.LOADED)");
fp = strstr (loaded, *ldname);
r = fp && (fp==loaded || fp[-1]==' ') && (fp[nmlen]=='\0' || fp[nmlen]==' ');
if (r)
goto exit;
/* If this object has been loaded, we're done: return -1 to ensure make does
not rebuild again. If a rebuild is allowed it was set up when this
object was initially loaded. */
file = lookup_file (ldname);
if (file && file->loaded)
return -1;
/* If we didn't find a symbol name yet, construct it from the ldname. */
if (! symname)
{
char *p = new;
fp = strrchr (*ldname, '/');
fp = strrchr (ldname, '/');
#ifdef HAVE_DOS_PATHS
if (fp)
{
@@ -186,82 +188,75 @@ load_file (const floc *flocp, const char **ldname, int noerror)
fp = fp2;
}
else
fp = strrchr (*ldname, '\\');
fp = strrchr (ldname, '\\');
/* The (improbable) case of d:foo. */
if (fp && *fp && fp[1] == ':')
fp++;
#endif
if (!fp)
fp = *ldname;
fp = ldname;
else
++fp;
while (isalnum (*fp) || *fp == '_')
while (isalnum ((unsigned char) *fp) || *fp == '_')
*(p++) = *(fp++);
strcpy (p, SYMBOL_EXTENSION);
symname = new;
}
DB (DB_VERBOSE, (_("Loading symbol %s from %s\n"), symname, *ldname));
DB (DB_VERBOSE, (_("Loading symbol %s from %s\n"), symname, ldname));
/* Load it! */
symp = load_object (flocp, noerror, *ldname, symname);
symp = load_object (flocp, noerror, ldname, symname);
if (! symp)
return 0;
/* Invoke the symbol. */
r = (*symp) (flocp);
/* If it succeeded, add the load file to the loaded variable. */
if (r > 0)
{
size_t loadlen = strlen (loaded);
char *newval = alloca (loadlen + strlen (*ldname) + 2);
/* Don't add a space if it's empty. */
if (loadlen)
{
memcpy (newval, loaded, loadlen);
newval[loadlen++] = ' ';
}
strcpy (&newval[loadlen], *ldname);
do_variable_definition (flocp, ".LOADED", newval, o_default, f_simple, 0);
}
/* If the load didn't fail, add the file to the .LOADED variable. */
if (r)
do_variable_definition(flocp, ".LOADED", ldname, o_file, f_append_value, 0);
exit:
free (loaded);
return r;
}
void
int
unload_file (const char *name)
{
int rc = 0;
struct load_list *d;
for (d = loaded_syms; d != NULL; d = d->next)
if (streq (d->name, name) && d->dlp)
{
if (dlclose (d->dlp))
DB (DB_VERBOSE, (_("Unloading shared object %s\n"), name));
rc = dlclose (d->dlp);
if (rc)
perror_with_name ("dlclose: ", d->name);
d->dlp = NULL;
else
d->dlp = NULL;
break;
}
return rc;
}
#else
int
load_file (const floc *flocp, const char **ldname UNUSED, int noerror)
load_file (const floc *flocp, struct file *file UNUSED, int noerror)
{
if (! noerror)
O (fatal, flocp,
_("The 'load' operation is not supported on this platform."));
_("The 'load' operation is not supported on this platform"));
return 0;
}
void
int
unload_file (const char *name UNUSED)
{
O (fatal, NILF, "INTERNAL: Cannot unload when load is not supported!");
O (fatal, NILF, "INTERNAL: Cannot unload when load is not supported");
}
#endif /* MAKE_LOAD */

View File

@@ -1,5 +1,5 @@
/* API for GNU Make dynamic objects.
Copyright (C) 2013-2019 Free Software Foundation, Inc.
Copyright (C) 2013-2022 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -12,7 +12,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
this program. If not, see <https://www.gnu.org/licenses/>. */
#include "makeint.h"

1398
src/main.c

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
/* Miscellaneous global declarations and portability cruft for GNU Make.
Copyright (C) 1988-2019 Free Software Foundation, Inc.
Copyright (C) 1988-2022 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -12,7 +12,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
this program. If not, see <https://www.gnu.org/licenses/>. */
/* We use <config.h> instead of "config.h" so that a compilation
using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
@@ -41,6 +41,21 @@ char *alloca ();
# endif
#endif
/* Some versions of GCC (e.g., 10.x) set the warn_unused_result attribute on
__builtin_alloca. This causes alloca(0) to fail and is not easily worked
around so avoid it via the preprocessor.
See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98055 */
#if defined (__has_builtin)
# if __has_builtin (__builtin_alloca)
# define free_alloca()
# else
# define free_alloca() alloca (0)
# endif
#else
# define free_alloca() alloca (0)
#endif
/* Disable assert() unless we're a maintainer.
Some asserts are compute-intensive. */
#ifndef MAKE_MAINTAINER_MODE
@@ -79,16 +94,10 @@ char *alloca ();
unless <sys/timeb.h> has been included first. */
# include <sys/timeb.h>
#endif
#if TIME_WITH_SYS_TIME
#if HAVE_SYS_TIME_H
# include <sys/time.h>
# include <time.h>
#else
# if HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
# endif
#endif
#include <time.h>
#include <errno.h>
@@ -115,7 +124,7 @@ extern int errno;
#endif
/* Some systems define _POSIX_VERSION but are not really POSIX.1. */
#if (defined (butterfly) || defined (__arm) || (defined (__mips) && defined (_SYSTYPE_SVR3)) || (defined (sequent) && defined (i386)))
#if (defined (butterfly) || (defined (__mips) && defined (_SYSTYPE_SVR3)) || (defined (sequent) && defined (i386)))
# undef POSIX
#endif
@@ -123,10 +132,6 @@ extern int errno;
# define POSIX 1
#endif
#ifndef RETSIGTYPE
# define RETSIGTYPE void
#endif
#ifndef sigmask
# define sigmask(sig) (1 << ((sig) - 1))
#endif
@@ -147,13 +152,14 @@ extern int errno;
#endif
#ifndef PATH_MAX
# ifndef POSIX
# ifdef MAXPATHLEN
# define PATH_MAX MAXPATHLEN
# else
/* Some systems (HURD) have fully dynamic pathnames with no maximum.
Ideally we'd support this but it will take some work. */
# define PATH_MAX 4096
# endif
#endif
#ifndef MAXPATHLEN
# define MAXPATHLEN 1024
#endif
#ifdef PATH_MAX
# define GET_PATH_MAX PATH_MAX
@@ -220,19 +226,22 @@ extern int vms_legacy_behavior;
extern int vms_unix_simulation;
#endif
#ifndef __attribute__
/* This feature is available in gcc versions 2.5 and later. */
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__
# define __attribute__(x)
# endif
#if !defined(__attribute__) && (__GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__)
/* Don't use __attribute__ if it's not supported. */
# define ATTRIBUTE(x)
#else
# define ATTRIBUTE(x) __attribute__ (x)
#endif
/* The __-protected variants of 'format' and 'printf' attributes
are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
# define __format__ format
# define __printf__ printf
# endif
#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
# define __format__ format
# define __printf__ printf
#endif
#define UNUSED __attribute__ ((unused))
#define UNUSED ATTRIBUTE ((unused))
#define NORETURN ATTRIBUTE ((noreturn))
#if defined (STDC_HEADERS) || defined (__GNU_LIBRARY__)
# include <stdlib.h>
@@ -255,8 +264,8 @@ void *malloc (int);
void *realloc (void *, int);
void free (void *);
void abort (void) __attribute__ ((noreturn));
void exit (int) __attribute__ ((noreturn));
void abort (void) NORETURN;
void exit (int) NORETURN;
# endif /* HAVE_STDLIB_H. */
#endif /* Standard headers. */
@@ -286,6 +295,21 @@ char *strerror (int errnum);
#if HAVE_STDINT_H
# include <stdint.h>
#endif
#if defined _MSC_VER || defined __MINGW32__
# define MK_PRI64_PREFIX "I64"
#else
# define MK_PRI64_PREFIX "ll"
#endif
#ifndef PRIdMAX
# define PRIdMAX MK_PRI64_PREFIX "d"
#endif
#ifndef PRIuMAX
# define PRIuMAX MK_PRI64_PREFIX "u"
#endif
#ifndef SCNdMAX
# define SCNdMAX PRIdMAX
#endif
#define FILE_TIMESTAMP uintmax_t
#if !defined(HAVE_STRSIGNAL)
@@ -327,7 +351,7 @@ extern mode_t umask (mode_t);
#define strneq(a, b, l) (strncmp ((a), (b), (l)) == 0)
#if defined(__GNUC__) || defined(ENUM_BITFIELDS)
#if defined(ENUM_BITFIELDS) || (defined(__GNUC__) && !defined(__STRICT_ANSI__))
# define ENUM_BITFIELD(bits) :bits
#else
# define ENUM_BITFIELD(bits)
@@ -385,11 +409,13 @@ extern int unixy_shell;
# define WIN32_LEAN_AND_MEAN
#endif /* WINDOWS32 */
/* ALL_SET() evaluates the second argument twice. */
#define ANY_SET(_v,_m) (((_v)&(_m)) != 0)
#define NONE_SET(_v,_m) (! ANY_SET ((_v),(_m)))
#define ALL_SET(_v,_m) (((_v)&(_m)) == (_m))
#define MAP_NUL 0x0001
#define MAP_BLANK 0x0002
#define MAP_BLANK 0x0002 /* space, TAB */
#define MAP_NEWLINE 0x0004
#define MAP_COMMENT 0x0008
#define MAP_SEMI 0x0010
@@ -443,10 +469,16 @@ extern int unixy_shell;
#define STOP_SET(_v,_m) ANY_SET(stopchar_map[(unsigned char)(_v)],(_m))
/* True if C is a directory separator on the current system. */
#define ISDIRSEP(c) STOP_SET((c),MAP_DIRSEP)
/* True if C is whitespace but not newline. */
#define ISBLANK(c) STOP_SET((c),MAP_BLANK)
/* True if C is whitespace including newlines. */
#define ISSPACE(c) STOP_SET((c),MAP_SPACE)
/* True if C is nul or whitespace (including newline). */
#define END_OF_TOKEN(c) STOP_SET((c),MAP_SPACE|MAP_NUL)
/* Move S past all whitespace (including newlines). */
#define NEXT_TOKEN(s) while (ISSPACE (*(s))) ++(s)
#define END_OF_TOKEN(s) while (! STOP_SET (*(s), MAP_SPACE|MAP_NUL)) ++(s)
/* We can't run setrlimit when using posix_spawn. */
#if defined(HAVE_SYS_RESOURCE_H) && defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT) && !defined(USE_POSIX_SPAWN)
@@ -461,11 +493,17 @@ extern struct rlimit stack_limit;
#define NILF ((floc *)0)
/* Number of characters in a string constant. Does NOT include the \0 byte. */
#define CSTRLEN(_s) (sizeof (_s)-1)
/* Only usable when NOT calling a macro: only use it for local functions. */
#define STRING_SIZE_TUPLE(_s) (_s), CSTRLEN(_s)
/* The number of bytes needed to represent the largest integer as a string. */
#define INTSTR_LENGTH CSTRLEN ("18446744073709551616")
/* The number of bytes needed to represent the largest signed and unsigned
integers as a string.
Does NOT include space for \0 so be sure to add it if needed.
Math suggested by Edward Welbourne <edward.welbourne@qt.io> */
#define INTSTR_LENGTH (53 * sizeof(uintmax_t) / 22 + 3)
#define DEFAULT_TTYNAME "true"
#ifdef HAVE_TTYNAME
@@ -474,8 +512,19 @@ extern struct rlimit stack_limit;
# define TTYNAME(_f) DEFAULT_TTYNAME
#endif
#ifdef VMS
# define DEFAULT_TMPDIR "/sys$scratch/"
#elif defined(P_tmpdir)
# define DEFAULT_TMPDIR P_tmpdir
#else
# define DEFAULT_TMPDIR "/tmp"
#endif
struct file;
/* Specify the location of elements read from makefiles. */
typedef struct
{
@@ -486,12 +535,12 @@ typedef struct
const char *concat (unsigned int, ...);
void message (int prefix, size_t length, const char *fmt, ...)
__attribute__ ((__format__ (__printf__, 3, 4)));
ATTRIBUTE ((__format__ (__printf__, 3, 4)));
void error (const floc *flocp, size_t length, const char *fmt, ...)
__attribute__ ((__format__ (__printf__, 3, 4)));
ATTRIBUTE ((__format__ (__printf__, 3, 4)));
void fatal (const floc *flocp, size_t length, const char *fmt, ...)
__attribute__ ((noreturn, __format__ (__printf__, 3, 4)));
void out_of_memory () __attribute__((noreturn));
ATTRIBUTE ((noreturn, __format__ (__printf__, 3, 4)));
void out_of_memory (void) NORETURN;
/* When adding macros to this list be sure to update the value of
XGETTEXT_OPTIONS in the po/Makevars file. */
@@ -509,10 +558,18 @@ void out_of_memory () __attribute__((noreturn));
#define ONS(_t,_a,_f,_n,_s) _t((_a), INTSTR_LENGTH + strlen (_s), \
(_f), (_n), (_s))
void die (int) __attribute__ ((noreturn));
void pfatal_with_name (const char *) __attribute__ ((noreturn));
void decode_env_switches (const char*, size_t line);
void temp_stdin_unlink (void);
void die (int) NORETURN;
void pfatal_with_name (const char *) NORETURN;
void perror_with_name (const char *, const char *);
#define xstrlen(_s) ((_s)==NULL ? 0 : strlen (_s))
unsigned int make_toui (const char*, const char**);
char *make_lltoa (long long, char *);
char *make_ulltoa (unsigned long long, char *);
void make_seed (unsigned int);
unsigned int make_rand (void);
pid_t make_pid (void);
void *xmalloc (size_t);
void *xcalloc (size_t);
void *xrealloc (void *, size_t);
@@ -527,9 +584,15 @@ int alpha_compare (const void *, const void *);
void print_spaces (unsigned int);
char *find_percent (char *);
const char *find_percent_cached (const char **);
FILE *get_tmpfile (char **, const char *);
ssize_t writebuf (int, const void*, size_t);
ssize_t readbuf (int, void*, size_t);
const char *get_tmpdir (void);
int get_tmpfd (char **);
FILE *get_tmpfile (char **);
ssize_t writebuf (int, const void *, size_t);
ssize_t readbuf (int, void *, size_t);
#ifndef HAVE_MEMRCHR
void *memrchr(const void *, int, size_t);
#endif
#ifndef NO_ARCHIVES
int ar_name (const char *);
@@ -537,13 +600,14 @@ void ar_parse_name (const char *, char **, char **);
int ar_touch (const char *);
time_t ar_member_date (const char *);
typedef long int (*ar_member_func_t) (int desc, const char *mem, int truncated,
typedef intmax_t (*ar_member_func_t) (int desc, const char *mem, int truncated,
long int hdrpos, long int datapos,
long int size, long int date, int uid,
long int size, intmax_t date, int uid,
int gid, unsigned int mode,
const void *arg);
long int ar_scan (const char *archive, ar_member_func_t function, const void *arg);
intmax_t ar_scan (const char *archive, ar_member_func_t function,
const void *arg);
int ar_name_equal (const char *name, const char *mem, int truncated);
#ifndef VMS
int ar_member_touch (const char *arname, const char *memname);
@@ -573,10 +637,6 @@ int gpath_search (const char *file, size_t len);
void construct_include_path (const char **arg_dirs);
void user_access (void);
void make_access (void);
void child_access (void);
char *strip_whitespace (const char **begpp, const char **endpp);
void show_goal_error (void);
@@ -593,15 +653,19 @@ int guile_gmake_setup (const floc *flocp);
/* Loadable object support. Sets to the strcached name of the loaded file. */
typedef int (*load_func_t)(const floc *flocp);
int load_file (const floc *flocp, const char **filename, int noerror);
void unload_file (const char *name);
int load_file (const floc *flocp, struct file *file, int noerror);
int unload_file (const char *name);
/* Maintainer mode support */
#ifdef MAKE_MAINTAINER_MODE
# define SPIN(_s) spin (_s)
void spin (const char* suffix);
# define DBG(_f) dbg _f
void dbg (const char *fmt, ...);
#else
# define SPIN(_s)
/* Never put this code into Git or a release. */
# define DBG(_f) compile-error
#endif
/* We omit these declarations on non-POSIX systems which define _POSIX_VERSION,
@@ -609,17 +673,16 @@ void spin (const char* suffix);
#if !defined (__GNU_LIBRARY__) && !defined (POSIX) && !defined (_POSIX_VERSION) && !defined(WINDOWS32)
long int atol ();
# ifndef VMS
long int lseek ();
# endif
# ifdef HAVE_GETCWD
# if !defined(VMS) && !defined(__DECC)
char *getcwd ();
char *getcwd (void);
# endif
# else
char *getwd ();
char *getwd (void);
# define getcwd(buf, len) getwd (buf)
# endif
@@ -643,10 +706,20 @@ int strcasecmp (const char *s1, const char *s2);
# define strncasecmp strncmpi
# else
/* Create our own, in misc.c */
int strncasecmp (const char *s1, const char *s2, int n);
int strncasecmp (const char *s1, const char *s2, size_t n);
# endif
#endif
#if !HAVE_MEMPCPY
/* Create our own, in misc.c */
void *mempcpy (void *dest, const void *src, size_t n);
#endif
#if !HAVE_STPCPY
/* Create our own, in misc.c */
char *stpcpy (char *dest, const char *src);
#endif
#define OUTPUT_SYNC_NONE 0
#define OUTPUT_SYNC_LINE 1
#define OUTPUT_SYNC_TARGET 2
@@ -663,21 +736,28 @@ extern unsigned short stopchar_map[];
extern int just_print_flag, run_silent, ignore_errors_flag, keep_going_flag;
extern int print_data_base_flag, question_flag, touch_flag, always_make_flag;
extern int env_overrides, no_builtin_rules_flag, no_builtin_variables_flag;
extern int print_version_flag, print_directory_flag, check_symlink_flag;
extern int warn_undefined_variables_flag, trace_flag, posix_pedantic;
extern int print_version_flag, print_directory, check_symlink_flag;
extern int warn_undefined_variables_flag, posix_pedantic;
extern int not_parallel, second_expansion, clock_skew_detected;
extern int rebuilding_makefiles, one_shell, output_sync, verify_flag;
extern unsigned long command_count;
extern const char *default_shell;
/* can we run commands via 'sh -c xxx' or must we use batch files? */
extern int batch_mode_shell;
#define GNUMAKEFLAGS_NAME "GNUMAKEFLAGS"
#define MAKEFLAGS_NAME "MAKEFLAGS"
/* Resetting the command script introduction prefix character. */
#define RECIPEPREFIX_NAME ".RECIPEPREFIX"
#define RECIPEPREFIX_DEFAULT '\t'
#define RECIPEPREFIX_NAME ".RECIPEPREFIX"
#define RECIPEPREFIX_DEFAULT '\t'
extern char cmd_prefix;
#define JOBSERVER_AUTH_OPT "jobserver-auth"
extern char *jobserver_auth;
extern unsigned int job_slots;
extern double max_load_average;
@@ -730,7 +810,7 @@ extern char *version_string, *remote_description, *make_host;
extern unsigned int commands_started;
extern int handling_fatal_signal;
extern volatile sig_atomic_t handling_fatal_signal;
#ifndef MIN
#define MIN(_a,_b) ((_a)<(_b)?(_a):(_b))

View File

@@ -1,5 +1,5 @@
/* Miscellaneous generic support functions for GNU Make.
Copyright (C) 1988-2019 Free Software Foundation, Inc.
Copyright (C) 1988-2022 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -12,11 +12,12 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
this program. If not, see <https://www.gnu.org/licenses/>. */
#include "makeint.h"
#include "filedef.h"
#include "dep.h"
#include "os.h"
#include "debug.h"
/* GNU make no longer supports pre-ANSI89 environments. */
@@ -24,6 +25,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#include <stdarg.h>
#ifdef WINDOWS32
# include <windows.h>
# include <io.h>
#endif
@@ -33,6 +35,71 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
# include <sys/file.h>
#endif
unsigned int
make_toui (const char *str, const char **error)
{
char *end;
unsigned long val = strtoul (str, &end, 10);
if (error)
{
if (str[0] == '\0')
*error = "Missing value";
else if (*end != '\0')
*error = "Invalid value";
else
*error = NULL;
}
return val;
}
/* Convert val into a string, written to buf. buf must be large enough
to hold the largest possible value, plus a nul byte. Returns buf.
We can't use standard PRI* here: those are based on intNN_t types. */
char *
make_lltoa (long long val, char *buf)
{
sprintf (buf, "%" MK_PRI64_PREFIX "d", val);
return buf;
}
char *
make_ulltoa (unsigned long long val, char *buf)
{
sprintf (buf, "%" MK_PRI64_PREFIX "u", val);
return buf;
}
/* Simple random number generator, for use with shuffle.
This doesn't need to be truly random, just pretty random. Use our own
implementation rather than relying on the C runtime's rand() so we always
get the same results for a given seed, regardless of C runtime. */
static unsigned int mk_state = 0;
void
make_seed (unsigned int seed)
{
mk_state = seed;
}
unsigned int
make_rand ()
{
/* mk_state must never be 0. */
if (mk_state == 0)
mk_state = (unsigned int)(time (NULL) ^ make_pid ()) + 1;
/* A simple xorshift RNG. */
mk_state ^= mk_state << 13;
mk_state ^= mk_state >> 17;
mk_state ^= mk_state << 5;
return mk_state;
}
/* Compare strings *S1 and *S2.
Return negative if the first is less, positive if it is greater,
zero if they are equal. */
@@ -172,6 +239,16 @@ concat (unsigned int num, ...)
return result;
}
#ifndef HAVE_UNISTD_H
pid_t getpid ();
#endif
pid_t make_pid ()
{
return getpid ();
}
/* Like malloc but get fatal error if memory is exhausted. */
/* Don't bother if we're using dmalloc; it provides these for us. */
@@ -260,6 +337,30 @@ xstrndup (const char *str, size_t length)
return result;
}
#ifndef HAVE_MEMRCHR
void *
memrchr(const void* str, int ch, size_t len)
{
const char* sp = str;
const char* cp = sp;
if (len == 0)
return NULL;
cp += len - 1;
while (cp[0] != ch)
{
if (cp == sp)
return NULL;
--cp;
}
return (void*)cp;
}
#endif
/* Limited INDEX:
@@ -283,7 +384,8 @@ lindex (const char *s, const char *limit, int c)
char *
end_of_token (const char *s)
{
END_OF_TOKEN (s);
while (! END_OF_TOKEN (*s))
++s;
return (char *)s;
}
@@ -407,7 +509,8 @@ free_ns_chain (struct nameseq *ns)
#ifdef MAKE_MAINTAINER_MODE
void spin(const char* type)
void
spin (const char* type)
{
char filenm[256];
struct stat dummy;
@@ -418,11 +521,31 @@ void spin(const char* type)
{
fprintf (stderr, "SPIN on %s\n", filenm);
do
#ifdef WINDOWS32
Sleep (1000);
#else
sleep (1);
#endif
while (stat (filenm, &dummy) == 0);
}
}
void
dbg (const char *fmt, ...)
{
FILE *fp = fopen ("/tmp/gmkdebug.log", "a+");
va_list args;
char buf[4096];
va_start (args, fmt);
vsprintf (buf, fmt, args);
va_end (args);
fprintf(fp, "%u: %s\n", (unsigned) make_pid (), buf);
fflush (fp);
fclose (fp);
}
#endif
@@ -445,53 +568,187 @@ umask (mode_t mask)
}
#endif
FILE *
get_tmpfile (char **name, const char *template)
#ifdef VMS
# define DEFAULT_TMPFILE "sys$scratch:gnv$make_cmdXXXXXX.com"
#else
# define DEFAULT_TMPFILE "GmXXXXXX"
#endif
const char *
get_tmpdir ()
{
FILE *file;
#ifdef HAVE_FDOPEN
int fd;
static const char *tmpdir = NULL;
if (!tmpdir)
{
#if defined (__MSDOS__) || defined (WINDOWS32) || defined (__EMX__)
# define TMP_EXTRAS "TMP", "TEMP",
#else
# define TMP_EXTRAS
#endif
const char *tlist[] = { "MAKE_TMPDIR", "TMPDIR", TMP_EXTRAS NULL };
const char **tp;
unsigned int found = 0;
for (tp = tlist; *tp; ++tp)
if ((tmpdir = getenv (*tp)) && *tmpdir != '\0')
{
struct stat st;
int r;
found = 1;
EINTRLOOP(r, stat (tmpdir, &st));
if (r < 0)
OSSS (error, NILF,
_("%s value %s: %s"), *tp, tmpdir, strerror (errno));
else if (! S_ISDIR (st.st_mode))
OSS (error, NILF,
_("%s value %s: not a directory"), *tp, tmpdir);
else
return tmpdir;
}
tmpdir = DEFAULT_TMPDIR;
if (found)
OS (error, NILF, _("using default temporary directory '%s'"), tmpdir);
}
return tmpdir;
}
static char *
get_tmptemplate ()
{
const char *tmpdir = get_tmpdir ();
char *template;
char *cp;
template = xmalloc (strlen (tmpdir) + CSTRLEN (DEFAULT_TMPFILE) + 2);
cp = stpcpy (template, tmpdir);
#if !defined VMS
/* It's not possible for tmpdir to be empty. */
if (! ISDIRSEP (cp[-1]))
*(cp++) = '/';
#endif
/* Preserve the current umask, and set a restrictive one for temp files. */
mode_t mask = umask (0077);
strcpy (cp, DEFAULT_TMPFILE);
#if defined(HAVE_MKSTEMP) || defined(HAVE_MKTEMP)
# define TEMPLATE_LEN strlen (template)
#else
# define TEMPLATE_LEN L_tmpnam
#endif
*name = xmalloc (TEMPLATE_LEN + 1);
strcpy (*name, template);
return template;
}
#if !HAVE_MKSTEMP || !HAVE_FDOPEN
/* Generate a temporary filename. This is not safe as another program could
snipe our filename after we've generated it: use this only on systems
without more secure alternatives. */
static char *
get_tmppath ()
{
char *path;
#if defined(HAVE_MKSTEMP) && defined(HAVE_FDOPEN)
/* It's safest to use mkstemp(), if we can. */
EINTRLOOP (fd, mkstemp (*name));
if (fd == -1)
file = NULL;
else
file = fdopen (fd, "w");
#else
# ifdef HAVE_MKTEMP
(void) mktemp (*name);
path = get_tmptemplate ();
if (*mktemp (path) == '\0')
pfatal_with_name ("mktemp");
# else
(void) tmpnam (*name);
path = xmalloc (L_tmpnam + 1);
if (tmpnam (path) == NULL)
pfatal_with_name ("tmpnam");
# endif
# ifdef HAVE_FDOPEN
/* Can't use mkstemp(), but guard against a race condition. */
EINTRLOOP (fd, open (*name, O_CREAT|O_EXCL|O_WRONLY, 0600));
if (fd == -1)
return 0;
file = fdopen (fd, "w");
# else
/* Not secure, but what can we do? */
file = fopen (*name, "w");
# endif
return path;
}
#endif
/* Generate a temporary file and return an fd for it. If name is NULL then
the temp file is anonymous and will be deleted when the process exits. */
int
get_tmpfd (char **name)
{
int fd = -1;
char *tmpnm;
mode_t mask;
/* If there's an os-specific way to get an anoymous temp file use it. */
if (!name)
{
fd = os_anontmp ();
if (fd >= 0)
return fd;
}
/* Preserve the current umask, and set a restrictive one for temp files.
Only really needed for mkstemp() but won't hurt for the open method. */
mask = umask (0077);
#if defined(HAVE_MKSTEMP)
tmpnm = get_tmptemplate ();
/* It's safest to use mkstemp(), if we can. */
EINTRLOOP (fd, mkstemp (tmpnm));
#else
tmpnm = get_tmppath ();
/* Can't use mkstemp(), but try to guard against a race condition. */
EINTRLOOP (fd, open (tmpnm, O_CREAT|O_EXCL|O_RDWR, 0600));
#endif
if (fd < 0)
OSS (fatal, NILF,
_("create temporary file %s: %s"), tmpnm, strerror (errno));
if (name)
*name = tmpnm;
else
{
int r;
EINTRLOOP (r, unlink (tmpnm));
if (r < 0)
OSS (fatal, NILF,
_("unlink temporary file %s: %s"), tmpnm, strerror (errno));
free (tmpnm);
}
umask (mask);
return fd;
}
/* Return a FILE* for a temporary file, opened in the safest way possible.
Set name to point to an allocated buffer containing the name of the file.
Note, this cannot be NULL! */
FILE *
get_tmpfile (char **name)
{
/* Be consistent with tmpfile, which opens as if by "wb+". */
const char *tmpfile_mode = "wb+";
FILE *file;
#if defined(HAVE_FDOPEN)
int fd = get_tmpfd (name);
ENULLLOOP (file, fdopen (fd, tmpfile_mode));
if (file == NULL)
OSS (fatal, NILF,
_("fdopen: temporary file %s: %s"), *name, strerror (errno));
#else
/* Preserve the current umask, and set a restrictive one for temp files. */
mode_t mask = umask (0077);
int err;
*name = get_tmppath ();
/* Although this fopen is insecure, it is executed only on non-fdopen
platforms, which should be a rarity nowadays. */
ENULLLOOP (file, fopen (*name, tmpfile_mode));
if (file == NULL)
OSS (fatal, NILF,
_("fopen: temporary file %s: %s"), *name, strerror (errno));
umask (mask);
#endif
return file;
}
@@ -505,8 +762,8 @@ strcasecmp (const char *s1, const char *s2)
{
while (1)
{
int c1 = (int) *(s1++);
int c2 = (int) *(s2++);
int c1 = (unsigned char) *(s1++);
int c2 = (unsigned char) *(s2++);
if (isalpha (c1))
c1 = tolower (c1);
@@ -526,12 +783,12 @@ strcasecmp (const char *s1, const char *s2)
substitute for it, define our own version. */
int
strncasecmp (const char *s1, const char *s2, int n)
strncasecmp (const char *s1, const char *s2, size_t n)
{
while (n-- > 0)
{
int c1 = (int) *(s1++);
int c2 = (int) *(s2++);
int c1 = (unsigned char) *(s1++);
int c2 = (unsigned char) *(s2++);
if (isalpha (c1))
c1 = tolower (c1);
@@ -548,254 +805,6 @@ strncasecmp (const char *s1, const char *s2, int n)
}
#endif
#ifdef GETLOADAVG_PRIVILEGED
#ifdef POSIX
/* Hopefully if a system says it's POSIX.1 and has the setuid and setgid
functions, they work as POSIX.1 says. Some systems (Alpha OSF/1 1.2,
for example) which claim to be POSIX.1 also have the BSD setreuid and
setregid functions, but they don't work as in BSD and only the POSIX.1
way works. */
#undef HAVE_SETREUID
#undef HAVE_SETREGID
#else /* Not POSIX. */
/* Some POSIX.1 systems have the seteuid and setegid functions. In a
POSIX-like system, they are the best thing to use. However, some
non-POSIX systems have them too but they do not work in the POSIX style
and we must use setreuid and setregid instead. */
#undef HAVE_SETEUID
#undef HAVE_SETEGID
#endif /* POSIX. */
#ifndef HAVE_UNISTD_H
extern int getuid (), getgid (), geteuid (), getegid ();
extern int setuid (), setgid ();
#ifdef HAVE_SETEUID
extern int seteuid ();
#else
#ifdef HAVE_SETREUID
extern int setreuid ();
#endif /* Have setreuid. */
#endif /* Have seteuid. */
#ifdef HAVE_SETEGID
extern int setegid ();
#else
#ifdef HAVE_SETREGID
extern int setregid ();
#endif /* Have setregid. */
#endif /* Have setegid. */
#endif /* No <unistd.h>. */
/* Keep track of the user and group IDs for user- and make- access. */
static int user_uid = -1, user_gid = -1, make_uid = -1, make_gid = -1;
#define access_inited (user_uid != -1)
static enum { make, user } current_access;
/* Under -d, write a message describing the current IDs. */
static void
log_access (const char *flavor)
{
if (! ISDB (DB_JOBS))
return;
/* All the other debugging messages go to stdout,
but we write this one to stderr because it might be
run in a child fork whose stdout is piped. */
fprintf (stderr, _("%s: user %lu (real %lu), group %lu (real %lu)\n"),
flavor, (unsigned long) geteuid (), (unsigned long) getuid (),
(unsigned long) getegid (), (unsigned long) getgid ());
fflush (stderr);
}
static void
init_access (void)
{
#ifndef VMS
user_uid = getuid ();
user_gid = getgid ();
make_uid = geteuid ();
make_gid = getegid ();
/* Do these ever fail? */
if (user_uid == -1 || user_gid == -1 || make_uid == -1 || make_gid == -1)
pfatal_with_name ("get{e}[gu]id");
log_access (_("Initialized access"));
current_access = make;
#endif
}
#endif /* GETLOADAVG_PRIVILEGED */
/* Give the process appropriate permissions for access to
user data (i.e., to stat files, or to spawn a child process). */
void
user_access (void)
{
#ifdef GETLOADAVG_PRIVILEGED
if (!access_inited)
init_access ();
if (current_access == user)
return;
/* We are in "make access" mode. This means that the effective user and
group IDs are those of make (if it was installed setuid or setgid).
We now want to set the effective user and group IDs to the real IDs,
which are the IDs of the process that exec'd make. */
#ifdef HAVE_SETEUID
/* Modern systems have the seteuid/setegid calls which set only the
effective IDs, which is ideal. */
if (seteuid (user_uid) < 0)
pfatal_with_name ("user_access: seteuid");
#else /* Not HAVE_SETEUID. */
#ifndef HAVE_SETREUID
/* System V has only the setuid/setgid calls to set user/group IDs.
There is an effective ID, which can be set by setuid/setgid.
It can be set (unless you are root) only to either what it already is
(returned by geteuid/getegid, now in make_uid/make_gid),
the real ID (return by getuid/getgid, now in user_uid/user_gid),
or the saved set ID (what the effective ID was before this set-ID
executable (make) was exec'd). */
if (setuid (user_uid) < 0)
pfatal_with_name ("user_access: setuid");
#else /* HAVE_SETREUID. */
/* In 4BSD, the setreuid/setregid calls set both the real and effective IDs.
They may be set to themselves or each other. So you have two alternatives
at any one time. If you use setuid/setgid, the effective will be set to
the real, leaving only one alternative. Using setreuid/setregid, however,
you can toggle between your two alternatives by swapping the values in a
single setreuid or setregid call. */
if (setreuid (make_uid, user_uid) < 0)
pfatal_with_name ("user_access: setreuid");
#endif /* Not HAVE_SETREUID. */
#endif /* HAVE_SETEUID. */
#ifdef HAVE_SETEGID
if (setegid (user_gid) < 0)
pfatal_with_name ("user_access: setegid");
#else
#ifndef HAVE_SETREGID
if (setgid (user_gid) < 0)
pfatal_with_name ("user_access: setgid");
#else
if (setregid (make_gid, user_gid) < 0)
pfatal_with_name ("user_access: setregid");
#endif
#endif
current_access = user;
log_access (_("User access"));
#endif /* GETLOADAVG_PRIVILEGED */
}
/* Give the process appropriate permissions for access to
make data (i.e., the load average). */
void
make_access (void)
{
#ifdef GETLOADAVG_PRIVILEGED
if (!access_inited)
init_access ();
if (current_access == make)
return;
/* See comments in user_access, above. */
#ifdef HAVE_SETEUID
if (seteuid (make_uid) < 0)
pfatal_with_name ("make_access: seteuid");
#else
#ifndef HAVE_SETREUID
if (setuid (make_uid) < 0)
pfatal_with_name ("make_access: setuid");
#else
if (setreuid (user_uid, make_uid) < 0)
pfatal_with_name ("make_access: setreuid");
#endif
#endif
#ifdef HAVE_SETEGID
if (setegid (make_gid) < 0)
pfatal_with_name ("make_access: setegid");
#else
#ifndef HAVE_SETREGID
if (setgid (make_gid) < 0)
pfatal_with_name ("make_access: setgid");
#else
if (setregid (user_gid, make_gid) < 0)
pfatal_with_name ("make_access: setregid");
#endif
#endif
current_access = make;
log_access (_("Make access"));
#endif /* GETLOADAVG_PRIVILEGED */
}
/* Give the process appropriate permissions for a child process.
This is like user_access, but you can't get back to make_access. */
void
child_access (void)
{
#ifdef GETLOADAVG_PRIVILEGED
if (!access_inited)
abort ();
/* Set both the real and effective UID and GID to the user's.
They cannot be changed back to make's. */
#ifndef HAVE_SETREUID
if (setuid (user_uid) < 0)
pfatal_with_name ("child_access: setuid");
#else
if (setreuid (user_uid, user_uid) < 0)
pfatal_with_name ("child_access: setreuid");
#endif
#ifndef HAVE_SETREGID
if (setgid (user_gid) < 0)
pfatal_with_name ("child_access: setgid");
#else
if (setregid (user_gid, user_gid) < 0)
pfatal_with_name ("child_access: setregid");
#endif
log_access (_("Child access"));
#endif /* GETLOADAVG_PRIVILEGED */
}
#ifdef NEED_GET_PATH_MAX
unsigned int
@@ -805,13 +814,163 @@ get_path_max (void)
if (value == 0)
{
long int x = pathconf ("/", _PC_PATH_MAX);
long x = pathconf ("/", _PC_PATH_MAX);
if (x > 0)
value = x;
value = (unsigned int) x;
else
return MAXPATHLEN;
value = PATH_MAX;
}
return value;
}
#endif
#if !HAVE_MEMPCPY
void *
mempcpy (void *dest, const void *src, size_t n)
{
return (char *) memcpy (dest, src, n) + n;
}
#endif
#if !HAVE_STPCPY
char *
stpcpy (char *dest, const char *src)
{
char *d = dest;
const char *s = src;
do
*d++ = *s;
while (*s++ != '\0');
return d - 1;
}
#endif
#if !HAVE_STRTOLL
# undef UNSIGNED
# undef USE_NUMBER_GROUPING
# undef USE_WIDE_CHAR
# define QUAD 1
# include <strtol.c>
#endif
#if !HAVE_STRERROR
char *
strerror (int errnum)
{
static char msg[256];
#define SETMSG(_e, _m) case _e: strcpy(msg, _m); break
switch (errnum)
{
#ifdef EPERM
SETMSG (EPERM , "Operation not permitted");
#endif
#ifdef ENOENT
SETMSG (ENOENT , "No such file or directory");
#endif
#ifdef ESRCH
SETMSG (ESRCH , "No such process");
#endif
#ifdef EINTR
SETMSG (EINTR , "Interrupted system call");
#endif
#ifdef EIO
SETMSG (EIO , "I/O error");
#endif
#ifdef ENXIO
SETMSG (ENXIO , "No such device or address");
#endif
#ifdef E2BIG
SETMSG (E2BIG , "Argument list too long");
#endif
#ifdef ENOEXEC
SETMSG (ENOEXEC, "Exec format error");
#endif
#ifdef EBADF
SETMSG (EBADF , "Bad file number");
#endif
#ifdef ECHILD
SETMSG (ECHILD , "No child processes");
#endif
#ifdef EAGAIN
SETMSG (EAGAIN , "Try again");
#endif
#ifdef ENOMEM
SETMSG (ENOMEM , "Out of memory");
#endif
#ifdef EACCES
SETMSG (EACCES , "Permission denied");
#endif
#ifdef EFAULT
SETMSG (EFAULT , "Bad address");
#endif
#ifdef ENOTBLK
SETMSG (ENOTBLK, "Block device required");
#endif
#ifdef EBUSY
SETMSG (EBUSY , "Device or resource busy");
#endif
#ifdef EEXIST
SETMSG (EEXIST , "File exists");
#endif
#ifdef EXDEV
SETMSG (EXDEV , "Cross-device link");
#endif
#ifdef ENODEV
SETMSG (ENODEV , "No such device");
#endif
#ifdef ENOTDIR
SETMSG (ENOTDIR, "Not a directory");
#endif
#ifdef EISDIR
SETMSG (EISDIR , "Is a directory");
#endif
#ifdef EINVAL
SETMSG (EINVAL , "Invalid argument");
#endif
#ifdef ENFILE
SETMSG (ENFILE , "File table overflow");
#endif
#ifdef EMFILE
SETMSG (EMFILE , "Too many open files");
#endif
#ifdef ENOTTY
SETMSG (ENOTTY , "Not a typewriter");
#endif
#ifdef ETXTBSY
SETMSG (ETXTBSY, "Text file busy");
#endif
#ifdef EFBIG
SETMSG (EFBIG , "File too large");
#endif
#ifdef ENOSPC
SETMSG (ENOSPC , "No space left on device");
#endif
#ifdef ESPIPE
SETMSG (ESPIPE , "Illegal seek");
#endif
#ifdef EROFS
SETMSG (EROFS , "Read-only file system");
#endif
#ifdef EMLINK
SETMSG (EMLINK , "Too many links");
#endif
#ifdef EPIPE
SETMSG (EPIPE , "Broken pipe");
#endif
#ifdef EDOM
SETMSG (EDOM , "Math argument out of domain of func");
#endif
#ifdef ERANGE
SETMSG (ERANGE , "Math result not representable");
#endif
default: sprintf (msg, "Unknown error %d", errnum); break;
}
return msg;
}
#endif

36
src/mkconfig.h.in Normal file
View File

@@ -0,0 +1,36 @@
/* Autoconf values for use on non-POSIX systems.
Copyright (C) 2022 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3 of the License, or (at your option) any later
version.
GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <https://www.gnu.org/licenses/>. */
/* Name of package */
#define PACKAGE "@PACKAGE@"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "@PACKAGE_BUGREPORT@"
/* Define to the full name of this package. */
#define PACKAGE_NAME "@PACKAGE_NAME@"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "@PACKAGE_NAME@ @PACKAGE_VERSION@"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "@PACKAGE_TARNAME@"
/* Define to the home page for this package. */
#define PACKAGE_URL "@PACKAGE_URL@"
/* Define to the version of this package. */
#define PACKAGE_VERSION "@PACKAGE_VERSION@"

123
src/os.h
View File

@@ -1,5 +1,5 @@
/* Declarations for operating system interfaces for GNU Make.
Copyright (C) 2016-2019 Free Software Foundation, Inc.
Copyright (C) 2016-2022 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -12,8 +12,35 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
this program. If not, see <https://www.gnu.org/licenses/>. */
#define IO_UNKNOWN 0x0001
#define IO_COMBINED_OUTERR 0x0002
#define IO_STDIN_OK 0x0004
#define IO_STDOUT_OK 0x0008
#define IO_STDERR_OK 0x0010
#if defined(VMS) || defined(_AMIGA) || defined(__MSDOS__)
# define check_io_state() (IO_STDIN_OK|IO_STDOUT_OK|IO_STDERR_OK)
# define fd_inherit(_i) (0)
# define fd_noinherit(_i) (0)
# define fd_set_append(_i) (void)(0)
# define os_anontmp() (-1)
#else
/* Determine the state of stdin/stdout/stderr. */
unsigned int check_io_state (void);
/* Set a file descriptor to close/not close in a subprocess. */
void fd_inherit (int);
void fd_noinherit (int);
/* If the file descriptor is for a file put it into append mode. */
void fd_set_append (int);
/* Return a file descriptor for a new anonymous temp file, or -1. */
int os_anontmp (void);
#endif
/* This section provides OS-specific functions to support the jobserver. */
@@ -22,19 +49,26 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Returns 1 if the jobserver is enabled, else 0. */
unsigned int jobserver_enabled (void);
/* Called in the master instance to set up the jobserver initially. */
unsigned int jobserver_setup (int job_slots);
/* Called in the parent make to set up the jobserver initially. */
unsigned int jobserver_setup (int job_slots, const char *style);
/* Called in a child instance to connect to the jobserver. */
/* Called in a child instance to connect to the jobserver.
Return 1 if we got a valid auth, else 0. */
unsigned int jobserver_parse_auth (const char* auth);
/* Returns an allocated buffer used to pass to child instances. */
char *jobserver_get_auth (void);
/* Clear this instance's jobserver configuration. */
/* Returns a pointer to a static string used to indicate that the child
cannot access the jobserver, or NULL if it always can. */
const char *jobserver_get_invalid_auth (void);
/* Clear this instance's jobserver configuration.
This method might be invoked from a signal handler. */
void jobserver_clear (void);
/* Recover all the jobserver tokens and return the number we got. */
/* Recover all the jobserver tokens and return the number we got.
Will also run jobserver_clear() as a side-effect. */
unsigned int jobserver_acquire_all (void);
/* Release a jobserver token. If it fails and is_fatal is 1, fatal. */
@@ -61,20 +95,60 @@ unsigned int jobserver_acquire (int timeout);
#else
#define jobserver_enabled() (0)
#define jobserver_setup(_slots) (0)
#define jobserver_parse_auth(_auth) (0)
#define jobserver_get_auth() (NULL)
#define jobserver_clear() (void)(0)
#define jobserver_release(_fatal) (void)(0)
#define jobserver_acquire_all() (0)
#define jobserver_signal() (void)(0)
#define jobserver_pre_child(_r) (void)(0)
#define jobserver_post_child(_r) (void)(0)
#define jobserver_pre_acquire() (void)(0)
#define jobserver_acquire(_tmout) (0)
#define jobserver_enabled() (0)
#define jobserver_setup(_slots, _style) (0)
#define jobserver_parse_auth(_auth) (0)
#define jobserver_get_auth() (NULL)
#define jobserver_get_invalid_auth() (NULL)
#define jobserver_clear() (void)(0)
#define jobserver_release(_fatal) (void)(0)
#define jobserver_acquire_all() (0)
#define jobserver_signal() (void)(0)
#define jobserver_pre_child(_r) (void)(0)
#define jobserver_post_child(_r) (void)(0)
#define jobserver_pre_acquire() (void)(0)
#define jobserver_acquire(_tmout) (0)
#endif
#endif /* MAKE_JOBSERVER */
#ifndef NO_OUTPUT_SYNC
/* Returns 1 if output sync is enabled, else 0. */
unsigned int osync_enabled (void);
/* Called in the parent make to set up output sync initially. */
void osync_setup (void);
/* Returns an allocated buffer containing output sync info to pass to child
instances, or NULL if not needed. */
char *osync_get_mutex (void);
/* Called in a child instance to obtain info on the output sync mutex.
Return 1 if we got a valid mutex, else 0. */
unsigned int osync_parse_mutex (const char *mutex);
/* Clean up this instance's output sync facilities.
This method might be invoked from a signal handler. */
void osync_clear (void);
/* Acquire the output sync lock. This will wait until available.
Returns 0 if there was an error getting the semaphore. */
unsigned int osync_acquire (void);
/* Release the output sync lock. */
void osync_release (void);
#else
#define osync_enabled() (0)
#define osync_setup() (void)(0)
#define osync_get_mutex() (0)
#define osync_parse_mutex(_s) (0)
#define osync_clear() (void)(0)
#define osync_acquire() (1)
#define osync_release() (void)(0)
#endif /* NO_OUTPUT_SYNC */
/* Create a "bad" file descriptor for stdin when parallel jobs are run. */
#if defined(VMS) || defined(WINDOWS32) || defined(_AMIGA) || defined(__MSDOS__)
@@ -82,12 +156,3 @@ unsigned int jobserver_acquire (int timeout);
#else
int get_bad_stdin (void);
#endif
/* Set a file descriptor to close/not close in a subprocess. */
#if defined(VMS) || defined(_AMIGA) || defined(__MSDOS__)
# define fd_inherit(_i) 0
# define fd_noinherit(_i) 0
#else
void fd_inherit (int);
void fd_noinherit (int);
#endif

View File

@@ -1,5 +1,5 @@
/* Output to stdout / stderr for GNU make
Copyright (C) 2013-2019 Free Software Foundation, Inc.
Copyright (C) 2013-2022 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -12,7 +12,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
this program. If not, see <https://www.gnu.org/licenses/>. */
#include "makeint.h"
#include "os.h"
@@ -47,30 +47,28 @@ unsigned int stdio_traced = 0;
#define OUTPUT_ISSET(_out) ((_out)->out >= 0 || (_out)->err >= 0)
#ifdef HAVE_FCNTL_H
# define STREAM_OK(_s) ((fcntl (fileno (_s), F_GETFD) != -1) || (errno != EBADF))
#else
# define STREAM_OK(_s) 1
#endif
/* Write a string to the current STDOUT or STDERR. */
static void
_outputs (struct output *out, int is_err, const char *msg)
{
if (! out || ! out->syncout)
{
FILE *f = is_err ? stderr : stdout;
fputs (msg, f);
fflush (f);
}
else
FILE *f;
if (out && out->syncout)
{
int fd = is_err ? out->err : out->out;
size_t len = strlen (msg);
int r;
EINTRLOOP (r, lseek (fd, 0, SEEK_END));
writebuf (fd, msg, len);
if (fd != OUTPUT_NONE)
{
size_t len = strlen (msg);
int r;
EINTRLOOP (r, lseek (fd, 0, SEEK_END));
writebuf (fd, msg, len);
return;
}
}
f = is_err ? stderr : stdout;
fputs (msg, f);
fflush (f);
}
/* Write a message indicating that we've just entered or
@@ -143,73 +141,10 @@ log_working_directory (int entering)
return 1;
}
/* Set a file descriptor to be in O_APPEND mode.
If it fails, just ignore it. */
static void
set_append_mode (int fd)
{
#if defined(F_GETFL) && defined(F_SETFL) && defined(O_APPEND)
int flags = fcntl (fd, F_GETFL, 0);
if (flags >= 0)
{
int r;
EINTRLOOP(r, fcntl (fd, F_SETFL, flags | O_APPEND));
}
#endif
}
#ifndef NO_OUTPUT_SYNC
/* Semaphore for use in -j mode with output_sync. */
static sync_handle_t sync_handle = -1;
#define FD_NOT_EMPTY(_f) ((_f) != OUTPUT_NONE && lseek ((_f), 0, SEEK_END) > 0)
/* Set up the sync handle. Disables output_sync on error. */
static int
sync_init (void)
{
int combined_output = 0;
#ifdef WINDOWS32
if ((!STREAM_OK (stdout) && !STREAM_OK (stderr))
|| (sync_handle = create_mutex ()) == -1)
{
perror_with_name ("output-sync suppressed: ", "stderr");
output_sync = 0;
}
else
{
combined_output = same_stream (stdout, stderr);
prepare_mutex_handle_string (sync_handle);
}
#else
if (STREAM_OK (stdout))
{
struct stat stbuf_o, stbuf_e;
sync_handle = fileno (stdout);
combined_output = (fstat (fileno (stdout), &stbuf_o) == 0
&& fstat (fileno (stderr), &stbuf_e) == 0
&& stbuf_o.st_dev == stbuf_e.st_dev
&& stbuf_o.st_ino == stbuf_e.st_ino);
}
else if (STREAM_OK (stderr))
sync_handle = fileno (stderr);
else
{
perror_with_name ("output-sync suppressed: ", "stderr");
output_sync = 0;
}
#endif
return combined_output;
}
/* Support routine for output_sync() */
static void
pump_from_tmp (int from, FILE *to)
@@ -250,55 +185,13 @@ pump_from_tmp (int from, FILE *to)
#endif
}
/* Obtain the lock for writing output. */
static void *
acquire_semaphore (void)
{
static struct flock fl;
fl.l_type = F_WRLCK;
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 1;
if (fcntl (sync_handle, F_SETLKW, &fl) != -1)
return &fl;
perror ("fcntl()");
return NULL;
}
/* Release the lock for writing output. */
static void
release_semaphore (void *sem)
{
struct flock *flp = (struct flock *)sem;
flp->l_type = F_UNLCK;
if (fcntl (sync_handle, F_SETLKW, flp) == -1)
perror ("fcntl()");
}
/* Returns a file descriptor to a temporary file. The file is automatically
closed/deleted on exit. Don't use a FILE* stream. */
/* Returns a file descriptor to a temporary file, that will be automatically
deleted on exit. */
int
output_tmpfd (void)
{
mode_t mask = umask (0077);
int fd = -1;
FILE *tfile = tmpfile ();
if (! tfile)
pfatal_with_name ("tmpfile");
/* Create a duplicate so we can close the stream. */
fd = dup (fileno (tfile));
if (fd < 0)
pfatal_with_name ("dup");
fclose (tfile);
set_append_mode (fd);
umask (mask);
int fd = get_tmpfd (NULL);
fd_set_append (fd);
return fd;
}
@@ -309,13 +202,25 @@ output_tmpfd (void)
static void
setup_tmpfile (struct output *out)
{
/* Is make's stdout going to the same place as stderr? */
static int combined_output = -1;
static unsigned int in_setup = 0;
unsigned int io_state;
if (combined_output < 0)
combined_output = sync_init ();
/* If something fails during setup we might recurse back into this function
while writing errors. Make sure we don't do so infinitely. */
if (in_setup)
return;
in_setup = 1;
if (STREAM_OK (stdout))
io_state = check_io_state ();
if (NONE_SET (io_state, IO_STDOUT_OK|IO_STDERR_OK))
{
/* This is probably useless since stdout/stderr aren't working. */
perror_with_name ("output-sync suppressed: ", "stderr");
goto error;
}
if (ANY_SET (io_state, IO_STDOUT_OK))
{
int fd = output_tmpfd ();
if (fd < 0)
@@ -324,9 +229,9 @@ setup_tmpfile (struct output *out)
out->out = fd;
}
if (STREAM_OK (stderr))
if (ANY_SET (io_state, IO_STDERR_OK))
{
if (out->out != OUTPUT_NONE && combined_output)
if (out->out != OUTPUT_NONE && ANY_SET (io_state, IO_COMBINED_OUTERR))
out->err = out->out;
else
{
@@ -338,12 +243,15 @@ setup_tmpfile (struct output *out)
}
}
in_setup = 0;
return;
/* If we failed to create a temp file, disable output sync going forward. */
error:
output_close (out);
output_sync = OUTPUT_SYNC_NONE;
osync_clear ();
in_setup = 0;
}
/* Synchronize the output of jobs in -j mode to keep the results of
@@ -354,6 +262,8 @@ setup_tmpfile (struct output *out)
void
output_dump (struct output *out)
{
#define FD_NOT_EMPTY(_f) ((_f) != OUTPUT_NONE && lseek ((_f), 0, SEEK_END) > 0)
int outfd_not_empty = FD_NOT_EMPTY (out->out);
int errfd_not_empty = FD_NOT_EMPTY (out->err);
@@ -364,10 +274,15 @@ output_dump (struct output *out)
/* Try to acquire the semaphore. If it fails, dump the output
unsynchronized; still better than silently discarding it.
We want to keep this lock for as little time as possible. */
void *sem = acquire_semaphore ();
if (!osync_acquire ())
{
O (error, NILF,
_("warning: Cannot acquire output lock, disabling output sync."));
osync_clear ();
}
/* Log the working directory for this dump. */
if (print_directory_flag && output_sync != OUTPUT_SYNC_RECURSE)
if (print_directory && output_sync != OUTPUT_SYNC_RECURSE)
traced = log_working_directory (1);
if (outfd_not_empty)
@@ -379,8 +294,7 @@ output_dump (struct output *out)
log_working_directory (0);
/* Exit the critical section. */
if (sem)
release_semaphore (sem);
osync_release ();
/* Truncate and reset the output, in case we use it again. */
if (out->out != OUTPUT_NONE)
@@ -400,53 +314,6 @@ output_dump (struct output *out)
#endif /* NO_OUTPUT_SYNC */
/* This code is stolen from gnulib.
If/when we abandon the requirement to work with K&R compilers, we can
remove this (and perhaps other parts of GNU make!) and migrate to using
gnulib directly.
This is called only through atexit(), which means die() has already been
invoked. So, call exit() here directly. Apparently that works...?
*/
/* Close standard output, exiting with status 'exit_failure' on failure.
If a program writes *anything* to stdout, that program should close
stdout and make sure that it succeeds before exiting. Otherwise,
suppose that you go to the extreme of checking the return status
of every function that does an explicit write to stdout. The last
printf can succeed in writing to the internal stream buffer, and yet
the fclose(stdout) could still fail (due e.g., to a disk full error)
when it tries to write out that buffered data. Thus, you would be
left with an incomplete output file and the offending program would
exit successfully. Even calling fflush is not always sufficient,
since some file systems (NFS and CODA) buffer written/flushed data
until an actual close call.
Besides, it's wasteful to check the return value from every call
that writes to stdout -- just let the internal stream state record
the failure. That's what the ferror test is checking below.
It's important to detect such failures and exit nonzero because many
tools (most notably 'make' and other build-management systems) depend
on being able to detect failure in other tools via their exit status. */
static void
close_stdout (void)
{
int prev_fail = ferror (stdout);
int fclose_fail = fclose (stdout);
if (prev_fail || fclose_fail)
{
if (fclose_fail)
perror_with_name (_("write error: stdout"), "");
else
O (error, NILF, _("write error: stdout"));
exit (MAKE_TROUBLE);
}
}
void
output_init (struct output *out)
{
@@ -457,28 +324,10 @@ output_init (struct output *out)
return;
}
/* Configure this instance of make. Be sure stdout is line-buffered. */
#ifdef HAVE_SETVBUF
# ifdef SETVBUF_REVERSED
setvbuf (stdout, _IOLBF, xmalloc (BUFSIZ), BUFSIZ);
# else /* setvbuf not reversed. */
/* Some buggy systems lose if we pass 0 instead of allocating ourselves. */
setvbuf (stdout, 0, _IOLBF, BUFSIZ);
# endif /* setvbuf reversed. */
#elif HAVE_SETLINEBUF
setlinebuf (stdout);
#endif /* setlinebuf missing. */
/* Force stdout/stderr into append mode. This ensures parallel jobs won't
lose output due to overlapping writes. */
set_append_mode (fileno (stdout));
set_append_mode (fileno (stderr));
#ifdef HAVE_ATEXIT
if (STREAM_OK (stdout))
atexit (close_stdout);
#endif
/* Force stdout/stderr into append mode (if they are files) to ensure
parallel jobs won't lose output due to overlapping writes. */
fd_set_append (fileno (stdout));
fd_set_append (fileno (stderr));
}
void
@@ -517,7 +366,7 @@ output_start (void)
/* If we're not syncing this output per-line or per-target, make sure we emit
the "Entering..." message where appropriate. */
if (output_sync == OUTPUT_SYNC_NONE || output_sync == OUTPUT_SYNC_RECURSE)
if (! stdio_traced && print_directory_flag)
if (! stdio_traced && print_directory)
stdio_traced = log_working_directory (1);
}
@@ -560,10 +409,11 @@ void
message (int prefix, size_t len, const char *fmt, ...)
{
va_list args;
char *start;
char *p;
len += strlen (fmt) + strlen (program) + INTSTR_LENGTH + 4 + 1 + 1;
p = get_buffer (len);
start = p = get_buffer (len);
if (prefix)
{
@@ -580,8 +430,8 @@ message (int prefix, size_t len, const char *fmt, ...)
strcat (p, "\n");
assert (fmtbuf.buffer[len-1] == '\0');
outputs (0, fmtbuf.buffer);
assert (start[len-1] == '\0');
outputs (0, start);
}
/* Print an error message. */
@@ -590,12 +440,13 @@ void
error (const floc *flocp, size_t len, const char *fmt, ...)
{
va_list args;
char *start;
char *p;
len += (strlen (fmt) + strlen (program)
+ (flocp && flocp->filenm ? strlen (flocp->filenm) : 0)
+ INTSTR_LENGTH + 4 + 1 + 1);
p = get_buffer (len);
start = p = get_buffer (len);
if (flocp && flocp->filenm)
sprintf (p, "%s:%lu: ", flocp->filenm, flocp->lineno + flocp->offset);
@@ -611,8 +462,8 @@ error (const floc *flocp, size_t len, const char *fmt, ...)
strcat (p, "\n");
assert (fmtbuf.buffer[len-1] == '\0');
outputs (1, fmtbuf.buffer);
assert (start[len-1] == '\0');
outputs (1, start);
}
/* Print an error message and exit. */
@@ -622,12 +473,13 @@ fatal (const floc *flocp, size_t len, const char *fmt, ...)
{
va_list args;
const char *stop = _(". Stop.\n");
char *start;
char *p;
len += (strlen (fmt) + strlen (program)
+ (flocp && flocp->filenm ? strlen (flocp->filenm) : 0)
+ INTSTR_LENGTH + 8 + strlen (stop) + 1);
p = get_buffer (len);
start = p = get_buffer (len);
if (flocp && flocp->filenm)
sprintf (p, "%s:%lu: *** ", flocp->filenm, flocp->lineno + flocp->offset);
@@ -643,8 +495,8 @@ fatal (const floc *flocp, size_t len, const char *fmt, ...)
strcat (p, stop);
assert (fmtbuf.buffer[len-1] == '\0');
outputs (1, fmtbuf.buffer);
assert (start[len-1] == '\0');
outputs (1, start);
die (MAKE_FAILURE);
}

Some files were not shown because too many files have changed in this diff Show More