Compare commits

...

196 Commits
3.99.91 ... 4.2

Author SHA1 Message Date
Paul Smith
ec61980122 GNU Make release 4.2. 2016-05-22 09:25:55 -04:00
Joe Crayne
9bb994e831 [SV 44742] Fix double-colon rules plus parallel builds.
* remake.c (update_file): Don't update double-colon target status
if we're still building targets.
(ftime_t): Don't propagate timestamps for double-colon targets that
we've not examined yet.
* tests/scripts/features/double_colon: Add parallel build tests.

Copyright-paperwork-exempt: yes
2016-05-21 17:34:45 -04:00
Paul Smith
e2ebea35f1 * read.c (eval): [SV 47960] Skip record waiting files when ignoring.
* tests/scripts/features/conditionals: Test this scenario.
2016-05-21 16:22:32 -04:00
Paul Smith
c73ed7dd1c Separate the GNU make load ABI from internal types.
Create an internal type "floc" and convert all users to that type.
* gnumake.h (gmk_floc): Remove the offset field from this type.
* loadapi.c (gmk_eval): Convert gmk_floc to internal floc.
2016-05-21 16:22:32 -04:00
Paul Eggert
ba8383efd8 Fixes for enhanced GCC warnings.
Move function prototypes into header files and out of .c files.
Use void argument lists for functions that accept no args.
Remove unused macros.  Make private functions static.  Align
types with printf format characters.
2016-05-21 16:22:25 -04:00
Paul Smith
6f7fb050b4 Fix compile issues with Windows and VMS.
* main.c (initialize_stopchar_map): isblank() is not part of C89.
Install bits for space and tab directly.
* makeint.h: Don't define vfork; autoconf handles this for us.
* vmsjobs.c: Rename NEXT_TOKEN to V_NEXT_TOKEN to avoid conflicts.
* dir.c (print_dir_data_base): Visual Studio C doesn't have int64_t.
* w32/subproc/sub_proc.c (process_begin): Missing arg to memset().
* build_w32.bat: Don't use obsolete Visual Studio flags.
2016-05-21 16:21:31 -04:00
Paul Smith
45200a42d3 Allow compiling with an ISO C 1989/1990 compiler.
* posixos.c (jobserver_post_child): Use C89 for loop syntax.
* remake.c (update_goal_chain): Ditto.
* variable.c (parse_variable_definition): Ditto.
2016-05-21 14:30:37 -04:00
Eli Zaretskii
4c9e10fd94 [SV 47942] Avoid random crashes in subordinate programs on MS-Windows
* w32/subproc/sub_proc.c (process_begin): Zero out startInfo
before using it.  Fixes crashes in Intel Fortran compiler invoked
by Make.
2016-05-17 18:15:26 +03:00
Eli Zaretskii
6e640321fd Fix the MS-Windows MinGW build
* build_w32.bat (GccCompile): Use -std=gnu99, as some code uses
C99 features ('for' loop initial declarations).

* dir.c (print_dir_data_base) [WINDOWS32]: Cast 'mtime' to
'int64_t', and use %I64d to print it, to avoid compile-time
warning about printing a 'time_t' value, which could be either
a 32-bit or a 64 bit integral type.
2016-04-24 09:53:38 +03:00
Paul Smith
7241d136f4 * tests/scripts/features/output-sync: increase test timeout.
I'm getting random failures with a timeout of 10s; increase to 30s.
2016-04-23 11:21:36 -04:00
Paul Smith
c2be1df880 * NEWS: Update for pre-release 2016-04-11 07:51:05 -04:00
Paul Smith
f1a9625001 * dep.h, makeint.h (show_goal_error): Move to makeint.h. 2016-04-11 07:51:05 -04:00
Paul Smith
047bd5a16f [SV 46433] Show recipe line offsets in line number messages.
While displaying line numbers, show the relevant line number inside
the recipe not just the first line of the entire recipe.
Sample changes suggested by Brian Vandenberg <phantall@gmail.com>

* gnumake.h (gmk_floc): Add an 'offset' to track the recipe offset.
* read.c (eval, eval_makefile, eval_buffer): Initialize 'offset'.
(record_files, install_pattern_rule): Ditto.
* job.c (new_job, job_next_command): Update 'offset' based on the
line of the recipe we're expanding or invoking.
(child_error): Add 'offset' when showing the line number.
* function.c (func_shell_base): Ditto.
* output.c (error, fatal): Ditto.
* NEWS: Mention the new ability.
* tests/scripts/features/errors: Check the line number on errors.
* tests/scripts/functions/warning: Check the line number on warnings.
* tests/scripts/features/output-sync,
tests/scripts/features/parallelism, tests/scripts/functions/shell,
tests/scripts/functions/error: Update line numbers.
2016-04-11 07:51:05 -04:00
Paul Smith
3fc99a48e1 * maintMakefile: Add a rule for storing preprocessor output. 2016-04-09 20:06:46 -04:00
Paul Smith
87a5f98d24 [SV 102] Don't show unnecessary include file errors.
Delay the generation of error messages for included files until we
are sure that we can't rebuild that included file.
* dep.h (struct dep): Don't reuse "changed"; make a separate field
to keep "flags".  Get rid of dontcare and use the flag.
(struct goaldep): Create a new structure for goal prereqs
that tracks an errno value and the floc where the include happened.
Rework the structures to ensure they are supersets as expected.
In maintainer mode with GCC, use inline to get type checking.
* read.c (eval_makefile): Return a struct goaldep for the new
makefile.  Ensure errno is set properly to denote a failure.
(read_all_makefiles): Switch to goaldep and check errno.
(eval): Don't show included file errors; instead remember them.
* remake.c (update_goal_chain): Set global variables to the current
goaldep we're building, and the entire chain.
(show_goal_error): Check if the current failure is a consequence
of building an included makefile and if so print an error.
(complain): Call show_goal_error() on rule failure.
* job.c (child_error): Call show_goal_error() on child error.
* main.c (main): Switch from struct dep to goaldep.
* misc.c (free_dep_chain): Not used; make into a macro.
* tests/scripts/features/include: Update and include new tests.
* tests/scripts/options/dash-B, tests/scripts/options/dash-W,
tests/scripts/options/print-directory,
tests/scripts/variables/MAKE_RESTARTS: Update known-good-output.
2016-04-09 20:06:46 -04:00
Paul Smith
53554e41e8 * job.c (child_error): Add filename length to output length.
Reported by Dale Stimson <dale@riyescott.com>
2016-04-09 09:25:50 -04:00
Paul Smith
5bd7ad2b22 Preserve the real value of -jN in MAKEFLAGS using jobserver.
Previously if the jobserver was active, MAKEFLAGS would contain only
the -j option but not the number (not -j5 or whatever) so users
could not discover that value.  Allow that value to be provided in
MAKEFLAGS without error but still give warnings if -jN is provided
on the command line if the jobserver is already activated.

* NEWS: Discuss the new behavior.
* os.h, posixos.c, w32/w32os.c: Return success/failure from
jobserver_setup() and jobserver_parse_auth().
* main.c (main): Separate the command line storage of job slots (now
in arg_job_slots) from the control storage (in job_slots).  Make a
distinction between -jN flags read from MAKEFLAGS and those seen
on the command line: for the latter if the jobserver is enabled then
warn and disable it, as before.
* tests/scripts/features/jobserver: Add new testing.
2016-04-04 01:38:37 -04:00
Paul Smith
65115e7095 * tests/run_make_tests.pl: Add file/lineno info to .run file. 2016-04-04 01:38:37 -04:00
Paul Smith
75dd0bd8bc * maintMakefile: Fix logging of check-alt-config target. 2016-04-04 01:38:37 -04:00
Paul Smith
8b54c5cff9 * job.c (child_execute_job): Fix $(shell...) under NO_OUTPUT_SYNC.
* main.c (decode_output_sync_flags): Use NONE for NO_OUTPUT_SYNC.
2016-04-04 01:38:32 -04:00
Paul Smith
65c447289e * main.c (main): Restrict disabling debugging for MAKEFILES. 2016-04-04 01:36:08 -04:00
Paul Smith
86b20728fe * Makefile.am, w32/Makefile.am: Fix *os.c for Windows builds.
Original change provided by Luke Allardyce <lukeallardyce@gmail.com>
2016-04-04 01:36:08 -04:00
Paul Smith
b8a8af6550 * make.texi: Confirm that CURDIR contains an absolute path. 2016-04-04 01:36:08 -04:00
Paul Smith
360b76af84 * docs/make.texi: [SV 47392] Add "Integrating make" chapter. 2016-04-04 01:36:08 -04:00
Paul Smith
c9e6ab9ac7 Change --jobserver-fds to more generic --jobserver-auth.
* NEWS: Mention the change.
* main.c: Rename jobserver_fds variable to jobserver_auth and
--jobserver-fds option to --jobserver-auth.
* os.h, posixos.c, w32/w32os.c: Rename jobserver_parse_arg() and
jobserver_get_arg() to jobserver_parse_auth()/jobserver_get_auth().
2016-04-04 01:36:08 -04:00
Paul Smith
40277b8850 * tests/run_make_tests.pl: Preserve $make_command
* tests/scripts/options/dash-n: Use $make_command.  This fixes
a spurious failure when running tests with valgrind enabled.
2016-03-23 01:26:55 -04:00
Paul Smith
35047f824a * variable.c: Clean up some memory leaks. 2016-03-23 01:26:04 -04:00
Paul Smith
e97159745d [SV 46995] Strip leading/trailing space from variable names
* makeint.h: Change MAP_SPACE to MAP_NEWLINE, and add MAP_PATHSEP
and MAP_SPACE which is now MAP_BLANK|MAP_NEWLINE.  Create
NEW_TOKEN(), END_OF_TOKEN(), ISBLANK(), ISSPACE() macros.
* main.c (initialize_stopchar_map): Set MAP_NEWLINE only for
newline characters.
* Convert all uses of isblank() and isspace() to macros.
* Examine all uses of isblank() (doesn't accept newlines) and
change them wherever possible to ISSPACE() (does accept newlines).
* function.c (func_foreach): Strip leading/trailing space.
* variable.c (parse_variable_definition): Clean up.
* tests/scripts/functions/foreach: Test settings and errors.
* tests/scripts/functions/call: Rewrite to new-style.
* tests/scripts/misc/bs-nl: Add many more tests for newlines.
2016-03-23 01:25:51 -04:00
Paul Smith
2b9dd215d5 * function.c (func_file): Support reading from files.
* NEWS: Add information about reading files.
* make.texi (File Function): Describe reading files.
* tests/scripts/functions/file: Test new features for $(file ...)
2016-03-21 00:44:53 -04:00
Paul Smith
fc2ddebdae * doc/make.texi (Setting Variables): Fix typo (add comma). 2016-03-20 14:23:46 -04:00
Paul Smith
b4682cb479 * job.c (child_error): Combine file info with error message.
* tests/scripts/...: Update error message matches.
2016-03-20 14:23:22 -04:00
Paul Smith
09202bc880 * variable.c: Align type of variable_changenum. 2016-03-19 17:23:19 -04:00
Paul Smith
9ae02b7916 [SV 45728] Detect changes in .VARIABLES more accurately.
For performance, we only recompute .VARIABLES when (a) it's expanded
and (b) when its value will change from a previous expansion.  To
determine (b) we were checking the number of entries in the hash
table which used to work until we started undefining entries: now if
you undefine and redefine the same number of entries in between
expanding .VARIABLES, it doesn't detect any change.  Instead, keep
an increasing change number.
* variables.c: Add variable_changenum.
(define_variable_in_set, merge_variable_sets): Increment
variable_changenum if adding a new variable to the global set.
(undefine_variable_in_set): Increment variable_changenum if
undefining a variable from the global set.
(lookup_special_var): Test variable_changenum not the hash table.
* tests/scripts/variables/special: Test undefining variables.
2016-03-13 18:23:20 -04:00
Paul Smith
247b71e690 * main.c(main): Disable output sync without parallel builds. 2016-03-13 15:59:12 -04:00
Paul Smith
e33f3d72bf [SV 46581] Pre-define .LOADED to avoid warnings.
* main.c (main): Pre-define .LOADED as a default-level variable.
* load.c (load_file): Set the value rather than append it.  Avoid
adding an extra initial whitespace.
* tests/scripts/features/load: Run with --warn-undefined-variables.
2016-03-13 03:02:00 -04:00
Paul Smith
fd1dd7c398 [SV 44555] Use vfork() instead of fork() where available.
Testing has shown that vfork() is actually significantly
more efficient on systems where it's supported, even for
copy-on-write implementations.  If make is big enough,
duplicating the page tables is significant overhead.

* configure.ac: Check for fork/vfork.
* makeint.h: Include vfork.h and set up #define for it.
* os.h, posixos.c (get_bad_stdin): For children who can't use
the normal stdin file descriptor, get a broken one.
* job.c (start_job_command): Avoid so many ifdefs and simplify
the invocation of child_execute_job()
(child_execute_job): move the fork operation here so it can
return early for the parent process.  Switch to use vfork().
* function.c (func_shell_base): Use new child_execute_job() and
simplify ifdefs.
* job.h, main.c, remote-cstms.c, vmsjobs.c, w32os.c: Update
declarations and calls.
2016-03-13 01:12:07 -05:00
Paul Smith
14b2d7effb * job.c (exec_command): [SV 47365] Show error on exec failure. 2016-03-09 00:18:57 -05:00
Paul Smith
85c788572d [SV 46261] Use pselect() for jobserver where supported.
* Makefile.am, configure.ac: Check for pselect() and sys/select.h.
* main.c (main): Block SIGCHLD if we have pselect() support.
* posixos.c (jobserver_acquire): If we support pselect() then use
it to query the jobserver pipe, while also listening for SIGCHLD.
Also pselect() supports a timeout so avoid alarm() calls.
2016-03-08 23:40:46 -05:00
Paul Smith
8164c8ab3d Clean up some compiler warnings.
* commands.c, commands.h: Use unsigned char for flags.
* dir.c: Use time_t and size_t, and char for a boolean value.
* job.c: Use unsigned and char.
* read.c: Return a signed type since -1 is a valid return code.
2016-03-08 23:40:46 -05:00
Paul Smith
fb7a7adc8a Extract jobserver implementation into OS-specific files.
* os.h, posixos.c, w32/w32os.c: New files implementing jobserver.
* job.c, job.h, main.c, makeint.h: Move content to new files.
* w32/include/sub_proc.h, w32/subproc/sub_proc.c: Ditto.
* Makefile.am: Build and package OS-specific files.
* build_w32.bat, make_msvc_net2003.vcproj, README.W32.template:
Update for new files, and clean up the build.
* POTFILES.in, maintMakefile, NMakefile.template: Ditto.
* w32/subproc/build.bat: Delete as unused.
2016-03-08 23:40:46 -05:00
Paul Smith
4f8be4bb28 [SV 46261] Add more EINTRLOOP wrappers.
This cannot be a perfect solution because there are always other
possible places EINTR can happen, including external libraries
such as gettext, Guile etc.
2016-03-08 00:31:47 -05:00
Paul Smith
e2b39edc22 * strcache.c (add_hugestring): [SV 46832] Support huge strings.
The strcache was limited to strings of length 65535 or less,
because the length is kept in an unsigned short.  To support
huge strings add a new simple linked list, which we don't try
to hash.
2016-02-29 01:35:02 -05:00
Paul Smith
8530d77c68 * strcache.c (add_string): [SV 47071] Handle huge initial string.
If the very first string added to the string cache is more than
half the maximum size, we failed when moving the only strcache
buffer to the full list.
2016-02-29 01:35:02 -05:00
Paul Smith
89e18c12eb [SV 47151] Exit with 1 when checking recursive make -q
* job.h (struct child): New bit to mark recursive command lines.
* job.c (start_job_command): Set the recursive command line bit.
(reap_children): If the child is a recursive command and it exits
with 1 during question mode, don't print an error and exit with 1.
* tests/scripts/options/dash-q: Add a regression test.
2016-02-29 01:33:50 -05:00
Paul Smith
bccd01354b * main.c (define_makeflags): Add parens to avoid GCC warning. 2016-02-29 01:32:12 -05:00
Paul Smith
5f9d341160 * tests/scripts/features/archives: Handle deterministic archives.
Newer versions of binutils allow ar to be compiled to generate
"deterministic archives" by default: in this mode no timestamp
information is generated in the static archive, which utterly
breaks GNU make's archive updating capability.  Debian and Ubuntu
have turned this feature on by default in their distributions
which causes the regression tests to fail.

Update the regression tests to check for the availability of the
"U" option to ar which disables deterministic archives and allows
GNU make's archive support to work properly again.
2016-02-29 01:31:16 -05:00
Paul Smith
798ebd241b Update Copyright statements for the new year. 2016-02-28 12:55:20 -05:00
Paul Smith
4db6d0c694 * doc/make.texi: [SV 47163] Fix typo in 'ifdef' documentation. 2016-02-28 12:41:41 -05:00
Paul Smith
b754a35df7 * doc/make.texi: [SV 35455] Add more uses for Empty Recipes. 2016-02-28 12:35:15 -05:00
Gisle Vanem
168f12375d Fix diagnostics on MS-Windows when environment is too large
* w32/subproc/sub_proc.c (process_begin): Fix test of the error
	cause when the environment block is too large.

Copyright-paperwork-exempt: yes.
2015-11-07 11:27:03 +02:00
Eli Zaretskii
83443c706a Update README.W32.template
* README.W32.template: Update for latest developments.  Make it
clear we don't recommend using HAVE_CASE_INSENSITIVE_FS in
general.
2015-10-27 20:51:43 +02:00
Eli Zaretskii
4a5377aef7 [SV 46304] Don't invoke C++ compiler on C sources on MS-Windows
* default.c (default_variables) [HAVE_CASE_INSENSITIVE_FS]: Make
COMPILE.C and LINK.C be synonyms for COMPILE.c and LINK.c,
respectively.
2015-10-27 20:47:27 +02:00
Eli Zaretskii
48391c2817 [SV 45838] When invoking w32 programs, don't use free'd memory.
* w32/subproc/sub_proc.c (process_begin): Freeing argv[0] makes
the other argv[i] pointers invalid, so need to allocate a new
array and copy argv[i] for i != 0 first, replacing argv[0] with
the batch file name, before we can free argv[0].
2015-09-23 11:42:53 +03:00
Paul Smith
42745a900f * implicit.c (pattern_search): [SV 43677] Mark files secondary.
In order to fix SV 12267 we were marking the prerequisites of
implicit (pattern) targets that existed elsewhere in the makefile
as precious to keep them from being deleted as intermediate files.
However this also keeps them from being deleted on error.  Instead
mark them as secondary.
* tests/scripts/targets/DELETE_ON_ERROR: Test DELETE_ON_ERROR.
2015-07-13 00:51:35 -04:00
Paul Smith
43181f1f82 [SV 28092] Preserve the exit status of the $(shell...) function.
Add a new variable .SHELLSTATUS which holds the exit status of the
last-invoked shell function or != assignment.

* NEWS, doc/make.texi: Document the change.
* function.c (shell_completed, msdos_openpipe, func_shell_base): Add
shell_completed() to handle the completion of the shell, by setting
.SHELLSTATUS.  Call it where needed.
* job.c (child_handler): Call shell_completed().
* tests/scripts/functions/shell: Add tests for .SHELLSTATUS.
2015-07-12 21:03:24 -04:00
Paul Smith
c18b23f7b2 * tests/scripts/misc/fopen-fail: [SV 42390] Increase test timeout.
* Makefile.am (check-regression): Force ulimit -n for fopen-fail test.
2015-07-12 18:19:01 -04:00
Paul Smith
fe5585528f * job.c: [SV 43936] Check sigaction for error return. 2015-07-12 17:29:05 -04:00
Paul Smith
0205d3d08c [SV 45049] Check for '$' being the last character in a string.
* expand.c (variable_expand_string): Add a single '$' if '$' ends the
string.
* read.c (find_char_unquote, get_next_mword): Stop if '$' ends the
string.
* variable.c (parse_variable_definition): Ditto.
2015-07-12 13:25:16 -04:00
Paul Smith
9ef06be018 * read.c (unescape_char): [SV 45050] Handle final backslashes.
If the last thing in the string to be unescaped is a backslash,
stop without reading beyond the end of the string.
2015-07-12 12:39:59 -04:00
Paul Smith
ac9a39dad7 * strcache.c: [SV 45275] Handle very long strings.
Our previous behavior for handling too-long strings involved
increasing the size of the default string cache buffer, but the
implementation was incomplete.  Instead, create a one-off large
string cache entry and add it directly to the full cache list
without changing the default buffer size.
2015-07-12 00:14:19 -04:00
Duncan Moore
c6ac580785 * job.c [RISCOS]: Remove logic that is no longer required.
Signed-off-by: Paul Smith <psmith@gnu.org>
Copyright-paperwork-exempt: yes
2015-07-12 00:14:19 -04:00
Paul Smith
9efd477e98 * remake.c (update_file): [SV 44742] Keep double-colon rule status.
Fix suggested by Everett Boyer <EvBoyer@aol.com>
2015-07-12 00:14:14 -04:00
James Johnston
5036dd120a [SVN 45515] Check exit status of sub-make in subproc.bat
* subproc.bat: Exit when sub-make invocation fails.

Copyright-paperwork-exempt: yes
2015-07-10 09:56:27 +03:00
Eli Zaretskii
7e849f3b81 [SV 45515] Ignore Windows-specific build artifacts
* .gitignore: Ignore *.exe, *.dll.a, *.lib, *pdb, and a few more MSVC
specific artifacts.
Suggested by James Johnston <johnstonj.public@codenest.com>
2015-07-10 09:50:27 +03:00
Eli Zaretskii
a80a8b8a10 [SV 44348] Fix handling of shell widlcards on MS-Windows.
* job.c (construct_command_argv_internal): If shell wildcard
	characters are found inside a string quoted with "..", give up the
	fast route and go through the shell.  Fixes Savannah bug #44348.
2015-02-28 14:34:51 +02:00
John Malmberg
e4ac28e830 Fix bs-nl handling, exit and Environment for VMS.
This fix required a complete rewrite of the command parser vmsjobs.c
child_execute_job.  The old parser had too many incorrect assumptions
about DCL commands and could not be repaired to extended.

The parser now more closely parses VMS commands and handles quoted
commands and redirection.  Command File mode has been improved, but can
not fully support bs-nl syntax.

VMS Unix shell simulation has been improved.

* commands.c: vms_comma_separator is now a run-time setting.
* function.c: vms_comma_separator is now a run-time setting.
* function.c(func_basename_dir) now reports "[]" or "./" based on
  VMS crtl runtime setting.
* job.c(start_job_command): VMS Handle empty commands propery.
* main.c: Add VMS environment variables for run-time settings.
  * vms_legacy_behavior - Force older behavior.
  * vms_comma_separator - Commas or spaces for separators.
  * vms_unix_simulation - Enhanced Posix shell simulation features.
  * Detect if VMS CRTL is set to report Unix paths instead of VMS.
  * ':' and '>' are also MAP_DIRSEP on VMS.
* makeint.h: Add VMS run-time option variables.
* readme.vms: Update to current behavior.
* variable.c(define_variable_in_set): Fix VMS Environment variable
  lookup.
* variable.c(define_automatic_variables): Remove some VMS specific
  automatic variables and use the Unix ones instead.
* vms_export_symbol.c: Set max symbol size correctly.
* vmsjobs.c: child_execute_job() complete rewrite of VMS comand
  parsing.
* vmsjobs.c(build_vms_cmd): VMS commmand building with shell simulation.

Signed-off-by: Paul Smith <psmith@gnu.org>
2015-01-27 21:43:16 -05:00
Christian Boos
1fae20a2b7 Fix $(shell) on hosts with 64-bit pid_t.
* function.c: Use pid_t for shell_function_pid.
* job.c: Likewise.

Copyright-paperwork-exempt: yes
2014-12-27 10:55:01 +02:00
Paul Smith
292da6f686 * main.c (main): [SV 43434] Handle NULL returns from ttyname(). 2014-10-20 01:54:56 -04:00
Benedikt Morbach
3c487e7ed5 * tests/scripts/features/archives: [SV 43405] override AR variable.
Copyright-paperwork-exempt: yes
2014-10-20 01:45:09 -04:00
John Malmberg
c0380823a2 Fix VMS implicit rules and UNIX paths.
This fixes VMS implicit rules and UNIX style pathname handling.
It also fixes some of the VMS style pathname handling, more work
there will be needed later.
TODO: There are other case insensitive platforms besides VMS.
We need to find out why there is extra VMS code for this.  This
indicates either the extra VMS code is not needed, or the case
insensitive support may not be complete on the other case
insensitive platforms.

* default.c: Add missing definitions to default_suffix_rules[] and
default_variables[].
TODO: As it is important that VMS DCL mode definitions must always
be a superset of UNIX definitions, a better way of maintaining the
VMS DCL mode definitions should be devised.
* dir.c (downcase_inplace): Add a reentrant downcase() routine.
Add future support for VMS 8.2+ _USE_STD_STAT macro which will
disable a lot of VMS specific code from compiling.
(dir_file_exists_p): vmsify filename only if directory name has VMS
directory delimiters.
(file_exists_p): Handle both VMS and UNIX directories.
(file_impossible): Handle both VMS and Unix directories.  Track
whether a VMS format path is needed for the return value.
* file.c (lookup_file): Check if vmsify is needed; handle UNIX paths.
* implicit.c (pattern_search): Enable UNIX paths.
* read.c (parse_file_seq): Enable UNIX paths.
* remake.c (f_mtime): Fix gpath_search call for VMS paths.
* rule.c (count_implicit_rule): Enable UNIX paths, Fix VMS paths.
* vpath.c (selective_vpath_search): Enable UNIX paths.
2014-10-20 01:31:42 -04:00
John Malmberg
1faae1d4ed Update README.VMS and move news to the NEWS file
* NEWS: Merge in VMS history.
* README.VMS: Remove VMS history, document current behavior and
known issues.
2014-10-20 01:31:42 -04:00
John Malmberg
18eb093f56 [SV 41758]: Fix archive support for VMS.
Upated to match change to run_make_tests and some future fixes to
make on VMS.

* arscan.c: Use ANSI compatible pragmas instead of VAX C extensions.
* tests/scripts/features/archives: Fix tests to use VMS rules and
answers when running on VMS and using DCL as a shell.
* tests/scripts/features/vpath3: Fix epected answer on test when
run on VMS.
* tests/scripts/vms/library: (New) Test the VMS library rules that
are not tested by existing tests.
2014-10-20 01:31:42 -04:00
John Malmberg
894ee7f6c8 [SV 42447]: VMS simulate exporting symbols
This also includes fixing the most of the exit handling code for VMS.

Self tests:
 Previously about 94 Tests in 36 categories fail.
 Now about 45 tests in 22 categories fail.

Because some tests do not properly clean up, the number of tests that
fail can vary by one or two test cases between consecutive runs.

* Makefile.am: Add new VMS files.
* job.c: add prototype for vms_strsignal().
* job.c: (child_error): Remove VMS specific code as no longer needed.
* job.c: (reap_children): The VMS specific code was setting the
status to 0 instead of setting it to the proper exit status.
* job.h: Add vms_launch_status to struct child.
* main.c: (main): Use environment variables for options to use MCR
* instead of a foreign command, and to always use command files for
subprocesses.
For VMS use (set_program_name) routine which is common to ports of
other GNU packages to VMS to set the program name used internally.
Use (vms_putenv_symbol) to set up symbols to be visible in child
programs, including recursive make launched by execve()
Start of Bash shell detection code for VMS.
* makefile.com: Need nested_include=none for building on VMS search
lists.  Add vms_progname, vms_exit, and vms_export_symbol.
* makefile.vms: Need nested_include=none for building on VMS search
lists.  Add vms_progname, vms_exit, vms_export_symbol.
* makeint.h: Make sure non-standard "VMS" macro is defined.  Add
prototypes for new VMS routines.  Remove VMS-specific failure codes.
* vmsjobs.c: Add VMS POSIX exit code constants.
(_is_unixy_shell): Detect Bash shell.
(vms_strsignal): simulate strsignal() on VMS.
(vmsHandleChildTerm): fix to properly report failed LIB$SPAWN() exit
status codes.  Remove code that duplicated code in job.c.
(child_execute_job): Export environment symbols before spawning a
child and restore afterward unless option to use command files for
subprocesses is set.  Improve handling of UNIX null commands ":".
* vms_exit.c: Provides vms_exit() to detect if an exit code is UNIX
or VMS, and converts the UNIX code into a VMS exit code.
* vms_export_symbol.c: Routines to create DCL symbols that work like
shell aliases or exported shell symbols and clean them up on exit.
* vms_export_symbol_test.com: Unit test for vms_export_symbol.c
* vms_progname.c: New file: VMS specific replace for progname.c that
is used in some GNU projects.
2014-10-20 01:28:46 -04:00
John Malmberg
e75662bc6a Set up for running tests on VMS.
* run_make_tests.pl: set $port_type to be 'VMS-DCL' when the test are
run from the VMS DCL Interpreter.  When the tests are run from GNV
on VMS, the $port_type will be 'UNIX'.
* run_make_tests.com: VMS search list support.  This is needed for
using a search list such as prj_root = lcl_root:,vms_root:,src_root:
for building and testing.
2014-10-20 01:23:47 -04:00
Paul Smith
d1df4b21f3 * configure.ac, NEWS, README.git: Set up for the next release. 2014-10-09 02:06:53 -04:00
Paul Smith
a66bf2d736 GNU Make release 4.1. 2014-10-05 12:18:08 -04:00
Eli Zaretskii
31c2024b2e Fix Cygwin compilation error.
* job.c (construct_command_argv_internal) [HAVE_DOS_PATHS]: Fix
initializer for sh_chars_sh.
Reported by Denis Excoffier<cygwin@Denis-Excoffier.org>.
2014-10-02 18:11:43 +03:00
Gisle Vanem
7df0fe77d8 Fix last commit. 2014-10-01 20:43:12 +03:00
Gisle Vanem
9fc787c658 * makeint.h (ftruncate): Define also for __WATCOMC__.
Copyright-paperwork-exempt: yes.
2014-10-01 20:41:28 +03:00
Eli Zaretskii
1afb0ad372 Avoid compilation warnings.
* main.c (find_and_set_default_shell, main) [WINDOWS32]: Declare
variables 'const char *' to avoid compiler warnings.
* job.c (construct_command_argv_internal) [!NDEBUG]: Declare 'end'
and set it only if NDEBUG is not defined, to avoid compiler
warnings.
2014-10-01 18:34:29 +03:00
Eli Zaretskii
86a058029b Treat redirection of standard handles on Windows as it is done on Unix.
* job.c (start_job_command) [WINDOWS32]: Compute outfd and errfd
as on Posix platforms, and pass the results to process_easy.
* function.c (windows32_openpipe) [WINDOWS32]: Accept an
additional argument ERRFD and use it for redirecting the standard
error handle passed to the subprocess.
(func_shell_base) [WINDOWS32]: Pass the computed errfd to
windows32_openpipe.
2014-10-01 18:26:28 +03:00
Paul Smith
0a3a0756b9 Update Copyright statements for 2014. 2014-09-30 09:32:42 -04:00
Paul Smith
3712e8a819 * tests/scripts/features/load: Avoid unused variable warnings. 2014-09-30 09:32:41 -04:00
Paul Smith
9ed452b041 * loadapi.c (gmk_eval): Use C90 syntax. 2014-09-30 08:32:06 -04:00
Hartmut Becker
b11bef0bea * job.c: fix make action continuation lines.
* vmsjobs.c: fix writing DCL command files when trimming (white
  spaces and $ signs) especially after a split (command continuation).
2014-09-30 08:12:46 -04:00
Bernhard Reutner-Fischer
bd716a1ec1 * configure.ac: Fix spacing in helptext of customs
Copyright-paperwork-exempt: yes
2014-09-15 14:17:49 -04:00
Eli Zaretskii
b484efca56 Support MAKE_TERMOUT and MAKE_TERMERR on MS-Windows.
* w32/compat/posixfcn.c (isatty, ttyname): New functions.
* config.h.W32.template (HAVE_TTYNAME): Define.  Add a prototype
for ttyname.
2014-09-15 19:51:41 +03:00
Paul Smith
562344122f * loadapi.c (gmk_eval): [SV 43221] Preserve var buff content for eval. 2014-09-15 09:42:52 -04:00
Paul Smith
9a2451af0b * main.c, NEWS, doc/make.text: Rename MAKE_TTY* to MAKE_TERM* 2014-09-15 09:30:40 -04:00
Paul Smith
7f9ce6e97b * main.c (main): Set MAKE_TTYOUT and MAKE_TTYERR.
* configure.ac: Test for isatty() and ttyname()
* makeint.h: provide a substitute for ttyname() if it's not available.
* config.ami.template, config.h-vms.template, config.h.W32.template:
define/undefine HAVE_ISATTY/HAVE_TTYNAME macros.
* NEWS, doc/make.texi: Document these new variables.
2014-09-14 01:03:19 -04:00
Paul Smith
621e9edfe9 * tests/config-flags.pm.in, tests/scripts/features/archives: [SV 43046]
Use the "ar" program detected by configure when running the test suite.
2014-09-07 20:14:26 -04:00
Paul Smith
986632ec23 * doc/make.texi: Clarify implicit rule lookup of phony targets
Reported by Frank Heckenbach <f.heckenbach@fh-soft.de>
2014-09-07 20:02:31 -04:00
Hartmut Becker
95ffcda425 Fix and enhance VMS library support.
* ar.c: fix VMS library search for members, which do not have
suffixes, aka filename extensions.
* arscan.c: fix time conversion and library callback routines.
* default.c: more suffixes and automatically create the VMS library
if it doesn't exists.
2014-09-07 18:11:36 -04:00
Hartmut Becker
dcca1b5b0e Enhance VMS exporting make environment variables.
* config.h-vms.template: add feature macro USE_DCL_COM_FILE to always
write a DCL command file, enabled by default.
* vmsjobs.c: with USE_DCL_COM_FILE enabled write make variables as DCL
symbol assignments into the command file.  This enables printing
directory and make level info for recursive use of make. This also
enables forced DCL symbol substitution in the actions.
2014-09-07 18:10:11 -04:00
Hartmut Becker
9cad73ad82 Fix VMS automatic variable expansion
* function.c: add VMS code to func_notdir_suffix and func_basename_dir
to work on comma separated lists; this fixes the expansion of
$(^D), $(+D) and the F variants for VMS.
2014-09-07 18:03:45 -04:00
Hartmut Becker
8e7a28a6a4 * main.c [VMS]: Say that parallel jobs (-j) are not supported on VMS 2014-09-07 18:02:10 -04:00
Hartmut Becker
98de32a681 Enhance/fix VMS ONESHELL implementation and command execution
* job.c, vmsjobs.c: fix some double quote and new line handling;
implement ONESHELL with writing multiple lines into one DCL command
procedure; in ONESHELL allow VMS/make internal redirection only on the
first line; fix the created DCL command procedure, which didn't abort
on errors; return correct exit status from the DCL command procedure;
preserve current procedure verification; make the generated command
procedure more robust.
2014-09-07 18:01:35 -04:00
Hartmut Becker
5369be5079 Enhance/fix VMS setting of program name, MAKE/MAKE_COMMAND variables
* default.c, main.c, makeint.h, vmsfunctions.c: prefix argv[0] with
"mcr " for MAKE/MAKE_COMMAND and set the program name to the image
filename (without the .exe;version)
* vmsfunctions.c: remove obsolete code
* vmsify: use xmalloc
2014-09-07 17:48:14 -04:00
Hartmut Becker
8de07f3e4a Enhance/fix VMS exit code handling.
* commands.c, function.c, hash.c, job.c, main.c, output.c:
use MAKE exit codes.
* makeint.h: encode make exit codes so that they are VMS compatible.
* job.c: check child exit code for VMS style exit codes.
* vmsjobs.c: save and return VMS style exit code.
2014-09-07 17:41:59 -04:00
Hartmut Becker
f970315766 Enhance/fix VMS multi-line support.
* job.c: split the command line at a newline.
* default.c, vmsjobs.c: change ECHO variable to a pseudo builtin,
which ensures that the VMS/DCL ECHO ("write sys$output") is used
and is correctly quoted.
* vmsjobs.c: remove unused builtin 'rm'.
2014-09-07 17:40:28 -04:00
Hartmut Becker
579ee85941 * config_flags_pm.com, [RENAMED test_make.com] run_make_tests.com:
Moved into tests directory.
2014-09-07 17:30:37 -04:00
Hartmut Becker
7e51810bb5 Enhance/fix VMS build environment
* config.h-vms.template: make sure the CRTL version is known
* makefile.com: always compile/link the guile module, remove VAXCRTL
parameter, new LIST parameter
* makefile.vms: always compile/link the guile module, use more
complete dependencies
* prepare_vms.com: helper to create a VMS config file when building
from a snapshot of the repository
2014-09-07 17:13:56 -04:00
Paul Smith
bd30df4478 * configure.ac, maintMakefile, w32/Makefile.am: Fix autotools issues.
Reported by Paul Eggert <eggert@cs.ucla.edu>
2014-09-07 16:59:37 -04:00
Eli Zaretskii
1f2fd22fec Change the order of "makefile" and "Makefile" to match the manual. 2014-08-30 10:43:34 +03:00
Eli Zaretskii
ab1210b1fe Fix regression with "makefile" not being found on MS-Windows.
* read.c (read_all_makefiles) [WINDOWS32]: Recognize "makefile",
all-lowercase, as a makefile.  Reported by Michael Waeber
<waeber@gmail.com>.
2014-08-30 10:40:12 +03:00
Eli Zaretskii
241787d8e4 Fix compilation on MS-Windows.
* makeint.h [WINDOWS32]: Don't declare 'program' as 'const char *',
since it is modified in 'main'.
2014-07-16 18:23:04 +03:00
Eli Zaretskii
faeeb27166 [SV 42695] Fix compilation error on MS-Windows.
* main.c [WINDOWS32]: Don't declare 'program' as 'const char *',
since it is modified in 'main'.
2014-07-12 13:01:18 +03:00
Jonny Grant
cab353d1dd Fix defalt_makefiles[] for MS-Windows.
* read.c (read_all_makefiles) [WINDOWS32]: Remove the redundant
"makefile" and add "makefile.mak".

Copyright-paperwork-exempt: yes
2014-07-12 12:53:59 +03:00
Fredrik Fornwall
8b01e6bebf * arscan.c [ANDROID]: Android has no ar.h but supports archives.
Copyright-paperwork-exempt: yes
2014-07-07 03:56:17 -04:00
Paul Smith
55c00544cc * read.c (eval): [SV 41677] Correct test for TAB vs. 8 spaces. 2014-07-07 03:43:57 -04:00
Piotr Jaroszynski
8d577c2ff4 * output.c (pump_from_tmp): [SV 42378] Flush the output file regularly.
Copyright-paperwork-exempt: yes
2014-07-07 03:10:17 -04:00
John Malmberg
e44d6a12bb Update the regression test harness to support VMS.
* config_flags_pm.com, test_make.com: set up and run the regression
test environment on VMS.
* tests/run_make_tests.pl [VMS]: Use an alternate rmdir()
implementation on VMS.
(run_make_with_options) [VMS]: Provide VMS-specific quoting and shell
invocations.
(set_more_defaults) [VMS]: Set default values when running on VMS.
* tests/test_driver.pl (vms_get_process_logicals) [VMS]: Retrieve the
proper values from %ENV on VMS.
(resetENV) [VMS]: Use it.
(toplevel) [VMS]: Fix a bug with opendir() on some logical_devices.
(compare_output) [VMS]: Convert VMS test output to a "standard" format.
(_run_command) [VMS]: Handle signals and exit codes the VMS way.
(remove_directory_tree_inner) [VMS]: Unlink all versions of the file.
2014-07-07 02:47:30 -04:00
Paul Smith
423c3955d9 * various: Assume ISO C89-compliant free() implementation. 2014-07-07 01:59:03 -04:00
Paul Smith
ac67346d0f * maintMakefile, various: Improve constification of the codebase. 2014-07-07 01:59:03 -04:00
Paul Smith
e364498113 [SV 41983] Support omitting the text argument to $(file ...)
Reported by Tim Murphy <tnmurphy@gmail.com>
* function.c (func_file): Only write TEXT if it is not NULL.
* NEWS, doc/make.texi: Document the new feature
* tests/scripts/functions/file: Verify that the no-text version of
  $(file ...) works and doesn't add a newline.
2014-07-07 01:59:03 -04:00
Jacques Germishuys
85047eb904 NMakefile.template ($(OUTDIR)/posixfcn.obj): Fix a typo.
Copyright-paperwork-exempt: yes.
2014-05-13 20:30:47 +03:00
Paul Smith
0faa98a0bb [SV 42249] Propagate correct rule status results.
* remake.c (update_file, update_file_1, check_dep): Return an enum
  update_status value instead of an int, and keep the highest value we
  find as we walk the graph so that the ultimate status is correct.
* tests/scripts/options/dash-q: Add a test for updating prerequisites.
2014-05-01 09:51:04 -04:00
Paul Smith
8411528fdd * Rename MAP_PATHSEP to MAP_DIRSEP. 2014-02-08 16:01:10 -05:00
Paul Smith
d2a3e9ca9c * configure.ac: Fixup for newer autoconf/automake 2014-02-08 16:01:10 -05:00
Ray Donnelly
e1863c05d8 * output.c: Ensure space for final nul byte in fmtbuf.
Copyright-paperwork-exempt: yes
2014-02-08 16:01:10 -05:00
Gisle Vanem
b981bfd197 Improve error reporting in the Windows port when env size is too large.
w32/subproc/misc.c (arr2envblk): Compute and return the size of
the environment passed to child process.

w32/subproc/sub_proc.c (process_begin): If the call to
CreateProcess failed with EINVAL, and the required environment
size was larger than 32KB, assume it's a Windows XP limitation,
and display an error message to that effect.

w32/subproc/proc.h (arr2envblk): Update prototype.

Copyright-paperwork-exempt: yes
2014-02-07 11:15:56 +02:00
Paul Smith
88713683fe * job.c (set_child_handler_action_flags): [SV 41341]
Ensure signal handler is in place before alarm(1).
2014-02-01 23:12:04 -05:00
Alan Hourihane
a7cac0f0e3 * configure.ac: [SV 40790] Fix load autoconf variables.
Copyright-paperwork-exempt: yes
2014-01-20 00:17:44 -05:00
Pavel Fedin
165ccf3137 Allow the EMX build to use output_sync.
job.c (start_job_command): Move the child output diversion out
of non-EMX branch.
[__EMX__]: Don't use fixed FD_STDOUT and FD_STDERR in the call to
child_execute_job.

Copyright-paperwork-exempt: yes
2014-01-17 09:51:28 +02:00
Paul Smith
24620378ba * commands.c: [SV 40789] Remove unneeded header dlfcn.h 2014-01-12 10:54:59 -05:00
Paul Smith
9c8b68a905 * main.c (die): Close output_context AND make_sync.
die() can be invoked inside a separate output_context, if the
$(error ...) function is expanded as part of a recipe.
2014-01-12 10:54:29 -05:00
Pavel Fedin
432cb6575d Fix .LIBPATTERNS for MS-Windows builds.
default.c (.LIBPATTERNS) [__CYGWIN__ || WINDOWS32]: Provide
library patterns for MS-Windows.

Copyright-paperwork-exempt: yes
2014-01-11 22:28:48 +02:00
Paul Smith
a4937bc897 * w32/*: Remove TABs from the source code.
I know whitespace commits are annoying, but having these TABs is
causing me to miss things when I search through the code.  This
doesn't try to change the w32 code to meet GNU coding standards.
2013-11-27 19:43:33 -05:00
Paul Smith
889303cdfe * main.c (decode_env_switches): Ensure we have enough space.
Reported (with patch) by Gerte Hoogewerf <g.hoogewerf@gmail.com>
2013-11-27 19:06:45 -05:00
Stephan T. Lavavej
99385ee6f7 Solve some Windows build issues.
* main.c (main): Use ONS(), not OSN().
(prepare_mutex_handle_string) [WINDOWS32]: Use %Ix formatting to
support both 32bit and 64bit systems.
* job.c (free_child, new_job): Use ONS(), not OSN().
* w32/subproc/w32err.c (map_windws32_error_to_string): Use O() when
calling fatal().

Copyright-paperwork-exempt: yes
2013-11-27 10:57:37 -05:00
Paul Smith
f5f5adb62c * features/loadapi (test_expand): Allocate memory for the nul byte. 2013-11-24 04:08:30 -05:00
Paul Smith
865d90bb1e * load.c (load_file): Reset the name length minus the symbol. 2013-11-24 04:03:19 -05:00
Paul Smith
30b25acc4e * read.c (unescape_char): Use memmove() for overlapping memory. 2013-11-24 03:45:38 -05:00
Paul Smith
f8905059c3 Fix memory leak during environment option decoding.
* main.c (decode_switches): Always make a copy of option arguments.
(decode_env_switches): Use a stack buffer to convert environment
switches for parsing.
2013-11-24 03:45:02 -05:00
Paul Smith
12a3104c3d [SV 40226] Add a new type of switch: single-string options
* main.c (struct command_switch): Change the "string" types to "strlist"
and make "string" be a single-valued string instead.
(output_sync_option, jobserver_fds, sync_mutex): Change to string type.
(decode_output_sync_flags): Handle single strings instead of lists.
(prepare_mutex_handle_string): Ditto.
(main): Ditto.
(clean_jobserver): Ditto.
(init_switches): Handle the new type.
(decode_switches): Ditto.
(define_makeflags): Ditto.
2013-11-24 03:21:40 -05:00
Daniel Richard G
7b485daffb * load.c: [SV 40515] Define RTLD_GLOBAL if not set.
Copyright-paperwork-exempt: yes
2013-11-23 22:39:39 -05:00
Paul Smith
757849cd93 [SV 40361] Don't use vsnprintf(), which is an ISO C99 function.
* output.c (error, fatal, message): Take an extra argument specifying
how many bytes are used by the formatted arguments.
(get_buffer): New function that allocates the requested buffer size.
Remove msc_vsnprintf(), vfmtconcat(), and fmtconcat() as unneeded.
* makeint.h: Declare various helper macros for generating output.
* *.c: Change all error(), fatal(), message() calls to use the macros,
or pass the extra length argument directly.
2013-11-23 22:23:52 -05:00
Paul Smith
9d58570c77 * makeint.h (STOP_SET): [SV 40371] Cast to unsigned char.
* tests/scripts/misc/utf8: Test variable names with characters >127.
Fix suggested by Robert Bogomip <bob.bogo@milohedge.com>
2013-10-27 17:43:21 -04:00
Gerte Hoogewerf
d49ab08ae0 Fix MS Visual Studio NET2003 build.
* make_msvc_net2003.vcproj: Do not exclude guile.c from compilation.
Copyright-paperwork-exempt: Yes.
2013-10-24 21:20:36 +03:00
Christian Boos
10a4b120bd Fix SV bug #40227 with respect to stack size set for the MSVC build.
* NMakefile.template (/STACK): Increase to 0x400000, mainly for
the 64-bit builds.  Fixes SV bug #40227.
Copyright-paperwork-exempt: Yes.
(guile): Uncomment.
2013-10-23 19:56:18 +03:00
Eli Zaretskii
309768aff1 Fix the MS-Windows build: now guile.c must always be compiled in.
* build_w32.bat: Always compile guile.c and link against guile.o.
  Reported by Alexey Pavlov <alexpux@gmail.com>.

* makeint.h (guile_gmake_setup): Define prototype unconditionally,
to avoid compiler warnings.
2013-10-23 19:28:38 +03:00
Eli Zaretskii
9c28d5125d Fix Savannah bug #31150 with failures due to setting window title.
* sub_proc.c (process_begin): Don't set startInfo.lpTitle, it
reportedly causes SV bug #31150, and according to MSDN it's a
no-no.
2013-10-22 19:04:34 +03:00
Eli Zaretskii
a7794f483b Fix Savannah bug 40241 with Unixy file names as commands to MSYS shell.
* sub_proc.c: Include filedef.h and variable.h.
(process_begin): If exec_path was not found, but its first
character is '/', assume there's some shell magic, and invoke the
command through '$(SHELL) -c "COMMAND"'.  Fixes SV bug#40241.
(make_command_line): Kludgey feature: if full_exec_path is "-c",
assume that argv[0] is not to be skipped, as it holds the command
string to be passed to the shell.
2013-10-22 18:55:38 +03:00
Paul Smith
5d653b535a * glob.c (glob) [SV 18123]: Cherry-pick glibc fix
Apply commit a471e96a5352a5f0bde6d32dd36d33524811a2b1 from
git://sourceware.org/git/glibc.git to fix
https://sourceware.org/bugzilla/show_bug.cgi?id=10278
2013-10-20 13:18:50 -04:00
Paul Smith
53b4a9e668 * read.c (record_files): [SV 33034] Change fatal() to error()
Allows deprecated syntax.  However we don't guarantee this syntax
will continue to be legal in the future.
Change suggested by David Boyce <david.s.boyce@gmail.com>
2013-10-20 13:08:27 -04:00
Paul Smith
d4723d643d * README.git: Add some missing release steps. 2013-10-20 13:08:27 -04:00
Paul Smith
107ab16bf6 [SV 40240] Use configure info to build load test shared libs
* tests/config-flags.pm.in: A new file containing variable assignments
for the test suite; these variables are set by configure to contain
the values detected there for compilers, flags, etc.
* tests/run_make_tests.pl: Require the config-flags.pm file
* tests/scripts/features/load, tests/scripts/features/loadapi: Use the
configure-provided values when building the shared test library.
* configure.ac: Replace tests/config-flags.pm.in
* Makefile.am: Make sure tests/config-flags.pm is up to date
2013-10-19 15:39:15 -04:00
Paul Smith
07f2666b91 * maintMakefile (checkcfg.%): Add testing of build.sh 2013-10-19 12:25:09 -04:00
Paul Smith
f4b746b8c2 [SV 40254] Modify build.sh to work properly with Guile support.
* guile.c (guile_gmake_setup) [HAVE_GUILE]: Define a stub function
when Guile support is not enabled.
* main.c (main) [HAVE_GUILE]: Always invoke guile_gmake_setup().
* Makefile.am: Make guile.c standard, not optional.
* build.template: Add the Guile compiler and linker flags.
2013-10-19 12:24:14 -04:00
Paul Smith
d7f25cfda5 * maintMakefile: Accept variable overrides from the environment. 2013-10-19 12:09:13 -04:00
Paul Smith
b9a01a8b3b * NEWS: Fix version so we can build a distfile. 2013-10-19 12:08:04 -04:00
Paul Smith
d654bff457 * read.c (eval): Avoid GCC warning to add braces. 2013-10-19 12:07:31 -04:00
Paul Smith
74ed682c54 * GNUMAKEFLAGS: Remove -O so it passes in NO_OUTPUT_SYNC mode. 2013-10-19 12:05:58 -04:00
Christian Boos
e498e464dc Fix initialization of stringlist variables for jobserver_fds and sync_mutex.
(tiny change)

 main.c (prepare_mutex_handle_string, main): Initialize
 stringlist variables with at least 2 members, as one member is not
 currently supported.
2013-10-18 13:23:43 +03:00
Eli Zaretskii
d1d737d0fa Fix MinGW64 problem with non-compliant vsnprintf.
makeint.h (__USE_MINGW_ANSI_STDIO) [__MINGW64_VERSION_MAJOR]:
 Define for MinGW64, to force it to use an ANSI-compliant
 implementation of vsnprintf.  Reported by Christian Boos
 <cboos@edgewall.org>.
2013-10-18 13:12:22 +03:00
Eli Zaretskii
87e5b64f41 Fix the MSVC build on MS-Windows.
output.c (vsnprintf) [_MSC_VER]: Define, instead of defining
 snprintf, which isn't used.  Reported by Christian Boos
 <cboos@edgewall.org>.
 NMakefile.template (OBJS): Add load.obj and posixfcn.obj.
 ($(OUTDIR)/pathstuff.obj): New dependency.
 Suggested by Christian Boos <cboos@edgewall.org>.
2013-10-18 13:08:12 +03:00
Paul Smith
70df3c35bf [SV 40139] Modify "missing separator" for better translation 2013-10-13 16:48:23 -04:00
Paul Smith
01a745025d Add support for updating the GNU make web pages.
Add makefile rules for updating the http://www.gnu.org/software/make
web pages, including the online GNU make manual.
2013-10-13 16:48:22 -04:00
Paul Smith
4792e154b6 Convert to auto-generated ChangeLog files.
Rename existing ChangeLog files so they won't be distributed.
Add targets to maintMakefile to generate ChangeLog from the Git
repository.  This will require a version of gnulib be available.
Because ChangeLog is auto-generated, we have to switch our
automake mode to "foreign" or it will complain and fail.
2013-10-13 16:48:22 -04:00
Paul Smith
188b2a0f23 Set up for the next release. 2013-10-13 16:48:22 -04:00
Paul Smith
52191d9d61 GNU Make release 4.0. 2013-10-09 02:09:21 -04:00
Paul Smith
dc9ae5e017 [SV 39709] Fix some typos. 2013-10-09 01:53:55 -04:00
Eli Zaretskii
723e047428 Untabify posixfcn.c. 2013-10-07 19:16:11 +03:00
Eli Zaretskii
b69b04dc8c Foix compilation with MSVC.
w32/compat/posixfcn.c (tmpfile): Move declaration of h before
 the first executable statement.  Reported by Gisle Vanem <gvanem@yahoo.no>.
2013-10-07 19:14:01 +03:00
Paul Smith
b539908f73 Clean up some tests for use on Windows. 2013-10-05 19:30:48 -04:00
Paul Smith
2fb91e19a0 Sanitize the registered function interface.
Expand the characters which are legal in a function name, and check
the name for validity.  Create a type for the function pointer.
Convert the last argument from a boolean to flags, to allow for expansion.
2013-10-05 16:10:30 -04:00
Eli Zaretskii
f96c114e22 function.c (abspath): Reset root_len to one for Cygwin only when
HAVE_DOS_PATHS is defined.  Suggested by Christopher Faylor.
2013-10-03 19:02:14 +03:00
Eli Zaretskii
98197303b1 Fix tmpfile on MS-Windows.
w32/compat/posixfcn.c (tmpfile): New function, a replacement for
 the Windows libc version.
2013-10-02 19:48:21 +03:00
Eli Zaretskii
f8786092ad Fix $abspath on Cygwin when HAVE_DOS_PATHS is in effect.
function.c (IS_ABSOLUTE) [__CYGWIN__]: Special definition for Cygwin.
 (abspath) [__CYGWIN__]: Reset root_len to 1 if the absolute file name
 has the Posix /foo/bar form.
 [HAVE_DOS_PATHS]: Use root_len instead of hard-coded 2.
2013-10-02 19:39:53 +03:00
Paul Smith
1d4c15b4e1 Release GNU Make version 3.99.93. 2013-10-01 00:33:01 -04:00
Paul Smith
b1c7f0df4e Fix portability issues for Guile 1.8. 2013-09-30 10:56:20 -04:00
Paul Smith
8e12202870 Final fixes for obscure output-sync errors. 2013-09-30 00:12:36 -04:00
Paul Smith
1f4ca0539b Fixes for building with MSVC. 2013-09-30 00:12:36 -04:00
Paul Smith
d0944ee2e8 Solaris /bin/sh can't handle multiple options ("-e -c"). 2013-09-30 00:12:18 -04:00
Paul Smith
38066b6f19 Fix build failures on EMX for output-sync support. 2013-09-29 13:17:56 -04:00
Paul Smith
3bf3fde984 Portability for Guile 1.8. Force UTF-8 encoding. 2013-09-29 13:16:21 -04:00
Paul Smith
543521cd47 Reset GNUMAKEFLAGS after parsing.
If we don't do this we'll continually add flags on recursion.  This
is mainly for users to set in their environment before invoking make.
2013-09-29 13:15:00 -04:00
Paul Smith
e8122ecb5d Rename dash-w to print-directory.
Avoid conflicts with dash-W on case-insensitive filesystems.
2013-09-23 11:24:51 -04:00
Eli Zaretskii
55a0c0e414 Fix broken w32 build due to OUTPUT_SYNC -> NO_OUTPUT_SYNC inversion.
w32/compat/posixfcn.c: Fix the forgotten OUTPUT_SYNC conditional.
 job.h: Ditto, but in a comment.
2013-09-23 10:56:51 +03:00
Paul Smith
8a3436c65d Release GNU Make version 3.99.92. 2013-09-23 00:55:55 -04:00
Paul Smith
fd30db1290 [SV 31155] Parse order-only tokens in second expansion results. 2013-09-22 17:10:35 -04:00
Paul Smith
c3524b83b9 Use explicit cast between void* and pointer-to-function. 2013-09-22 17:10:35 -04:00
Paul Smith
0296e40fc7 Allow loaded objects to opt out of the "auto-rebuild" feature. 2013-09-22 17:10:35 -04:00
Paul Smith
f69922b335 Defer Guile initialization until the first $(guile...) call. 2013-09-22 17:10:35 -04:00
Paul Smith
65931ce7a9 Regression test portability to Solaris. 2013-09-22 17:10:34 -04:00
Paul Smith
1a991ada47 Add VMS port updates from Hartmut Becker. 2013-09-22 17:10:34 -04:00
Paul Smith
7e77685bc3 Portability enhancements for Mac OSX.
Don't dup stdout into stderr in the test suite.
Don't rely on $port_type eq "UNIX" to mean case-preserving.
Check against the real output of ar when creating archives.
2013-09-22 17:09:46 -04:00
Paul Smith
300d1296fb Create a target that tests alternative configurations. 2013-09-21 18:10:08 -04:00
Paul Smith
822f8dae41 Remove obsolete tests. 2013-09-21 17:41:11 -04:00
Paul Smith
d2d44f76c4 Invert the #define for output-sync: turn it off with NO_OUTPUT_SYNC 2013-09-21 17:37:59 -04:00
Paul Smith
6c3e88e60f Ensure that output generated while reading makefiles is synced. 2013-09-21 17:24:59 -04:00
Paul Smith
9cd01958da Ensure that stderr from shell functions in recipes is synced. 2013-09-21 17:08:42 -04:00
Paul Smith
4120f91846 Don't write "Entering" every time we re-exec for remake makefiles. 2013-09-21 14:24:44 -04:00
Paul Smith
30a5ee0d85 [SV 40043] Set the current directory before printing errors. 2013-09-18 19:29:28 -04:00
Eli Zaretskii
8a6205b43f Fix a typo in a comment. 2013-09-16 11:42:20 +03:00
Eli Zaretskii
bc120f27bd Avoid compiler warnings in output.c on MS-Windows.
output.c [WINDOWS32]: Include windows.h and sub_proc.h, to avoid
 compiler warnings for CLOSE_ON_EXEC.
2013-09-16 11:30:01 +03:00
174 changed files with 12139 additions and 5920 deletions

16
.gitignore vendored
View File

@@ -13,6 +13,7 @@ Makefile
Makefile.in
aclocal.m4
autom4te.cache
config.cache
config.h
config.h.in
config.log
@@ -26,9 +27,23 @@ gmk-default.h
loadavg
make
*.o
*.exe
*.dll.a
*.obj
*.lib
*.pdb
*.sbr
# Windows build artifacts
WinDebug/
WinRel/
GccDebug/
GccRel/
# Distribution artifacts
.dep_segment
.check-git-HEAD
ChangeLog
Makefile.DOS
NMakefile
README
@@ -44,3 +59,4 @@ config.h.W32
configh.dos
make-[0-9]*/
make-[0-9]*.tar.*
checkcfg.*.log

View File

@@ -72,7 +72,7 @@ With suggestions/comments/bug reports from a cast of ... well ...
hundreds, anyway :)
-------------------------------------------------------------------------------
Copyright (C) 1997-2013 Free Software Foundation, Inc.
Copyright (C) 1997-2016 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

View File

@@ -1703,7 +1703,7 @@ Thu Sep 14 18:29:38 1989 Roland McGrath (mcgrath at paris.Berkeley.EDU)
existing variable's origin, is `o_env', make it `o_env_override'.
* load.c: Use the symbol KERNEL_FILE_NAME instead of KERNEL_FILE.
* compatMakefile: Changed the comment for `LOAD_AVG' accordinly.
* compatMakefile: Changed the comment for `LOAD_AVG' accordingly.
Thu Sep 7 16:46:26 1989 Roland McGrath (mcgrath at paris.Berkeley.EDU)
@@ -3218,7 +3218,7 @@ Sun Feb 5 19:52:38 1989 Roland McGrath (mcgrath at paris.Berkeley.EDU)
* variable.c (expand_function: `shell'): Use
`shell_function_completed'. Block children before forking and
unblock after `shell_function_pid' is set properly and
`shell_functon_completed' is reset to 0.
`shell_function_completed' is reset to 0.
* commands.c (child_handler): When the child of the `shell' function
completes, set `shell_function_completed' to 1 if it actually ran,
@@ -4465,7 +4465,7 @@ Fri Sep 16 13:59:59 1988 Roland McGrath (mcgrath at tully.Berkeley.EDU)
`maxsuffix', and must be called before count_implicit_rule_limits.
* rule.c (pattern_search): If an existent (non-intermediate)
dependendency was found via a terminal rule, set its
dependency was found via a terminal rule, set its
`tried_implicit' flag, so it will never have implicit rule search done.
* glob.c: Bug fix to avoid alloca(0).
@@ -4826,7 +4826,7 @@ Sat Jul 30 15:47:23 1988 Roland McGrath (mcgrath at tully.Berkeley.EDU)
new entry as the old entry's prev pointer.
* dir.c: Re-indented the `struct dir' definition to be right.
(dir_load): Cleaned up slighty.
(dir_load): Cleaned up slightly.
(file_exists_p): Removed comment saying we could use `access', since
that is a bad idea (except for setuid programs). Cleaned up slightly.

View File

@@ -1,3 +1,213 @@
2013-10-09 Paul Smith <psmith@gnu.org>
Version 4.0 released.
* configure.ac: Updated for the release.
* NEWS: Updated for the release.
* maintMakefile (tag-release): New target to add a Git tag.
* read.c (eval): Typo fix.
* ChangeLog.1: Typo fixes.
* w32/subproc/sub_proc.c (process_cleanup): Typo fix.
2013-10-07 Eli Zaretskii <eliz@gnu.org>
* w32/compat/posixfcn.c (tmpfile): Move declaration of h before
the first executable statement. Reported by Gisle Vanem
<gvanem@yahoo.no>.
2013-10-05 Paul Smith <psmith@gnu.org>
* makeint.h (MAP_USERFUNC): A new map type for function names.
* main.c (initialize_stopchar_map): Set up the function name map.
* gnumake.h (gmk_func_ptr): Define a type for function pointers.
(gmk_add_function): Convert the last argument to FLAGS.
(GMK_FUNC_*): Define flags for the function. Change the default
behavior to "expand" since that's the most common one.
* function.c (function_table_entry): Use new function pointer type.
(lookup_function): Accept any valid function name character based
on the MAP_USERFUNC values.
(define_new_function): Use the new calling signature. Verify that
registered functions have valid names.
* guile.c (guile_gmake_setup): Use new calling signatures.
* loadapi.c (gmk_add_function): Ditto.
* variable.h (define_new_function): Ditto.
* doc/make.texi (Loaded Object API): Make the registered function
API documentation more clear.
2013-10-03 Eli Zaretskii <eliz@gnu.org>
* function.c (abspath): Reset root_len to one for Cygwin only when
HAVE_DOS_PATHS is defined. Suggested by Christopher Faylor.
2013-10-02 Eli Zaretskii <eliz@gnu.org>
* w32/compat/posixfcn.c (tmpfile): New function, a replacement for
the Windows libc version.
Fix $abspath on Cygwin when HAVE_DOS_PATHS is in effect.
* function.c (IS_ABSOLUTE) [__CYGWIN__]: Special definition for
Cygwin.
(abspath) [__CYGWIN__]: Reset root_len to 1 if the absolute file
name has the Posix /foo/bar form.
[HAVE_DOS_PATHS]: Use root_len instead of hard-coded 2.
2013-10-01 Paul Smith <psmith@gnu.org>
* configure.ac: Update version to 3.99.93.
* NEWS: Ditto.
2013-09-30 Paul Smith <psmith@gnu.org>
* guile.c: Portability fixes for Guile 1.8.
2013-09-29 Paul Smith <psmith@gnu.org>
* output.c (output_dump): Always write Enter/Leave messages to stdio.
(log_working_directory): This now always writes to stdio, so we
don't need the struct output parameter anymore.
(output_start): Show the working directory when output_sync is not
set or is recursive.
* main.c (main): Ensure the special "already shown Enter message"
token is removed from MAKE_RESTARTS before the user can see it.
* function.c (func_shell_base): If the output_context stderr
exists but is invalid, write to the real stderr.
Fixes suggested by Frank Heckenbach <f.heckenbach@fh-soft.de>.
* output.c: Guard unistd.h inclusion, add io.h.
* gnumake.h: Move GMK_EXPORT before the declarations.
* make_msvc_net2003.vcproj: Add missing files.
Changes for MSVC suggested by Gerte Hoogewerf <g.hoogewerf@gmail.com>
* function.c (func_shell_base) [EMX]: Fix EMX support for output-sync.
* job.c (child_execute_job) [EMX]: Ditto.
* job.h (child_execute_job) [EMX]: Ditto.
* w32/compat/posixfcn.c: Invert the test for NO_OUTPUT_SYNC.
* guile.c (GSUBR_TYPE): Pre-2.0 Guile doesn't provide a typedef
for gsubr pointers. Create one.
(guile_define_module): Use it.
(internal_guile_eval): Force UTF-8 encoding for Guile strings.
* main.c (main): Clear GNUMAKEFLAGS after parsing, to avoid
proliferation of options.
* NEWS: Document it.
* doc/make.texi (Options/Recursion): Ditto.
2013-09-23 Eli Zaretskii <eliz@gnu.org>
* w32/compat/posixfcn.c: Fix the forgotten OUTPUT_SYNC conditional.
* job.h: Ditto, but in a comment.
2013-09-22 Paul Smith <psmith@gnu.org>
* configure.ac: Update version to 3.99.92.
* NEWS: Ditto.
* implicit.c (pattern_search): After second expansion be sure to
handle order-only markers inside the expansion properly.
Fixes Savannah bug #31155.
* guile.c (guile_define_module): Technically a void* cannot
contain a pointer-to-function and some compilers warn about this.
Cast the function pointers.
* load.c (load_object): Ditto.
* read.c (eval): If load_file() returns -1, don't add this to the
"to be rebuilt" list.
* doc/make.texi (load Directive): Document it.
* guile.c (guile_gmake_setup): Don't initialize Guile so early.
(func_guile): Lazily initialize Guile the first time the $(guile ..)
function is invoked. Guile can steal file descriptors which
confuses our jobserver FD checking, so we don't want to initialize
it before we have to.
VMS port updates by Hartmut Becker <becker.ismaning@freenet.de>
* makefile.com: Add output to the filelist.
* output.c (va_copy): Add an implementation of this macro for VMS.
* commands.c: Ensure filedef.h is #included before dep.h.
* dir.c: Ditto.
* file.c: Ditto.
* guile.c: Ditto.
* main.c: Ditto.
* misc.c: Ditto.
* read.c: Ditto.
* rule.c: Ditto.
* variable.c: Ditto.
* readme.vms: Renamed to README.VMS and updates for this release.
* Makefile.am: Ditto.
* NEWS: Ditto.
* README.template: Ditto.
* Makefile.DOS.template: Ditto.
2013-09-21 Paul Smith <psmith@gnu.org>
* maintMakefile (check-alt-config): Create a target to test
alternative configurations. Each one will build make with a
different configuration then run the test suite.
Invert the output-sync #define to NO_OUTPUT_SYNC
* configure.ac: Don't set OUTPUT_SYNC.
* makeint.h: Ditto.
* main.c: Use NO_OUTPUT_SYNC instead of OUTPUT_SYNC.
* output.c: Ditto.
* output.h: Ditto.
* job.h: Ditto.
* job.c: Ditto.
* config.ami.template: Set NO_OUTPUT_SYNC.
* config.h-vms.template: Ditto.
* config.h.W32.template: Ditto.
* configh.dos.template: Ditto.
Output generated while reading makefiles should be synced.
* main.c (make_sync): Define a context for syncing while reading
makefiles and other top-level operations.
(main): If we request syncing, enable it while we are parsing
options, reading makefiles, etc. to capture that output. Just
before we start to run rules, dump the output if any.
(die): Dump any output we've been syncing before we die
* output.h (OUTPUT_SET): Disable output_context if not syncout.
Stderr generated from shell functions in recipes should be synced.
* job.h (FD_STDIN, FD_STDOUT, FD_STDERR): Create new macros to
avoid magic numbers.
(child_execute_job): Take a FD for stderr.
* job.c (child_execute_job): Handle STDERR FD's in addition to
stdin and stdout.
(start_job_command): Call child_execute_job() with the new STDERR
parameter. Instead of performing the dup() here, send it to
child_execute_job() where it's already being done.
* function.c (func_shell_base): Pass the OUTPUT_CONTEXT stderr to
child_execute_job() if it's set, otherwise FD_STDERR.
* main.c (main): Pass FD_STDERR to child_execute_job().
2013-09-19 Paul Smith <psmith@gnu.org>
* main.c (main): Set MAKE_RESTARTS to negative before re-exec if
we've already generated an "Entering" message. If we are started
and notice that MAKE_RESTARTS is negative, assume we already wrote
"Entering" and don't write it again.
2013-09-18 Paul Smith <psmith@gnu.org>
* main.c (main): Set starting_directory before we write any
errors. Fixes Savannah bug #40043.
2013-09-16 Eli Zaretskii <eliz@gnu.org>
* output.c [WINDOWS32]: Include windows.h and sub_proc.h, to avoid
compiler warnings for CLOSE_ON_EXEC.
2013-09-16 Paul Smith <psmith@gnu.org>
* configure.ac: Update version to 3.99.91.

View File

@@ -1,7 +1,7 @@
# -*-Makefile-*- template for DJGPP
# Makefile.in generated automatically by automake 1.2 from Makefile.am
#
# Copyright (C) 1994-2013 Free Software Foundation, Inc.
# Copyright (C) 1994-2016 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
@@ -88,7 +88,7 @@ INCLUDES = -I$(srcdir)/glob -DLIBDIR=\"$(prefix)$(libdir)\" -DINCLUDEDIR=\"$(pre
BUILT_SOURCES = README build.sh-in
EXTRA_DIST = $(BUILT_SOURCES) $(man_MANS) README.customs remote-cstms.c make-stds.texi texinfo.tex SCOPTIONS SMakefile Makefile.ami README.Amiga config.ami amiga.c amiga.h NMakefile README.DOS configh.dos configure.bat makefile.com README.W32 build_w32.bat config.h-W32 subproc.bat make.lnk config.h-vms makefile.vms readme.vms vmsdir.h vmsfunctions.c vmsify.c gmk-default.scm gmk-default.h
EXTRA_DIST = $(BUILT_SOURCES) $(man_MANS) README.customs remote-cstms.c make-stds.texi texinfo.tex SCOPTIONS SMakefile Makefile.ami README.Amiga config.ami amiga.c amiga.h NMakefile README.DOS configh.dos configure.bat makefile.com README.W32 build_w32.bat config.h-W32 subproc.bat make.lnk config.h-vms makefile.vms README.VMS vmsdir.h vmsfunctions.c vmsify.c gmk-default.scm gmk-default.h
SUBDIRS = glob doc
mkinstalldirs = ${exec_prefix}/bin/gmkdir -p

View File

@@ -1,6 +1,6 @@
# This is a -*-Makefile-*-, or close enough
#
# Copyright (C) 1997-2013 Free Software Foundation, Inc.
# Copyright (C) 1997-2016 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,8 +16,8 @@
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>.
AUTOMAKE_OPTIONS = 1.8 dist-bzip2 check-news
ACLOCAL_AMFLAGS = -I config
AUTOMAKE_OPTIONS = dist-bzip2 silent-rules std-options
ACLOCAL_AMFLAGS = -I config
MAKE_HOST = @MAKE_HOST@
@@ -26,6 +26,9 @@ if WINDOWSENV
MAYBE_W32 = w32
W32INC = -I $(top_srcdir)/w32/include
W32LIB = -Lw32 -lw32
ossrc =
else
ossrc = posixos.c
endif
SUBDIRS = glob config po doc $(MAYBE_W32)
@@ -40,19 +43,15 @@ else
endif
make_SOURCES = ar.c arscan.c commands.c default.c dir.c expand.c file.c \
function.c getopt.c getopt1.c implicit.c job.c load.c \
loadapi.c main.c misc.c output.c read.c remake.c rule.c \
signame.c strcache.c variable.c version.c vpath.c hash.c \
$(remote)
if HAVE_GUILE
make_SOURCES += guile.c
endif
function.c getopt.c getopt1.c guile.c implicit.c job.c load.c \
loadapi.c main.c misc.c $(ossrc) output.c read.c remake.c \
rule.c signame.c strcache.c variable.c version.c vpath.c \
hash.c $(remote)
EXTRA_make_SOURCES = vmsjobs.c remote-stub.c remote-cstms.c
noinst_HEADERS = commands.h dep.h filedef.h job.h makeint.h rule.h variable.h \
debug.h getopt.h gettext.h hash.h output.h
debug.h getopt.h gettext.h hash.h output.h os.h
make_LDADD = @LIBOBJS@ @ALLOCA@ $(GLOBLIB) @GETLOADAVG_LIBS@ @LIBINTL@ \
$(GUILE_LIBS)
@@ -75,28 +74,22 @@ endif
# Extra stuff to include in the distribution.
EXTRA_DIST = README build.sh.in $(man_MANS) \
EXTRA_DIST = ChangeLog README build.sh.in $(man_MANS) \
README.customs README.OS2 \
SCOPTIONS SMakefile \
README.Amiga Makefile.ami config.ami make.lnk amiga.c amiga.h \
README.DOS Makefile.DOS configure.bat dosbuild.bat configh.dos\
README.W32 NMakefile config.h.W32 build_w32.bat subproc.bat \
make_msvc_net2003.sln make_msvc_net2003.vcproj \
readme.vms makefile.vms makefile.com config.h-vms \
vmsdir.h vmsfunctions.c vmsify.c \
README.VMS makefile.vms makefile.com config.h-vms \
vmsdir.h vmsfunctions.c vmsify.c vms_exit.c vms_progname.c \
vms_export_symbol.c vms_export_symbol_test.com \
gmk-default.scm gmk-default.h
# This is built during configure, but behind configure's back
DISTCLEANFILES = build.sh
# Forward targets
html:
cd doc && $(MAKE) $(AM_MAKEFLAGS) $@
.PHONY: html
# --------------- Internationalization Section
localedir = $(datadir)/locale
@@ -136,8 +129,8 @@ guile.$(OBJEXT): gmk-default.h
gmk-default.h: $(srcdir)/gmk-default.scm
(echo 'static const char *const GUILE_module_defn = " '\\ \
&& sed -e 's/;.*//' -e '/^[ \t]*$$/d' -e 's/"/\\"/g' -e 's/$$/ \\/' \
$(srcdir)/gmk-default.scm \
&& echo '";') > $@
$(srcdir)/gmk-default.scm \
&& echo '";') > $@
# --------------- Local DIST Section
@@ -183,8 +176,9 @@ loadavg_LDADD = @GETLOADAVG_LIBS@
#
MAKETESTFLAGS =
check-regression:
check-regression: tests/config-flags.pm
@if test -f '$(srcdir)/tests/run_make_tests'; then \
ulimit -n 128; \
if $(PERL) -v >/dev/null 2>&1; then \
case `cd '$(srcdir)'; pwd` in `pwd`) : ;; \
*) test -d tests || mkdir tests; \
@@ -199,9 +193,9 @@ check-regression:
else \
echo "Can't find a working Perl ($(PERL)); the test suite requires Perl."; \
fi; \
else \
else \
echo "Can't find the GNU Make test suite ($(srcdir)/tests)."; \
fi
fi
# --------------- Maintainer's Section

View File

@@ -3,7 +3,7 @@
# NOTE: If you have no 'make' program at all to process this makefile, run
# 'build.sh' instead.
#
# Copyright (C) 1995-2013 Free Software Foundation, Inc.
# Copyright (C) 1995-2016 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

390
NEWS
View File

@@ -1,6 +1,6 @@
GNU make NEWS -*-indented-text-*-
History of user-visible changes.
16 Sep 2013
22 May 2016
See the end of this file for copyrights and conditions.
@@ -9,7 +9,94 @@ 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
reporting bugs.
Version 3.99.91
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
* 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
successful or not "0" if not successful. The variable value is unset if no
!= or $(shell ...) function has been invoked.
* The $(file ...) function can now read from a file with $(file <FILE).
The function is expanded to the contents of the file. The contents are
expanded verbatim except that the final newline, if any, is stripped.
* The makefile line numbers shown by GNU make now point directly to the
specific line in the recipe where the failure or warning occurred.
Sample changes suggested by Brian Vandenberg <phantall@gmail.com>
* The interface to GNU make's "jobserver" is stable as documented in the
manual, for tools which may want to access it.
WARNING: Backward-incompatibility! The internal-only command line option
--jobserver-fds has been renamed for publishing, to --jobserver-auth.
* The amount of parallelism can be determined by querying MAKEFLAGS, even when
the job server is enabled (previously MAKEFLAGS would always contain only
"-j", with no number, when job server was enabled).
* VMS-specific changes:
* Perl test harness now works.
* Full support for converting Unix exit status codes to VMS exit status
codes. BACKWARD INCOMPATIBILITY Notice: On a child failure the VMS exit
code is now the encoded Unix exit status that Make usually generates, not
the VMS exit status of the child.
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
* 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
terminal. These variables are exported by default.
* Allow a no-text-argument form of the $(file ...) function. Without a text
argument nothing is written to the file: it is simply opened in the
requested mode, then closed again.
* Change the fatal error for mixed explicit and implicit rules, that was
introduced in GNU make 3.82, to a non-fatal error. However, this syntax is
still deprecated and may return to being illegal in a future version of GNU
make. Makefiles that rely on this syntax should be fixed.
See https://savannah.gnu.org/bugs/?33034
* VMS-specific changes:
* Support for library files added, including support for using the GNV ar
utility.
* Partial support for properly encoding Unix exit status codes into VMS exit
status codes.
WARNING: Backward-incompatibility! These are different exit status codes
than Make exited with in the past.
* Macros to hold the current make command are set up to translate the
argv[0] string to a VMS format path name and prefix it with "MCR " so that
the macro has a space in it.
WARNING: Backward-incompatibility! This may break complex makefiles that
do processing on those macros. This is unlikely because so much in that
area was not and is still not currently working on VMS, it is unlikely to
find such a complex makefile, so this is more likely to impact
construction of a future makefile.
* A command file is always used to run the commands for a recipe.
WARNING: Backward-incompatibility! Running the make self tests has
exposed that there are significant differences in behavior when running
with the command file mode. It is unknown if this will be noticed by most
existing VMS makefiles.
Version 4.0 (09 Oct 2013)
A complete list of bugs fixed in this version is available here:
@@ -23,6 +110,14 @@ http://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=101&set
* Each backslash/newline (plus subsequent whitespace) is converted to a
single space
* New feature: GNU Guile integration
This version of GNU make can be compiled with GNU Guile integration.
GNU Guile serves as an embedded extension language for make.
See the "Guile Function" section in the GNU Make manual for details.
Currently GNU Guile 1.8 and 2.0+ are supported. In Guile 1.8 there is no
support for internationalized character sets. In Guile 2.0+, scripts can be
encoded in UTF-8.
* New command line option: --output-sync (-O) enables grouping of output by
target or by recursive make. This is useful during parallel builds to avoid
mixing output from different jobs together giving hard-to-understand
@@ -47,6 +142,8 @@ http://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=101&set
* New feature: "!=" shell assignment operator as an alternative to the
$(shell ...) function. Implemented for compatibility with BSD makefiles.
Note there are subtle differences between "!=" and $(shell ...). See the
description in the GNU make manual.
WARNING: Backward-incompatibility!
Variables ending in "!" previously defined as "variable!= value" will now be
interpreted as shell assignment. Change your assignment to add whitespace
@@ -58,11 +155,6 @@ http://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=101&set
version of POSIX (see http://austingroupbugs.net/view.php?id=330). It is
not necessary to define the .POSIX target to access this operator.
* New feature: GNU Guile integration
This version of GNU make can be compiled with GNU Guile integration.
GNU Guile serves as an embedded extension language for make.
See the "Guile Function" section in the GNU Make manual for details.
* New feature: Loadable objects
This version of GNU make contains a "technology preview": the ability to
load dynamic objects into the make runtime. These objects can be created by
@@ -73,7 +165,8 @@ http://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=101&set
* New variable: $(GNUMAKEFLAGS) will be parsed for make flags, just like
MAKEFLAGS is. It can be set in the environment or the makefile, containing
GNU make-specific flags to allow your makefile to be portable to other
versions of make. GNU make never sets or modifies GNUMAKEFLAGS.
versions of make. Once this variable is parsed, GNU make will set it to the
empty string so that flags will not be duplicated on recursion.
* New variable: `MAKE_HOST' gives the name of the host architecture
make was compiled for. This is the same value you see after 'Built for'
@@ -81,8 +174,10 @@ http://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=101&set
* Behavior of MAKEFLAGS and MFLAGS is more rigorously defined. All simple
flags are grouped together in the first word of MAKEFLAGS. No options that
accept arguments appear there. If no simple flags are present MAKEFLAGS
begins with a space. MFLAGS never begins with "- ".
accept arguments appear in the first word. If no simple flags are present
MAKEFLAGS begins with a space. Flags with both short and long versions
always use the short versions in MAKEFLAGS. Flags are listed in
alphabetical order using ASCII ordering. MFLAGS never begins with "- ".
* Setting the -r and -R options in MAKEFLAGS inside a makefile now works as
expected, removing all built-in rules and variables, respectively.
@@ -135,15 +230,6 @@ http://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=104&set
results from wildcard expansions, use the $(sort ...) function to request
it explicitly.
* WARNING: Backward-incompatibility!
In previous versions of make it was acceptable to list one or more explicit
targets followed by one or more pattern targets in the same rule and it
worked "as expected". However, this was not documented as acceptable and if
you listed any explicit targets AFTER the pattern targets, the entire rule
would be mis-parsed. This release removes this ability completely: make
will generate an error message if you mix explicit and pattern targets in
the same rule.
* WARNING: Backward-incompatibility!
As a result of parser enhancements, three backward-compatibility issues
exist: first, a prerequisite containing an "=" cannot be escaped with a
@@ -217,6 +303,57 @@ http://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=104&set
after the variable name, to allow for simple, conditional, or appending
multi-line variable assignment.
* VMS-specific changes:
* Michael Gehre (at VISTEC-SEMI dot COM) supplied a fix for a problem with
timestamps of object modules in OLBs. The timestamps were not correctly
adjusted to GMT based time, if the local VMS time was using a daylight
saving algorithm and if daylight saving was switched off.
* John Eisenbraun (at HP dot COM) supplied fixes and and an enhancement to
append output redirection in action lines.
* Rework of ctrl+c and ctrl+y handling.
* Fix a problem with cached strings, which showed on case-insensitive file
systems.
* Build fixes for const-ified code in VMS specific sources.
* A note on appending the redirected output. With this change, a simple
mechanism is implemented to make ">>" work in action lines. In VMS
there is no simple feature like ">>" to have DCL command or program
output redirected and appended to a file. GNU make for VMS already
implements the redirection of output. If such a redirection is detected,
an ">" on the action line, GNU make creates a DCL command procedure to
execute the action and to redirect its output. Based on that, now ">>"
is also recognized and a similar but different command procedure is
created to implement the append. The main idea here is to create a
temporary file which collects the output and which is appended to the
wanted output file. Then the temporary file is deleted. This is all done
in the command procedure to keep changes in make small and simple. This
obviously has some limitations but it seems good enough compared with
the current ">" implementation. (And in my opinion, redirection is not
really what GNU make has to do.) With this approach, it may happen that
the temporary file is not yet appended and is left in SYS$SCRATCH.
The temporary file names look like "CMDxxxxx.". Any time the created
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 as well. Its name is CMDxxxxx.COM.
* Change in the Ctrl+Y handling. The CtrlY handler now uses $delprc to
delete all children. This way also actions with DCL commands will be
stopped. As before the CtrlY handler then sends SIGQUIT to itself,
which is handled in common code.
* Change in deleteing temporary command files. Temporary command files
are now deleted in the vms child termination handler. That deletes
them even if a Ctrl+C was pressed.
* 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.
Version 3.81 (01 Apr 2006)
@@ -231,8 +368,8 @@ Version 3.81 (01 Apr 2006)
any prerequisite that does not exist, even though that prerequisite
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 this Savannah bug:
http://savannah.gnu.org/bugs/index.php?func=detailitem&item_id=16051
the target to be considered out of date.
See http://savannah.gnu.org/bugs/?16051
* WARNING: Backward-incompatibility!
GNU make now implements a generic "second expansion" feature on the
@@ -341,7 +478,7 @@ Version 3.81 (01 Apr 2006)
could be found on the system.
* On VMS there is now support for case-sensitive filesystems such as ODS5.
See the readme.vms file for information.
See the README.VMS file for information.
* Parallel builds (-jN) no longer require a working Bourne shell on
Windows platforms. They work even with the stock Windows shells, such
@@ -436,6 +573,42 @@ Version 3.80 (03 Oct 2002)
* Updated to autoconf 2.54 and automake 1.7. Users should not be impacted.
* VMS-specific changes:
* In default.c define variable ARCH as IA64 for VMS on Itanium systems.
* In makefile.vms avoid name collision for glob and globfree.
* This is the VMS port of GNU Make done by Hartmut.Becker@compaq.com.
It is based on the specific version 3.77k and on 3.78.1. 3.77k was done
by Klaus Kämpf <kkaempf@rmi.de>, the code was based on the VMS port of
GNU Make 3.60 by Mike Moretti.
It was ported on OpenVMS/Alpha V7.1, DECC V5.7-006. It was re-build and
tested on OpenVMS/Alpha V7.2, OpenVMS/VAX 7.1 and 5.5-2. Different
versions of DECC were used. VAXC was tried: it fails; but it doesn't
seem worth to get it working. There are still some PTRMISMATCH warnings
during the compile. Although perl is working on VMS the test scripts
don't work. The function $shell is still missing.
There is a known bug in some of the VMS CRTLs. It is in the shipped
versions of VMS V7.2 and V7.2-1 and in the currently (October 1999)
available ECOs for VMS V7.1 and newer versions. It is fixed in versions
shipped with newer VMS versions and all ECO kits after October 1999. It
only shows up during the daylight saving time period (DST): stat()
returns a modification time 1 hour ahead. This results in GNU make
warning messages. For a just created source you will see:
$ gmake x.exe
gmake.exe;1: *** Warning: File 'x.c' has modification time in the future
(940582863 > 940579269)
cc /obj=x.obj x.c
link x.obj /exe=x.exe
gmake.exe;1: *** Warning: Clock skew detected. Your build may be
incomplete.
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
@@ -491,7 +664,57 @@ Version 3.79 (04 Apr 2000)
returned.
* Hartmut Becker provided many updates for the VMS port of GNU make.
See the readme.vms file for more details.
See the README.VMS file for more details.
* VMS-specific changes:
* Fix a problem with automatically remaking makefiles. GNU make uses an
execve to restart itself after a successful remake of the makefile. On
UNIX systems execve replaces the running program with a new one and
resets all signal handling to the default. On VMS execve creates a child
process, signal and exit handlers of the parent are still active, and,
unfortunately, corrupt the exit code from the child. Fix in job.c:
ignore SIGCHLD.
* Added some switches to reflect latest features of DECC. Modifications in
makefile.vms.
* Set some definitions to reflect latest features of DECC. Modifications in
config.h-vms (which is copied to config.h).
* Added extern strcmpi declaration to avoid 'implicitly declared' messages.
Modification in make.h.
* Default rule for C++, conditionals for gcc (GCC_IS_NATIVE) or DEC/Digital/
Compaq c/c++ compilers. Modifications in default.c.
* Usage of opendir() and friends, suppress file version. Modifications in
dir.c.
* Added VMS specific code to handle ctrl+c and ctrl+y to abort make.
Modifications in job.c.
* Added support to have case sensitive targets and dependencies but to
still use case blind file names. This is especially useful for Java
makefiles on VMS:
.SUFFIXES :
.SUFFIXES : .class .java
.java.class :
javac "$<
HelloWorld.class : HelloWorld.java
* A new macro WANT_CASE_SENSITIVE_TARGETS in config.h-vms was introduced.
It needs to be enabled to get this feature; default is disabled. The
macro HAVE_CASE_INSENSITIVE_FS must not be touched: it is still enabled.
Modifications in file.c and config.h-vms.
* Bootstrap make to start building make is still makefile.com, but make
needs to be re-made with a make to make a correct version: ignore all
possible warnings, delete all objects, rename make.exe to a different
name and run it.
* Made some minor modifications to the bootstrap build makefile.com.
Version 3.78 (22 Sep 1999)
@@ -594,6 +817,45 @@ Version 3.77 (28 Jul 1998)
* Updates to the Windows 95/NT port from Rob Tulloh (see README.W32),
and to the DOS port from Eli Zaretski (see README.DOS).
* VMS-specific changes:
* This is the VMS port of GNU Make.
It is based on the VMS port of GNU Make 3.60 by Mike Moretti.
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
about other vms software and forthcoming updates to gnu make.
* /bin/sh style I/O redirection is supported. You can now write lines like
mcr sys$disk:[]program.exe < input.txt > output.txt &> error.txt
* Makefile variables are looked up in the current environment. You can set
symbols or logicals in DCL and evaluate them in the Makefile via
$(<name-of-symbol-or-logical>). Variables defined in the Makefile
override VMS symbols/logicals !
* Functions for file names are working now. See the GNU Make manual for
$(dir ...) and $(wildcard ...). Unix-style and VMS-style names are
supported as arguments.
* The default rules are set up for GNU C. Building an executable from a
single source file is as easy as 'make file.exe'.
* The variable $(ARCH) is predefined as ALPHA or VAX resp. Makefiles for
different VMS systems can now be written by checking $(ARCH) as in
ifeq ($(ARCH),ALPHA)
$(ECHO) "On the Alpha"
else
$(ECHO) "On the VAX"
endif
* Command lines of excessive length are correctly broken and written to a
batch file in sys$scratch for later execution. There's no limit to the
lengths of commands (and no need for .opt files :-) any more.
* Empty commands are handled correctly and don't end in a new DCL process.
Version 3.76.1 (19 Sep 1997)
@@ -642,8 +904,54 @@ Version 3.76 (16 Sep 1997)
concerning this port to Eli Zaretskii <eliz@is.elta.co.il> or DJ
Delorie <dj@delorie.com>.
* John W. Eaton has updated the VMS port to support libraries and VPATH.
* VMS-specific changes:
* John W. Eaton has updated the VMS port to support libraries and VPATH.
* The cd command is supported if it's called as $(CD). This invokes
the 'builtin_cd' command which changes the directory.
Calling 'set def' doesn't do the trick, since a sub-shell is
spawned for this command, the directory is changed *in this sub-shell*
and the sub-shell ends.
* Libraries are not supported. They were in GNU Make 3.60 but somehow I
didn't care porting the code. If there is enough interest, I'll do it at
some later time.
* The variable $^ separates files with commas instead of spaces (It's the
natural thing to do for VMS).
* See defaults.c for VMS default suffixes and my definitions for default
rules and variables.
* The shell function is not implemented yet.
* Load average routines haven't been implemented for VMS yet.
* The default include directory for including other makefiles is
SYS$SYSROOT:[SYSLIB] (I don't remember why I didn't just use
SYS$LIBRARY: instead; maybe it wouldn't work that way).
* The default makefiles make looks for are: makefile.vms, gnumakefile,
makefile., and gnumakefile. .
* The stat() function and handling of time stamps in VMS is broken, so I
replaced it with a hack in vmsfunctions.c. I will provide a full rewrite
somewhere in the future. Be warned, the time resolution inside make is
less than what vms provides. This might be a problem on the faster Alphas.
* You can use a : in a filename only if you precede it with a backslash ('\').
E.g.- hobbes\:[bogas.files]
* Make ignores success, informational, or warning errors (-S-, -I-, or -W-).
But it will stop on -E- and -F- errors. (unless you do something
to override this in your makefile, or whatever).
* Remote stuff isn't implemented yet.
* Multiple line DCL commands, such as "if" statements, must be put inside
command files. You can run a command file by using \@.
Version 3.75 (27 Aug 1996)
* The directory messages printed by `-w' and implicitly in sub-makes,
@@ -664,6 +972,14 @@ Version 3.75 (27 Aug 1996)
* Rob Tulloh of Tivoli Systems has contributed a port to Windows NT or 95.
See README.W32 for details, and direct all Windows-related questions to
<rob_tulloh@tivoli.com>.
* VMS-specific changes:
* Lots of default settings are adapted for VMS. See default.c.
* Long command lines are now converted to command files.
* Comma (',') as a separator is now allowed. See makefile.vms for an example.
Version 3.73 (05 Apr 1995)
@@ -759,7 +1075,7 @@ Version 3.69 (07 Nov 1993)
have reversed the change made in version 3.68 because it turned out to
cause a paradoxical situation in cases like:
export variable = $(shell echo value)
export variable = $(shell echo value)
When Make attempted to put this variable in the environment for a
recipe, it would try expand the value by running the shell command
@@ -782,8 +1098,8 @@ Version 3.68 (28 Jul 1993)
foo.a(b.o) bar.a(c.o) bar.a(d.o)'.
* A suffix rule `.X.a' now produces two pattern rules:
(%.o): %.X # Previous versions produced only this.
%.a: %.X # Now produces this as well, just like other suffixes.
(%.o): %.X # Previous versions produced only this.
%.a: %.X # Now produces this as well, just like other suffixes.
* The new flag `--warn-undefined-variables' says to issue a warning message
whenever Make expands a reference to an undefined variable.
@@ -853,15 +1169,15 @@ Version 3.63 (22 Jan 1993)
no longer automatically put into the environments of the recipe lines that
Make runs. Instead, only variables specified on the command line or in
the environment are exported by default. To export others, use:
export VARIABLE
export VARIABLE
or you can define variables with:
export VARIABLE = VALUE
export VARIABLE = VALUE
or:
export VARIABLE := VALUE
export VARIABLE := VALUE
You can use just:
export
export
or:
.EXPORT_ALL_VARIABLES:
.EXPORT_ALL_VARIABLES:
to get the old behavior. See the node `Variables/Recursion' in the manual
for a full description.
@@ -881,9 +1197,9 @@ Version 3.63 (22 Jan 1993)
* A single `include' directive can now specify more than one makefile to
include, like this:
include file1 file2
include file1 file2
You can also use shell file name patterns in an `include' directive:
include *.mk
include *.mk
* The default directories to search for included makefiles, and for
libraries specified with `-lNAME', are now set by configuration.
@@ -1019,7 +1335,7 @@ Version 3.49
* The `wildcard' variable expansion function now expands ~ and ~USER.
* Messages indicating failed recipe lines now contain the target name:
make: *** [target] Error 1
make: *** [target] Error 1
* The `-p' output format has been changed somewhat to look more like
makefile rules and to give all information that Make has about files.
@@ -1199,7 +1515,7 @@ Version 3.05
(Changes from versions 1 through 3.05 were never recorded. Sorry.)
-------------------------------------------------------------------------------
Copyright (C) 1988-2013 Free Software Foundation, Inc.
Copyright (C) 1988-2016 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

View File

@@ -3,7 +3,7 @@
# NOTE: If you have no 'make' program at all to process this makefile,
# run 'build_w32.bat' instead.
#
# Copyright (C) 1996-2013 Free Software Foundation, Inc.
# Copyright (C) 1996-2016 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
@@ -32,9 +32,9 @@ CFLAGS_debug = $(CFLAGS_any) /Od /D DEBUG /D _DEBUG /FR.\WinDebug/ /Fp.\WinDebug
CFLAGS_release = $(CFLAGS_any) /O2 /D NDEBUG /FR.\WinRel/ /Fp.\WinRel/make.pch /Fo.\WinRel/
LDFLAGS_debug = w32\subproc\WinDebug\subproc.lib /NOLOGO /SUBSYSTEM:console\
/INCREMENTAL:no /PDB:WinDebug/make.pdb /OUT:WinDebug/make.exe /DEBUG
/STACK:0x400000 /INCREMENTAL:no /PDB:WinDebug/make.pdb /OUT:WinDebug/make.exe /DEBUG
LDFLAGS_release = w32\subproc\WinRel\subproc.lib /NOLOGO /SUBSYSTEM:console\
/INCREMENTAL:no /OUT:WinRel/make.exe
/STACK:0x400000 /INCREMENTAL:no /OUT:WinRel/make.exe
all: config.h subproc Release Debug
@@ -72,7 +72,7 @@ $(OUTDIR):
LIBS = kernel32.lib user32.lib advapi32.lib
#guile = $(OUTDIR)/guile.obj
guile = $(OUTDIR)/guile.obj
OBJS = \
$(OUTDIR)/ar.obj \
@@ -89,6 +89,7 @@ OBJS = \
$(OUTDIR)/hash.obj \
$(OUTDIR)/implicit.obj \
$(OUTDIR)/job.obj \
$(OUTDIR)/load.obj \
$(OUTDIR)/main.obj \
$(OUTDIR)/misc.obj \
$(OUTDIR)/output.obj \
@@ -105,6 +106,8 @@ OBJS = \
$(OUTDIR)/fnmatch.obj \
$(OUTDIR)/dirent.obj \
$(OUTDIR)/pathstuff.obj \
$(OUTDIR)/posixfcn.obj \
$(OUTDIR)/w32os.obj \
$(guile)
$(OUTDIR)/make.exe: $(OUTDIR) $(OBJS)
@@ -121,5 +124,9 @@ $(OUTDIR)/fnmatch.obj : glob/fnmatch.c
$(CC) $(CFLAGS) /c $?
$(OUTDIR)/dirent.obj : w32/compat/dirent.c
$(CC) $(CFLAGS) /c $?
$(OUTDIR)/posixfcn.obj : w32/compat/posixfcn.c
$(CC) $(CFLAGS) /c $?
$(OUTDIR)/pathstuff.obj : w32/pathstuff.c
$(CC) $(CFLAGS) /c $?
$(OUTDIR)/w32os.obj : w32/w32os.c
$(CC) $(CFLAGS) /c $?

View File

@@ -61,7 +61,7 @@ If you plan to use recursive makes, install make resident:
-------------------------------------------------------------------------------
Copyright (C) 1995-2013 Free Software Foundation, Inc.
Copyright (C) 1995-2016 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

View File

@@ -324,7 +324,7 @@ Bug reports:
-------------------------------------------------------------------------------
Copyright (C) 1996-2013 Free Software Foundation, Inc.
Copyright (C) 1996-2016 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

View File

@@ -160,7 +160,7 @@ from the make source tree.
-------------------------------------------------------------------------------
Copyright (C) 2003-2013 Free Software Foundation, Inc.
Copyright (C) 2003-2016 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

515
README.VMS Normal file
View File

@@ -0,0 +1,515 @@
Overview: -*-text-mode-*-
---------
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
make scripts with a special syntax that is described below. It
likely will not be able to run unmodified Unix makefiles.
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
GNU Make on Unix as possible.
The descriptions below are for running GNU make from DCL or equivalent.
Recipe differences:
-------------------
GNU Make for OpenVMS can not currently run native Unix make files because of
differences in the implementation.
I am trying to document the current behavior in this section. This is based
on the information in the file NEWS. and running the test suite.
TODO: More tests are needed to validate and demonstrate the OpenVMS
expected behavior.
In some cases the older behavior of GNU Make when run from DCL is not
compatible with standard makefile behavior.
This behavior can be changed when running GNU Make from DCL by setting
either DCL symbols or logical names of the format GNV$. The settings
are enabled with a string starting with one of '1', 'T', or 'E' for "1",
"TRUE", or "ENABLE". They are disabled with a '0', 'F', or 'D' for "1",
"FALSE", or "DISABLE". If they are not explicitly set to one of these
values, then they will be set to their default values.
The value of the setting DECC$FILENAME_UNIX_REPORT or
DECC$FILENAME_UNIX_ONLY will now cause the $(dir x) function to return
'./' or '[]' as appropriate.
The name GNV$MAKE_OLD_VMS when enabled will cause GNU Make to behave as
much as the older method as can be done with out disabling VMS features.
When it is disabled GNU Make have the new behavior which more closely
matches Unix Make behavior.
The default is currently the old behavior when running GNU Make from DCL.
In the future this may change. When running make from GNV Bash the new
behavior is the default.
This is a global setting that sets the default behavior for several other
options that can be individually changed. Many of the individual settings
are to make it so that the self tests for GNU Make need less VMS specific
modifications.
The name GNV$MAKE_COMMA when enabled will cause GNU Make to expect a comma
for a path separator and use a comma for the separator for a list of files.
When disabled, it will cause GNU Make to use a colon for a path separator
and a space for the separator for a list of files. The default is to be
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:
* 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
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.
VMS generally uses logical name search lists instead of path variables
where the resolution is handled by VMS independent of the program. Which
means that it is likely that nothing will notice if the default path
specifier is changed in the future.
Currently the built in VMS specific macros and recipes depend on the comma
being used as a file list separator.
TODO: Remove this dependency as other functions in GNU Make depend on a
space being used as a separator.
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.
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
recipe lines, allowing multiple line rules.
The default makefile search order is "makefile.vms", "gnumakefile",
"makefile". TODO: See if that lookup is case sensitive.
When Make is invoked from DCL, it will create a foreign command
using the name of executable image, with any facility prefix removed,
for the duration of the make program, so it can be used internally
to recursively run make(). The macro MAKE_COMMAND will be set to
this foreign command.
When make is launched from an exec*() command from a C program,
the foreign command is not created. The macro MAKE_COMMAND will be
set to the actual command passed as argv[0] to the exec*() function.
If the DCL symbol or logical name GNV$MAKE_USE_MCR exists, then
the macro MAKE_COMMAND will be set to be an "MCR" command with the
absolute path used by DCL to launch make. The foreign command
will not be created.
The macro MAKE is set to be the same value as the macro MAKE_COMMAND
on all platforms.
Each recipe command is normally run as a separate spawned processes,
except for the cases documented below where a temporary DCL command
file may be used.
BUG: Testing has shown that the commands in the temporary command files
are not always created properly. This issue is still under investigation.
Any macros marked as exported are temporarily created as DCL symbols
for child images to use. DCL symbol substitution is not done with these
commands.
Untested: Symbol substitution.
When a temporary DCL command file is used, DCL symbol substitution
will work.
For VMS 7.3-1 and earlier, command lines are limited to 255 characters
or 1024 characters in a command file.
For VMS 7.3-2 and later, command lines are limited to 4059 characters
or 8192 characters in a command file.
VMS limits each token of a command line to 256 characters, and limits
a command line to 127 tokens.
Command lines above the limit length are written to a command file
in sys$scratch:.
In order to handle Unix style extensions to VMS DCL, GNU Make has
parsed the recipe commands and them modified them as needed. The
parser has been re-written to resolve numerous bugs in handling
valid VMS syntax and potential buffer overruns.
The new parser may need whitespace characters where DCL does not require
it, and also may require that quotes are matched were DCL forgives if
they are not. There is a small chance that existing VMS specific makefiles
will be affected.
The '<', '>' was previously implemented using command files. Now
GNU Make will check to see if the is already a VMS "PIPE" command and
if it is not, will convert the command to a VMS "PIPE" command.
The '>>' redirection has been implemented by using a temporary command file.
This will be described later.
The DCL symbol or logical name GNV$MAKE_USE_CMD_FILE when set to a
string starting with one of '1','T', or 'E' for "1", "TRUE", or "ENABLE",
then temporary DCL command files are always used for running commands.
Some recipe strings with embedded new lines will not be handled correctly
when a command file is used.
GNU Make generally does text comparisons for the targets and sources. The
make program itself can handle either Unix or OpenVMS format filenames, but
normally does not do any conversions from one format to another.
TODO: The OpenVMS format syntax handling is incomplete.
TODO: ODS-5 EFS support is missing.
BUG: The internal routines to convert filenames to and from OpenVMS format
do not work correctly.
Note: In the examples below, line continuations such as a backslash may have
been added to make the examples easier to read in this format.
BUG: That feature does not completely work at this time.
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
as it does on Unix.
The variables $^ and $@ separate files with commas instead of spaces.
This is controlled by the name GNV$MAKE_COMMA as documented in the
previous section.
While this may seem the natural thing to do with OpenVMS, it actually
causes problems when trying to use other make functions that expect the
files to be separated by spaces. If you run into this, you need the
following workaround to convert the output.
TODO: Look at have the $^ and $@ use spaces like on Unix and have
and easy to use function to do the conversions and have the built
in OpenVMS specific recipes and macros use it.
Example:
comma := ,
empty :=
space := $(empty) $(empty)
foo: $(addsuffix .3,$(subs $(comma),$(space),$^)
Makefile variables are looked up in the current environment. You can set
symbols or logicals in DCL and evaluate them in the Makefile via
$(<name-of-symbol-or-logical>). Variables defined in the Makefile
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
that they should show up just as "environment".
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
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
single dollar signs.
The variable $(ARCH) is predefined as IA64, ALPHA or VAX respectively.
Makefiles for different OpenVMS systems can now be written by checking
$(ARCH). Since IA64 and ALPHA are similar, usually just a check for
VAX or not VAX is sufficient.
You may have to update makefiles that assume VAX if not ALPHA.
ifeq ($(ARCH),VAX)
$(ECHO) "On the VAX"
else
$(ECHO) "On the ALPHA or IA64"
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
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.
Lexical functions can be used in pipes to simulate shell file test rules.
Example:
Posix:
b : c ; [ -f $@ ] || echo >> $@
OpenVMS:
b : c ; if f$$search("$@") then pipe open/append xx $@ ; write xx "" ; close xx
You can also use pipes and turning messages off to silently test for a
failure.
x = %x1035a00a
%.b : %.c
<tab>pipe set mess/nofac/noiden/nosev/notext ; type $^/output=$@ || exit $(x)
Runtime issues:
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
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
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
code.
Make internally has two error codes, MAKE_FAILURE and MAKE_TROUBLE. These
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.
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
other platforms it does not. Also output that would be in double quotes
on some platforms may show up as single quotes on VMS.
There may be extra blank lines in the output on VMS.
https://savannah.gnu.org/bugs/?func=detailitem&item_id=41760
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.
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.
TODO: VMS
There may be extra leading white space or additional or missing whitespace
in the output of recipes.
GNU Make uses sys$scratch: for the tempfiles that it creates.
The OpenVMS CRTL library maps /tmp to sys$scratch if the TMP: logical name
does not exist. As the CRTL may use both sys$scratch: and /tmp internally,
if you define the TMP logical name to be different than SYS$SCRATCH:,
you may end up with only some temporary files in TMP: and some in SYS$SCRATCH:
The default include directory for including other makefiles is
SYS$SYSROOT:[SYSLIB] (I don't remember why I didn't just use
SYS$LIBRARY: instead; maybe it wouldn't work that way).
TODO: A better default may be desired.
If the device for a file in a recipe does not exist, on OpenVMS an error
message of "stat: <file>: no such device or address" will be output.
Make ignores success, informational, or warning errors (-S-, -I-, or
-W-). But it will stop on -E- and -F- errors. (unless you do something
to override this in your makefile, or whatever).
Unix compatibilty 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
spawned for that command.
The 'builtin_cd' is generally expected to be on its own line.
The 'builtin_cd' either from the expansion of $(CD) or directly
put in a recipe line will be executed before any other commands in
that recipe line. DCL parameter substitution will not work for the
'builtin_cd' command.
Putting a 'builtin_cd' in a pipeline or an IF-THEN line should not be
done because the 'builtin_cd' is always executed
and executed first. The directory change is persistent.
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.
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
of ">>" by using a command procedure.
The current algorithm creates the output file if it does not exist and
then uses the DCL open/append to extend it. SYS$OUTPUT is then directed
to that file.
The implementation supports only one redirected append output to a file
and that redirection is done before any other commands in that line
are executed, so it redirects all output for that command.
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
abort make is one case.
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
actions with DCL commands will be stopped. As before the CtrlY handler
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.
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,
after the current action is terminated. If that doesn't happen or takes too
long, Ctrl+Y should be used instead.
Build Options:
Added support to have case sensitive targets and dependencies but to
still use case blind file names. This is especially useful for Java
makefiles on VMS:
<TAB>.SUFFIXES :
<TAB>.SUFFIXES : .class .java
<TAB>.java.class :
<TAB><TAB>javac "$<"
<TAB>HelloWorld.class : HelloWorld.java
A new macro WANT_CASE_SENSITIVE_TARGETS in config.h-vms was introduced.
It needs to be enabled to get this feature; default is disabled.
TODO: This should be a run-time setting based on if the process
has been set to case sensitive.
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
for OpenVMS does not support running multiple commands simultaneously.
Self test failures and todos:
-----------------------------
The test harness can not handle testing some of the VMS specific modes
because of the features needed for to be set for the Perl to run.
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
Perl test script to compensate for it. This should be being handled
internally to Make.
TODO: Verify and update the Perl test script.
The features/parallelism test was failing. OpenVMS is executing the rules
in sequence not in parallel as this feature was not implemented.
GNU Make on VMS no longer claims it is implemented.
TODO: Implement it.
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.
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
names correctly.
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.
Make a 1st version
$ @makefile.com ! ignore any compiler and/or linker warning
$ copy make.exe 1st-make.exe
Use the 1st version to generate a 2nd version as a test.
$ mc sys$disk:[]1st-make clean ! ignore any file not found messages
$ mc sys$disk:[]1st-make
Verify your 2nd version by building Make again.
$ copy make.exe 2nd-make.exe
$ mc sys$disk:[]2nd-make clean
$ mc sys$disk:[]2nd-make
Running the tests:
------------------
Running the tests on OpenVMS requires the following software to be installed
as most of the tests are Unix oriented.
* Perl 5.18 or later.
https://sourceforge.net/projects/vmsperlkit/files/
* GNV 2.1.3 + Updates including a minimum of:
* Bash 4.3.30
* ld_tools 3.0.2
* coreutils 8.21
https://sourceforge.net/p/gnv/wiki/InstallingGNVPackages/
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
a dedicated login to run the tests.
To get detailed information for running the tests:
$ set default [.tests]
$ @run_make_tests help
Running the script with no parameters will run all the tests.
After the the test script has been run once in a session, assuming
that you built make in sys$disk:[make], you can redefined the
"bin" logical name as follows:
$ define bin sys$disk:[make],gnv$gnu:[bin]
Then you can use Perl to run the scripts.
$ perl run_make_tests.pl
Acknowlegements:
----------------
See NEWS. for details of past changes.
These are the currently known contributers to this port.
Hartmut Becker
John Malmberg
Michael Gehre
John Eisenbraun
Klaus Kaempf
Mike Moretti
John W. Eaton

View File

@@ -1,44 +1,45 @@
This version of GNU make has been tested on
Microsoft Windows 2000/XP/2003/Vista/7/2008.
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.
It builds with the MinGW port of GCC (tested with GCC 3.4.2).
It builds with the MinGW port of GCC (tested with GCC 3.4.2, 4.8.1,
and 4.9.3).
It also builds with MSVC 2.x, 4.x, 5.x, 6.x, and 2003 as well as
with .NET 7.x and .NET 2003.
It also builds with MSVC 2.x, 4.x, 5.x, 6.x, 2003, and 14 (2015) as
well as with .NET 7.x and .NET 2003.
As of version 3.83, a build with Guile is supported (tested with Guile
As of version 4.0, a build with Guile is supported (tested with Guile
2.0.3). To build with Guile, you will need, in addition to Guile
itself, its dependency libraries and the pkg-config program. The
latter is used to figure out 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 the Windows download page of the GTK+ project:
on ezwinports site:
http://www.gtk.org/download/win32.php
http://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
will be needed, and typically also GNU MP, libffi, libunistring, and
libtool's libltdl. Whoever built the port of Guile you have should
also provide you with these dependencies or a URL where to download
them.
them. A precompiled 32-bit Windows build of Guile is available from
the ezwinports site mentioned above.
The Windows 32-bit port of GNU make is maintained jointly by various
people. It was originally made by Rob Tulloh.
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.
Do this first, regardless of the build method you choose:
---------------------------------------------------------
1. At the Windows command prompt run:
if not exist NMakefile copy NMakefile.template NMakefile
if not exist config.h copy config.h.W32 config.h
Then edit config.h to your liking (especially the few shell-related
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').
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.)
Using make_msvc_net2003.vcproj
@@ -57,7 +58,9 @@ Building with (MinGW-)GCC using build_w32.bat
build_w32.bat gcc
This produces gnumake.exe in the current directory.
This produces gnumake.exe in the GccRel directory.
If you want a version of GNU make built with debugging enabled,
add the --debug option.
The batch file will probe for Guile installation, and will build
gnumake.exe with Guile if it finds it. If you have Guile
@@ -77,7 +80,9 @@ Building with (MSVC++-)cl using build_w32.bat or NMakefile
build_w32.bat
(this produces WinDebug/gnumake.exe and WinRel/gnumake.exe)
This produces gnumake.exe in the WinRel directory.
If you want a version of GNU make built with debugging enabled,
add the --debug option.
... OR ...
@@ -293,7 +298,7 @@ Bug reports:
is described in the GNU make manual and the base README.
-------------------------------------------------------------------------------
Copyright (C) 1996-2013 Free Software Foundation, Inc.
Copyright (C) 1996-2016 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

View File

@@ -96,7 +96,7 @@ SunOS 4.1.x:
-------------------------------------------------------------------------------
Copyright (C) 1998-2013 Free Software Foundation, Inc.
Copyright (C) 1998-2016 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

View File

@@ -1,7 +1,7 @@
-*-text-*-
-------------------------------------------------------------------------------
Copyright (C) 2002-2013 Free Software Foundation, Inc.
Copyright (C) 2002-2016 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
@@ -31,12 +31,17 @@ make source code via Git from the FSF's Savannah project
Changes using Git
-----------------
For non-developers, please continue to provide patches as before, or if you
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.
For developers, I'm still new to Git myself, so I don't have a ton of advice.
In this release we will continue to create ChangeLog files by hand so please
don't forget to update the ChangeLog.
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
after conversion. In particular, each line of your comment will have a TAB
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").
@@ -59,12 +64,13 @@ 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. 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.
GNU make code adheres to the GNU Coding Standards. Please use only spaces and
no TAB characters in source code.
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.
Building From Git
@@ -73,7 +79,7 @@ Building From Git
To build GNU make from Git, you will need Autoconf, Automake, and
Gettext, and any tools that those utilities require (GNU m4, Perl,
etc.). See the configure.ac file to find the minimum versions of each
of these tools. You will also need a copy of wget.
of these tools. You will also need a copy of wget and gnulib.
When building from Git you must build in the source directory: "VPATH
builds" from remote directories are not supported. Once you've created
@@ -83,7 +89,6 @@ there.
After checking out the code, you will need to perform these steps to get
to the point where you can run "make".
1) $ autoreconf -i
This rebuilds all the things that need rebuilding, installing
@@ -92,12 +97,10 @@ to the point where you can run "make".
You may get warnings here about missing files like README, etc.
Ignore them, they are harmless.
2) $ ./configure
Generate a Makefile
3) $ make update
Use wget to retrieve various other files that GNU make relies on,
@@ -106,7 +109,6 @@ to the point where you can run "make".
NB: You may need GNU make to correctly perform this step; if you use
a platform-local make you may get problems with missing files in doc/.
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.
@@ -158,29 +160,50 @@ Steps to Release
----------------
Here are the things that need to be done (in more or less this order)
before making an official release:
before making an official release. If something breaks such that you need to
change code, be sure to start over again sufficiently that everything is
consistent (that's why we don't finalize the Git tag, etc. until the end).
* Update the configure.ac file with the new release number.
* Update the EDITION value in the doc/make.texi file.
* Update the NEWS file with the release number and date.
* Ensure the Savannah bug list URL in the NEWS file uses the correct
"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:
>>> This is only for real releases, not release candidate builds <<<
* 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, for "Bugs" and "Patches".
* Update the Savannah bug list URL in the NEWS file to use the correct
"Fixed Release" ID number.
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:
- Value: SCM
- Rank: 20
- Descr: Fixed in Git; will be available in the next version of Make.
* Run "make distcheck" to be sure it all works.
* git tag -u <GPGID> <VER> where GPGID is my GPG key fingerprint,
and VER is the release version.
* Push everything:
git push --tags origin master
* Create the new release in the Savannah "Bugs" Administration for
both the "Component Version" and "Fixed Release" fields.
* Create the new release in the Savannah "Patches" Administration for
the "Fixed Release" field.
- 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.
Start the next release:
* Update configure.ac and add a ".90" to the release number.
* Update the NEWS file with a new section for the release / date.
* Update the Savannah URL for the bugs fixed in the NEWS section.
Publishing a Package
@@ -220,19 +243,27 @@ work on it:
Where to Announce
-----------------
Create the announcement in a text file, then sign it with GPG.
Create the announcement in a text file, using 'git shortlog',
then sign it with GPG:
gpg --clearsign <announcement.txt>
Upload to gnu.org, then login and send from my account there.
Or, use your mail client's PGP/GPG signing capabilities.
To: bug-make@gnu.org, help-make@gnu.org, make-w32@gnu.org
CC: info-gnu@gnu.org
BCC: make-alpha@gnu.org
Announce the release:
Add a news item to the Savannah project site.
* 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
Add an update to freshmeat.net.
* 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

View File

@@ -142,7 +142,7 @@ Ports
- 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.
- See README.VMS for details about GNU Make on OpenVMS.
- See README.Amiga for details about GNU Make on AmigaDOS.
@@ -162,7 +162,7 @@ at the right README!
-------------------------------------------------------------------------------
Copyright (C) 1988-2013 Free Software Foundation, Inc.
Copyright (C) 1988-2016 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

View File

@@ -3,7 +3,7 @@
# NOTE: If you have no 'make' program at all to process this makefile,
# run 'build.sh' instead.
#
# Copyright (C) 1995-2013 Free Software Foundation, Inc.
# Copyright (C) 1995-2016 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

View File

@@ -99,33 +99,9 @@ The Rest of the List
you just can't figure it out. The way variables are expanded now
means this isn't 100% trivial, but it probably won't be hard.
8) Integration of Guile as an embedded scripting language. This means:
allowing Guile functions to be declared in makefiles somehow, then
providing a syntax for invoking them. At least one formulation of
that would have the function resolve to a string which would be
substituted in the makefile, kind of like $(shell ...) does now, but
using the embedded interpreter so there's no process forked of
course. Obviously this is an optional add-on feature.
It could be more advanced than that, even, who knows? Maybe make
could provide Guile functions that allow Guile scripts more direct
access to internal make structures, somehow. This kind of thing
needs a lot of thought.
Also there's always the flip side: in some very fundamental ways
make isn't the best choice right now for a complex build tool. It's
great for simple-to-medium tasks, but there are already other tools
available for the really tough situations. Ask yourself,
realistically, how much work is worthwhile to add to make, given the
fundamentals you can't really overcome without significantly
affecting backward compatibility--and then why not use another tool
in the first place?
Something to think about.
-------------------------------------------------------------------------------
Copyright (C) 1997-2013 Free Software Foundation, Inc.
Copyright (C) 1997-2016 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

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-2013 Free Software Foundation, Inc.
dnl Copyright (C) 1998-2016 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

View File

@@ -1,5 +1,5 @@
/* Running commands on Amiga
Copyright (C) 1995-2013 Free Software Foundation, Inc.
Copyright (C) 1995-2016 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
@@ -42,7 +42,7 @@ MyExecute (char **argv)
buffer = AllocMem (len, MEMF_ANY);
if (!buffer)
fatal (NILF, "MyExecute: Cannot allocate space for calling a command");
O (fatal, NILF, "MyExecute: Cannot allocate space for calling a command\n");
ptr = buffer;

View File

@@ -1,5 +1,5 @@
/* Definitions for amiga specific things
Copyright (C) 1995-2013 Free Software Foundation, Inc.
Copyright (C) 1995-2016 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

73
ar.c
View File

@@ -1,5 +1,5 @@
/* Interface to 'ar' archives for GNU Make.
Copyright (C) 1988-2013 Free Software Foundation, Inc.
Copyright (C) 1988-2016 Free Software Foundation, Inc.
This file is part of GNU Make.
@@ -43,7 +43,7 @@ ar_name (const char *name)
return 0;
if (p[1] == '(' && end[-1] == ')')
fatal (NILF, _("attempt to use unsupported feature: '%s'"), name);
OS (fatal, NILF, _("attempt to use unsupported feature: '%s'"), name);
return 1;
}
@@ -73,7 +73,7 @@ static long int
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,
int uid UNUSED, int gid UNUSED, int mode UNUSED,
int uid UNUSED, int gid UNUSED, unsigned int mode UNUSED,
const void *name)
{
return ar_name_equal (name, mem, truncated) ? date : 0;
@@ -120,7 +120,7 @@ ar_member_date (const char *name)
int
ar_touch (const char *name)
{
error (NILF, _("touch archive member is not available on VMS"));
O (error, NILF, _("touch archive member is not available on VMS"));
return -1;
}
#else
@@ -144,24 +144,24 @@ ar_touch (const char *name)
switch (ar_member_touch (arname, memname))
{
case -1:
error (NILF, _("touch: Archive '%s' does not exist"), arname);
OS (error, NILF, _("touch: Archive '%s' does not exist"), arname);
break;
case -2:
error (NILF, _("touch: '%s' is not a valid archive"), arname);
OS (error, NILF, _("touch: '%s' is not a valid archive"), arname);
break;
case -3:
perror_with_name ("touch: ", arname);
break;
case 1:
error (NILF,
_("touch: Member '%s' does not exist in '%s'"), memname, arname);
OSS (error, NILF,
_("touch: Member '%s' does not exist in '%s'"), memname, arname);
break;
case 0:
val = 0;
break;
default:
error (NILF,
_("touch: Bad return code from ar_member_touch on '%s'"), name);
OS (error, NILF,
_("touch: Bad return code from ar_member_touch on '%s'"), name);
}
free (arname);
@@ -172,10 +172,20 @@ ar_touch (const char *name)
/* State of an 'ar_glob' run, passed to 'ar_glob_match'. */
/* On VMS, (object) modules in libraries do not have suffixes. That is, to
find a match for a pattern, the pattern must not have any suffix. So the
suffix of the pattern is saved and the pattern is stripped (ar_glob).
If there is a match and the match, which is a module name, is added to
the chain, the saved suffix is added back to construct a source filename
(ar_glob_match). */
struct ar_glob_state
{
const char *arname;
const char *pattern;
#ifdef VMS
char *suffix;
#endif
unsigned int size;
struct nameseq *chain;
unsigned int n;
@@ -188,7 +198,7 @@ static long int
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,
int gid UNUSED, int mode UNUSED, const void *arg)
int gid UNUSED, unsigned int mode UNUSED, const void *arg)
{
struct ar_glob_state *state = (struct ar_glob_state *)arg;
@@ -196,7 +206,13 @@ ar_glob_match (int desc UNUSED, const char *mem, int truncated UNUSED,
{
/* We have a match. Add it to the chain. */
struct nameseq *new = xcalloc (state->size);
new->name = strcache_add (concat (4, state->arname, "(", mem, ")"));
#ifdef VMS
if (state->suffix)
new->name = strcache_add(
concat(5, state->arname, "(", mem, state->suffix, ")"));
else
#endif
new->name = strcache_add(concat(4, state->arname, "(", mem, ")"));
new->next = state->chain;
state->chain = new;
++state->n;
@@ -208,7 +224,7 @@ ar_glob_match (int desc UNUSED, const char *mem, int truncated UNUSED,
/* Return nonzero if PATTERN contains any metacharacters.
Metacharacters can be quoted with backslashes if QUOTE is nonzero. */
static int
glob_pattern_p (const char *pattern, int quote)
ar_glob_pattern_p (const char *pattern, int quote)
{
const char *p;
int opened = 0;
@@ -248,19 +264,46 @@ ar_glob (const char *arname, const char *member_pattern, unsigned int size)
struct nameseq *n;
const char **names;
unsigned int i;
if (! glob_pattern_p (member_pattern, 1))
#ifdef VMS
char *vms_member_pattern;
#endif
if (! ar_glob_pattern_p (member_pattern, 1))
return 0;
/* Scan the archive for matches.
ar_glob_match will accumulate them in STATE.chain. */
state.arname = arname;
state.pattern = member_pattern;
#ifdef VMS
{
/* In a copy of the pattern, find the suffix, save it and remove it from
the pattern */
char *lastdot;
vms_member_pattern = xstrdup(member_pattern);
lastdot = strrchr(vms_member_pattern, '.');
state.suffix = lastdot;
if (lastdot)
{
state.suffix = xstrdup(lastdot);
*lastdot = 0;
}
state.pattern = vms_member_pattern;
}
#endif
state.size = size;
state.chain = 0;
state.n = 0;
ar_scan (arname, ar_glob_match, &state);
#ifdef VMS
/* Deallocate any duplicated string */
free(vms_member_pattern);
if (state.suffix)
{
free(state.suffix);
}
#endif
if (state.chain == 0)
return 0;

378
arscan.c
View File

@@ -1,5 +1,5 @@
/* Library function for scanning an archive file.
Copyright (C) 1987-2013 Free Software Foundation, Inc.
Copyright (C) 1987-2016 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
@@ -16,6 +16,11 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#include "makeint.h"
#ifdef TEST
/* Hack, the real error() routine eventually pulls in die from main.c */
#define error(a, b, c, d)
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#else
@@ -30,99 +35,145 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#include <credef.h>
#include <descrip.h>
#include <ctype.h>
#if __DECC
#include <unixlib.h>
#include <lbr$routines.h>
#include <ssdef.h>
#include <stsdef.h>
#include <rmsdef.h>
/* This symbol should be present in lbrdef.h. */
#ifndef LBR$_HDRTRUNC
#pragma extern_model save
#pragma extern_model globalvalue
extern unsigned int LBR$_HDRTRUNC;
#pragma extern_model restore
#endif
#include <unixlib.h>
#include <lbr$routines.h>
const char *
vmsify (const char *name, int type);
/* Time conversion from VMS to Unix
Conversion from local time (stored in library) to GMT (needed for gmake)
Note: The tm_gmtoff element is a VMS extension to the ANSI standard. */
static time_t
vms_time_to_unix(void *vms_time)
{
struct tm *tmp;
time_t unix_time;
unix_time = decc$fix_time(vms_time);
tmp = localtime(&unix_time);
unix_time -= tmp->tm_gmtoff;
return unix_time;
}
/* VMS library routines need static variables for callback */
static void *VMS_lib_idx;
static char *VMS_saved_memname;
static time_t VMS_member_date;
static const void *VMS_saved_arg;
static long int (*VMS_function) ();
static long int VMS_function_ret;
/* This is a callback procedure for lib$get_index */
static int
VMS_get_member_info (struct dsc$descriptor_s *module, unsigned long *rfa)
VMS_get_member_info(struct dsc$descriptor_s *module, unsigned long *rfa)
{
int status, i;
long int fnval;
const int truncated = 0; /* Member name may be truncated */
time_t member_date; /* Member date */
char *filename;
unsigned int buffer_length; /* Actual buffer length */
time_t val;
/* Unused constants - Make does not actually use most of these */
const int file_desc = -1; /* archive file descriptor for reading the data */
const int header_position = 0; /* Header position */
const int data_position = 0; /* Data position in file */
const int data_size = 0; /* Data size */
const int uid = 0; /* member gid */
const int gid = 0; /* member gid */
const int mode = 0; /* member protection mode */
/* End of unused constants */
static struct dsc$descriptor_s bufdesc =
{ 0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL };
/* Only need the module definition */
struct mhddef *mhd;
char filename[128];
bufdesc.dsc$a_pointer = filename;
bufdesc.dsc$w_length = sizeof (filename);
status = lbr$set_module (&VMS_lib_idx, rfa, &bufdesc,
&bufdesc.dsc$w_length, 0);
if (! (status & 1))
/* If a previous callback is non-zero, just return that status */
if (VMS_function_ret)
{
error (NILF, _("lbr$set_module() failed to extract module info, status = %d"),
status);
lbr$close (&VMS_lib_idx);
return 0;
return SS$_NORMAL;
}
mhd = (struct mhddef *) filename;
/* lbr_set_module returns more than just the module header. So allocate
a buffer which is big enough: the maximum LBR$C_MAXHDRSIZ. That's at
least bigger than the size of struct mhddef.
If the request is too small, a buffer truncated warning is issued so
it can be reissued with a larger buffer.
We do not care if the buffer is truncated, so that is still a success. */
mhd = xmalloc(LBR$C_MAXHDRSIZ);
bufdesc.dsc$a_pointer = (char *) mhd;
bufdesc.dsc$w_length = LBR$C_MAXHDRSIZ;
#ifdef __DECC
/* John Fowler <jfowler@nyx.net> writes this is needed in his environment,
* but that decc$fix_time() isn't documented to work this way. Let me
* know if this causes problems in other VMS environments.
*/
{
/* Modified by M. Gehre at 11-JAN-2008 because old formula is wrong:
* val = decc$fix_time (&mhd->mhd$l_datim) + timezone - daylight*3600;
* a) daylight specifies, if the timezone has daylight saving enabled, not
* if it is active
* b) what we need is the information, if daylight saving was active, if
* the library module was replaced. This information we get using the
* localtime function
*/
status = lbr$set_module(&VMS_lib_idx, rfa, &bufdesc, &buffer_length, 0);
struct tm *tmp;
if ((status != LBR$_HDRTRUNC) && !$VMS_STATUS_SUCCESS(status))
{
ON(error, NILF,
_("lbr$set_module() failed to extract module info, status = %d"),
status);
/* Conversion from VMS time to C time */
val = decc$fix_time (&mhd->mhd$l_datim);
lbr$close(&VMS_lib_idx);
/*
* Conversion from local time (stored in library) to GMT (needed for gmake)
* Note: The tm_gmtoff element is a VMS extension to the ANSI standard.
*/
tmp = localtime (&val);
val -= tmp->tm_gmtoff;
}
return status;
}
#ifdef TEST
/* When testing this code, it is useful to know the length returned */
printf("Input length = %d, actual = %d\n",
bufdesc.dsc$w_length, buffer_length);
#endif
/* Conversion from VMS time to C time.
VMS defectlet - mhddef is sub-optimal, for the time, it has a 32 bit
longword, mhd$l_datim, and a 32 bit fill instead of two longwords, or
equivalent. */
member_date = vms_time_to_unix(&mhd->mhd$l_datim);
free(mhd);
/* Here we have a problem. The module name on VMS does not have
a file type, but the filename pattern in the "VMS_saved_arg"
may have one.
But only the method being called knows how to interpret the
filename pattern.
There are currently two different formats being used.
This means that we need a VMS specific code in those methods
to handle it. */
filename = xmalloc(module->dsc$w_length + 1);
/* TODO: We may need an option to preserve the case of the module
For now force the module name to lower case */
for (i = 0; i < module->dsc$w_length; i++)
filename[i] = _tolower ((unsigned char)module->dsc$a_pointer[i]);
filename[i] = _tolower((unsigned char )module->dsc$a_pointer[i]);
filename[i] = '\0';
VMS_member_date = (time_t) -1;
VMS_function_ret = (*VMS_function)(file_desc, filename, truncated,
header_position, data_position, data_size, member_date, uid, gid, mode,
VMS_saved_arg);
fnval =
(*VMS_function) (-1, filename, 0, 0, 0, 0, val, 0, 0, 0,
VMS_saved_memname);
if (fnval)
{
VMS_member_date = fnval;
return 0;
}
else
return 1;
free(filename);
return SS$_NORMAL;
}
/* Takes three arguments ARCHIVE, FUNCTION and ARG.
Open the archive named ARCHIVE, find its members one by one,
@@ -153,60 +204,89 @@ VMS_get_member_info (struct dsc$descriptor_s *module, unsigned long *rfa)
Returns 0 if have scanned successfully. */
long int
ar_scan (const char *archive, ar_member_func_t function, const void *arg)
ar_scan (const char *archive, ar_member_func_t function, const void *varg)
{
char *p;
char *vms_archive;
static struct dsc$descriptor_s libdesc =
{ 0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL };
unsigned long func = LBR$C_READ;
unsigned long type = LBR$C_TYP_UNK;
unsigned long index = 1;
const unsigned long func = LBR$C_READ;
const unsigned long type = LBR$C_TYP_UNK;
const unsigned long index = 1;
unsigned long lib_idx;
int status;
status = lbr$ini_control (&VMS_lib_idx, &func, &type, 0);
VMS_saved_arg = varg;
if (! (status & 1))
/* Null archive string can show up in test and cause an access violation */
if (archive == NULL)
{
error (NILF, _("lbr$ini_control() failed with status = %d"), status);
return -2;
}
/* there is no such descriptor with "const char *dsc$a_pointer" */
libdesc.dsc$a_pointer = (char *)archive;
libdesc.dsc$w_length = strlen (archive);
status = lbr$open (&VMS_lib_idx, &libdesc, 0, 0, 0, 0, 0);
if (! (status & 1))
{
error (NILF, _("unable to open library '%s' to lookup member '%s'"),
archive, (char *)arg);
/* Null filenames do not exist */
return -1;
}
VMS_saved_memname = (char *)arg;
/* archive path name must be in VMS format */
vms_archive = (char *) vmsify(archive, 0);
/* For comparison, delete .obj from arg name. */
status = lbr$ini_control(&VMS_lib_idx, &func, &type, 0);
p = strrchr (VMS_saved_memname, '.');
if (p)
*p = '\0';
if (!$VMS_STATUS_SUCCESS(status))
{
ON(error, NILF, _("lbr$ini_control() failed with status = %d"), status);
return -2;
}
libdesc.dsc$a_pointer = vms_archive;
libdesc.dsc$w_length = strlen(vms_archive);
status = lbr$open(&VMS_lib_idx, &libdesc, 0, NULL, 0, NULL, 0);
if (!$VMS_STATUS_SUCCESS(status))
{
/* TODO: A library format failure could mean that this is a file
generated by the GNU AR utility and in that case, we need to
take the UNIX codepath. This will also take a change to the
GNV AR wrapper program. */
switch (status)
{
case RMS$_FNF:
/* Archive does not exist */
return -1;
default:
#ifndef TEST
OSN(error, NILF,
_("unable to open library '%s' to lookup member status %d"),
archive, status);
#endif
/* For library format errors, specification says to return -2 */
return -2;
}
}
VMS_function = function;
VMS_member_date = (time_t) -1;
lbr$get_index (&VMS_lib_idx, &index, VMS_get_member_info, 0);
/* Clear the return status, as we are supposed to stop calling the
callback function if it becomes non-zero, and this is a static
variable. */
VMS_function_ret = 0;
/* Undo the damage. */
if (p)
*p = '.';
status = lbr$get_index(&VMS_lib_idx, &index, VMS_get_member_info, NULL, 0);
lbr$close (&VMS_lib_idx);
lbr$close(&VMS_lib_idx);
return VMS_member_date > 0 ? VMS_member_date : 0;
/* Unless a failure occurred in the lbr$ routines, return the
the status from the 'function' routine. */
if ($VMS_STATUS_SUCCESS(status))
{
return VMS_function_ret;
}
/* This must be something wrong with the library and an error
message should already have been printed. */
return -2;
}
#else /* !VMS */
@@ -251,10 +331,10 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
#endif
#ifndef WINDOWS32
# ifndef __BEOS__
# if !defined (__ANDROID__) && !defined (__BEOS__)
# include <ar.h>
# else
/* BeOS 5 doesn't have <ar.h> but has archives in the same format
/* These platforms don't have <ar.h> but have archives in the same format
* as many other Unices. This was taken from GNU binutils for BeOS.
*/
# define ARMAG "!<arch>\n" /* String that begins an archive file. */
@@ -340,7 +420,8 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
#ifdef SARMAG
{
char buf[SARMAG];
register int nread = read (desc, buf, SARMAG);
int nread;
EINTRLOOP (nread, read (desc, buf, SARMAG));
if (nread != SARMAG || memcmp (buf, ARMAG, SARMAG))
{
(void) close (desc);
@@ -350,8 +431,8 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
#else
#ifdef AIAMAG
{
register int nread = read (desc, &fl_header, FL_HSZ);
int nread;
EINTRLOOP (nread, read (desc, &fl_header, FL_HSZ));
if (nread != FL_HSZ)
{
(void) close (desc);
@@ -362,17 +443,20 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
re-read the header into the "big" structure. */
if (!memcmp (fl_header.fl_magic, AIAMAGBIG, SAIAMAG))
{
off_t o;
big_archive = 1;
/* seek back to beginning of archive */
if (lseek (desc, 0, 0) < 0)
EINTRLOOP (o, lseek (desc, 0, 0));
if (o < 0)
{
(void) close (desc);
return -2;
}
/* re-read the header into the "big" structure */
nread = read (desc, &fl_header_big, FL_HSZ_BIG);
EINTRLOOP (nread, read (desc, &fl_header_big, FL_HSZ_BIG));
if (nread != FL_HSZ_BIG)
{
(void) close (desc);
@@ -395,7 +479,8 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
#else
unsigned short int buf;
#endif
register int nread = read (desc, &buf, sizeof (buf));
int nread;
EINTRLOOP (nread, read (desc, &buf, sizeof (buf)));
if (nread != sizeof (buf) || buf != ARMAG)
{
(void) close (desc);
@@ -462,10 +547,12 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
int long_name = 0;
#endif
long int eltsize;
int eltmode;
unsigned int eltmode;
long int fnval;
off_t o;
if (lseek (desc, member_offset, 0) < 0)
EINTRLOOP (o, lseek (desc, member_offset, 0));
if (o < 0)
{
(void) close (desc);
return -2;
@@ -477,8 +564,8 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
#ifdef AIAMAGBIG
if (big_archive)
{
nread = read (desc, &member_header_big,
AR_MEMHDR_SZ(member_header_big) );
EINTRLOOP (nread, read (desc, &member_header_big,
AR_MEMHDR_SZ(member_header_big)));
if (nread != AR_MEMHDR_SZ(member_header_big))
{
@@ -487,7 +574,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
}
sscanf (member_header_big.ar_namlen, "%4d", &name_len);
nread = read (desc, name, name_len);
EINTRLOOP (nread, read (desc, name, name_len));
if (nread != name_len)
{
@@ -509,8 +596,8 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
else
#endif
{
nread = read (desc, &member_header,
AR_MEMHDR_SZ(member_header) );
EINTRLOOP (nread, read (desc, &member_header,
AR_MEMHDR_SZ(member_header)));
if (nread != AR_MEMHDR_SZ(member_header))
{
@@ -519,7 +606,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
}
sscanf (member_header.ar_namlen, "%4d", &name_len);
nread = read (desc, name, name_len);
EINTRLOOP (nread, read (desc, name, name_len));
if (nread != name_len)
{
@@ -547,7 +634,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
eltmode, arg);
#else /* Not AIAMAG. */
nread = read (desc, &member_header, AR_HDR_SIZE);
EINTRLOOP (nread, read (desc, &member_header, AR_HDR_SIZE));
if (nread == 0)
/* No data left means end of file; that is OK. */
break;
@@ -616,7 +703,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
int namesize = atoi (name + 3);
name = alloca (namesize + 1);
nread = read (desc, name, namesize);
EINTRLOOP (nread, read (desc, name, namesize));
if (nread != namesize)
{
close (desc);
@@ -687,7 +774,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
char *limit;
namemap = alloca (eltsize);
nread = read (desc, namemap, eltsize);
EINTRLOOP (nread, read (desc, namemap, eltsize));
if (nread != eltsize)
{
(void) close (desc);
@@ -751,9 +838,32 @@ ar_name_equal (const char *name, const char *mem, int truncated)
#endif /* !__hpux && !cray */
#endif /* !AIAMAG */
}
#endif /* !VMS */
return !strcmp (name, mem);
#else
/* VMS members do not have suffixes, but the filenames usually
have.
Do we need to strip VMS disk/directory format paths?
Most VMS compilers etc. by default are case insensitive
but produce uppercase external names, incl. module names.
However the VMS librarian (ar) and the linker by default
are case sensitive: they take what they get, usually
uppercase names. So for the non-default settings of the
compilers etc. there is a need to have a case sensitive
mode. */
{
int len;
len = strlen(mem);
int match;
char *dot;
if ((dot=strrchr(name,'.')))
match = (len == dot - name) && !strncasecmp(name, mem, len);
else
match = !strcasecmp (name, mem);
return match;
}
#endif /* !VMS */
}
#ifndef VMS
@@ -762,7 +872,7 @@ static long int
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,
int mode UNUSED, const void *name)
unsigned int mode UNUSED, const void *name)
{
if (!ar_name_equal (name, mem, truncated))
return 0;
@@ -782,7 +892,8 @@ ar_member_touch (const char *arname, const char *memname)
long int pos = ar_scan (arname, ar_member_pos, memname);
int fd;
struct ar_hdr ar_hdr;
int i;
off_t o;
int r;
unsigned int ui;
struct stat statbuf;
@@ -791,28 +902,32 @@ ar_member_touch (const char *arname, const char *memname)
if (!pos)
return 1;
fd = open (arname, O_RDWR, 0666);
EINTRLOOP (fd, open (arname, O_RDWR, 0666));
if (fd < 0)
return -3;
/* Read in this member's header */
if (lseek (fd, pos, 0) < 0)
EINTRLOOP (o, lseek (fd, pos, 0));
if (o < 0)
goto lose;
if (AR_HDR_SIZE != read (fd, &ar_hdr, AR_HDR_SIZE))
EINTRLOOP (r, read (fd, &ar_hdr, AR_HDR_SIZE));
if (r != AR_HDR_SIZE)
goto lose;
/* Write back the header, thus touching the archive file. */
if (lseek (fd, pos, 0) < 0)
EINTRLOOP (o, lseek (fd, pos, 0));
if (o < 0)
goto lose;
if (AR_HDR_SIZE != write (fd, &ar_hdr, AR_HDR_SIZE))
EINTRLOOP (r, write (fd, &ar_hdr, AR_HDR_SIZE));
if (r != AR_HDR_SIZE)
goto lose;
/* The file's mtime is the time we we want. */
EINTRLOOP (i, fstat (fd, &statbuf));
if (i < 0)
EINTRLOOP (r, fstat (fd, &statbuf));
if (r < 0)
goto lose;
#if defined(ARFMAG) || defined(ARFZMAG) || defined(AIAMAG) || defined(WINDOWS32)
/* Advance member's time to that time */
for (ui = 0; ui < sizeof ar_hdr.ar_date; ui++)
ar_hdr.ar_date[ui] = ' ';
sprintf (TOCHAR (ar_hdr.ar_date), "%ld", (long int) statbuf.st_mtime);
sprintf (TOCHAR (ar_hdr.ar_date), "%lu", (long unsigned) statbuf.st_mtime);
#ifdef AIAMAG
ar_hdr.ar_date[strlen (ar_hdr.ar_date)] = ' ';
#endif
@@ -820,17 +935,19 @@ ar_member_touch (const char *arname, const char *memname)
ar_hdr.ar_date = statbuf.st_mtime;
#endif
/* Write back this member's header */
if (lseek (fd, pos, 0) < 0)
EINTRLOOP (o, lseek (fd, pos, 0));
if (o < 0)
goto lose;
if (AR_HDR_SIZE != write (fd, &ar_hdr, AR_HDR_SIZE))
EINTRLOOP (r, write (fd, &ar_hdr, AR_HDR_SIZE));
if (r != AR_HDR_SIZE)
goto lose;
close (fd);
return 0;
lose:
i = errno;
r = errno;
close (fd);
errno = i;
errno = r;
return -3;
}
#endif
@@ -840,7 +957,8 @@ ar_member_touch (const char *arname, const char *memname)
long int
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, int mode, const void *arg)
long int date, int uid, int gid, unsigned int mode,
const void *arg)
{
extern char *ctime ();

View File

@@ -2,7 +2,7 @@
# Shell script to build GNU Make in the absence of any 'make' program.
# @configure_input@
# Copyright (C) 1993-2013 Free Software Foundation, Inc.
# Copyright (C) 1993-2016 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
@@ -22,11 +22,11 @@
srcdir='@srcdir@'
CC='@CC@'
CFLAGS='@CFLAGS@'
CFLAGS='@CFLAGS@ @GUILE_CFLAGS@'
CPPFLAGS='@CPPFLAGS@'
LDFLAGS='@LDFLAGS@'
LDFLAGS='@AM_LDFLAGS@ @LDFLAGS@'
ALLOCA='@ALLOCA@'
LOADLIBES='@LIBS@ @LIBINTL@'
LOADLIBES='@LIBS@ @GUILE_LIBS@ @LIBINTL@'
eval extras=\'@LIBOBJS@\'
REMOTE='@REMOTE@'
GLOBLIB='@GLOBLIB@'
@@ -46,7 +46,7 @@ includedir=${prefix}/include
localedir=${prefix}/share/locale
aliaspath=${localedir}${PATH_SEPARATOR}.
defines="-DALIASPATH=\"${aliaspath}\" -DLOCALEDIR=\"${localedir}\" -DLIBDIR=\"${libdir}\" -DINCLUDEDIR=\"${includedir}\""' @DEFS@'
defines="-DLOCALEDIR=\"${localedir}\" -DLIBDIR=\"${libdir}\" -DINCLUDEDIR=\"${includedir}\""' @DEFS@'
# Exit as soon as any command fails.
set -e

493
build_w32.bat Normal file → Executable file
View File

@@ -1,5 +1,5 @@
@echo off
rem Copyright (C) 1996-2013 Free Software Foundation, Inc.
rem Copyright (C) 1996-2016 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
@@ -15,292 +15,217 @@ 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/>.
if "%1" == "-h" GoTo Usage
if "%1" == "--help" GoTo Usage
if not exist config.h.W32.template GoTo NotSCM
sed -n "s/^AC_INIT(\[GNU make\],\[\([^]]\+\)\].*/s,%%VERSION%%,\1,g/p" configure.ac > config.h.W32.sed
echo s,%%PACKAGE%%,make,g >> config.h.W32.sed
sed -f config.h.W32.sed config.h.W32.template > config.h.W32
echo static const char *const GUILE_module_defn = ^" \> gmk-default.h
sed -e "s/;.*//" -e "/^[ \t]*$/d" -e "s/\"/\\\\\"/g" -e "s/$/ \\/" gmk-default.scm >> gmk-default.h
echo ^";>> gmk-default.h
:NotSCM
copy config.h.W32 config.h
call :Reset
if "%1" == "-h" goto Usage
if "%1" == "--help" goto Usage
set MAKE=gnumake
set GUILE=Y
set COMPILER=msvc
rem Guile configuration
set GUILECFLAGS=
set GUILELIBS=
set GUILESRC=
set NOGUILE=
set OPT=-O2
set COMPILER=
set PKGMSC=
:ParseSW
if "%1" == "--debug" GoTo SetOpt
if "%1" == "--without-guile" GoTo NoGuile
if "%1" == "gcc" GoTo SetCC
if "%1" == "" GoTo ChkGuile
:SetOpt
set OPT=-O0
if "%1" == "--debug" goto SetDebug
if "%1" == "--without-guile" goto NoGuile
if "%1" == "gcc" goto SetCC
if "%1" == "" goto DoneSW
:SetDebug
set DEBUG=Y
shift
GoTo ParseSW
goto ParseSW
:NoGuile
set NOGUILE=Y
echo "Building without Guile"
set GUILE=N
echo Building without Guile
shift
GoTo ParseSW
goto ParseSW
:SetCC
set COMPILER=gcc
echo "Building with GCC"
echo Building with GCC
shift
GoTo ParseSW
rem Build with Guile is supported only on NT and later versions
:ChkGuile
if "%NOGUILE%" == "Y" GoTo GuileDone
if not "%OS%" == "Windows_NT" GoTo NoGuile
pkg-config --help > guile.tmp 2> NUL
if ERRORLEVEL 1 GoTo NoPkgCfg
echo "Checking for Guile 2.0"
if not "%COMPILER%" == "gcc" set PKGMSC=--msvc-syntax
pkg-config --cflags --short-errors "guile-2.0" > guile.tmp
if not ERRORLEVEL 1 set /P GUILECFLAGS= < guile.tmp
pkg-config --libs --static --short-errors %PKGMSC% "guile-2.0" > guile.tmp
if not ERRORLEVEL 1 set /P GUILELIBS= < guile.tmp
if not "%GUILECFLAGS%" == "" GoTo GuileDone
echo "Checking for Guile 1.8"
pkg-config --cflags --short-errors "guile-1.8" > guile.tmp
if not ERRORLEVEL 1 set /P GUILECFLAGS= < guile.tmp
pkg-config --libs --static --short-errors %PKGMSC% "guile-1.8" > guile.tmp
if not ERRORLEVEL 1 set /P GUILELIBS= < guile.tmp
if not "%GUILECFLAGS%" == "" GoTo GuileDone
echo "No Guile found, building without Guile"
GoTo GuileDone
:NoPkgCfg
echo "pkg-config not found, building without Guile"
:GuileDone
if not "%GUILECFLAGS%" == "" echo "Guile found, building with Guile"
if not "%GUILECFLAGS%" == "" set GUILESRC=guile.c
if not "%GUILECFLAGS%" == "" set GUILECFLAGS=%GUILECFLAGS% -DHAVE_GUILE
if "%COMPILER%" == "gcc" if "%OPT%" == "-O0" echo "Building without compiler optimizations"
cd w32\subproc
echo.
echo "Creating the subproc library"
%ComSpec% /c build.bat
cd ..\..
goto ParseSW
if exist link.dbg del link.dbg
if exist link.rel del link.rel
rem Build with Guile is supported only on NT and later versions
:DoneSW
echo.
echo "Creating GNU Make for Windows 9X/NT/2K/XP/Vista/7/8"
if "%COMPILER%" == "gcc" GoTo GCCBuild
set make=gnumake
echo Creating GNU Make for Windows 9X/NT/2K/XP/Vista/7/8
if "%DEBUG%" == "Y" echo Building without compiler optimizations
if "%COMPILER%" == "gcc" goto GccBuild
set OUTDIR=.\WinRel
set "OPTS=/O2 /D NDEBUG"
set LINKOPTS=
if "%DEBUG%" == "Y" set OUTDIR=.\WinDebug
if "%DEBUG%" == "Y" set "OPTS=/Zi /Od /D _DEBUG"
if "%DEBUG%" == "Y" set LINKOPTS=/DEBUG
call :Build
goto Done
:GccBuild
set OUTDIR=.\GccRel
set OPTS=-O2
if "%DEBUG%" == "Y" set OPTS=-O0
if "%DEBUG%" == "Y" set OUTDIR=.\GccDebug
call :Build
goto Done
:Done
call :Reset
goto :EOF
:Build
:: Clean the directory if it exists
if exist %OUTDIR%\nul rmdir /S /Q %OUTDIR%
:: Recreate it
mkdir %OUTDIR%
mkdir %OUTDIR%\glob
mkdir %OUTDIR%\w32
mkdir %OUTDIR%\w32\compat
mkdir %OUTDIR%\w32\subproc
if "%GUILE%" == "Y" call :ChkGuile
echo.
echo Compiling %OUTDIR% version
if exist config.h.W32.template call :ConfigSCM
copy config.h.W32 %OUTDIR%\config.h
call :Compile ar
call :Compile arscan
call :Compile commands
call :Compile default
call :Compile dir
call :Compile expand
call :Compile file
call :Compile function
call :Compile getloadavg
call :Compile getopt
call :Compile getopt1
call :Compile glob\fnmatch
call :Compile glob\glob
call :Compile guile GUILE
call :Compile hash
call :Compile implicit
call :Compile job
call :Compile load
call :Compile loadapi
call :Compile main GUILE
call :Compile misc
call :Compile output
call :Compile read
call :Compile remake
call :Compile remote-stub
call :Compile rule
call :Compile signame
call :Compile strcache
call :Compile variable
call :Compile version
call :Compile vpath
call :Compile w32\compat\posixfcn
call :Compile w32\pathstuff
call :Compile w32\subproc\misc
call :Compile w32\subproc\sub_proc
call :Compile w32\subproc\w32err
call :Compile w32\w32os
if not "%COMPILER%" == "gcc" call :Compile w32\compat\dirent
call :Link
echo.
if not exist %OUTDIR%\%MAKE%.exe echo %OUTDIR% build FAILED!
if exist %OUTDIR%\%MAKE%.exe echo %OUTDIR% build succeeded.
goto :EOF
:Compile
set EXTRAS=
if "%2" == "GUILE" set "EXTRAS=%GUILECFLAGS%"
if "%COMPILER%" == "gcc" goto GccCompile
:: MSVC Compile
echo on
if not exist .\WinDebug\nul mkdir .\WinDebug
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D TIVOLI /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c variable.c
echo WinDebug\variable.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c rule.c
echo WinDebug\rule.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c remote-stub.c
echo WinDebug\remote-stub.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c commands.c
echo WinDebug\commands.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c file.c
echo WinDebug\file.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c getloadavg.c
echo WinDebug\getloadavg.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c default.c
echo WinDebug\default.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c signame.c
echo WinDebug\signame.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c expand.c
echo WinDebug\expand.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c dir.c
echo WinDebug\dir.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od %GUILECFLAGS% /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c main.c
echo WinDebug\main.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c getopt1.c
echo WinDebug\getopt1.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c job.c
echo WinDebug\job.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c output.c
echo WinDebug\output.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c read.c
echo WinDebug\read.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c version.c
echo WinDebug\version.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c getopt.c
echo WinDebug\getopt.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c arscan.c
echo WinDebug\arscan.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c hash.c
echo WinDebug\hash.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c strcache.c
echo WinDebug\strcache.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c remake.c
echo WinDebug\remake.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c misc.c
echo WinDebug\misc.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c ar.c
echo WinDebug\ar.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c function.c
echo WinDebug\function.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c vpath.c
echo WinDebug\vpath.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c implicit.c
echo WinDebug\implicit.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c loadapi.c
echo WinDebug\loadapi.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c load.c
echo WinDebug\load.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c .\w32\compat\dirent.c
echo WinDebug\dirent.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c .\w32\compat\posixfcn.c
echo WinDebug\posixfcn.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c .\glob\glob.c
echo WinDebug\glob.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c .\glob\fnmatch.c
echo WinDebug\fnmatch.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c .\w32\pathstuff.c
echo WinDebug\pathstuff.obj >>link.dbg
if "%GUILESRC%" == "" GoTo LinkDbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od %GUILECFLAGS%% /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c guile.c
echo WinDebug\guile.obj >>link.dbg
:LinkDbg
echo off
echo "Linking WinDebug/%make%.exe"
rem link.exe %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 w32\subproc\windebug\subproc.lib /NOLOGO /SUBSYSTEM:console /INCREMENTAL:yes /PDB:.\WinDebug/%make%.pdb /DEBUG /OUT:.\WinDebug/%make%.exe .\WinDebug/variable.obj .\WinDebug/rule.obj .\WinDebug/remote-stub.obj .\WinDebug/commands.obj .\WinDebug/file.obj .\WinDebug/getloadavg.obj .\WinDebug/default.obj .\WinDebug/signame.obj .\WinDebug/expand.obj .\WinDebug/dir.obj .\WinDebug/main.obj .\WinDebug/getopt1.obj .\WinDebug/job.obj .\WinDebug/output.obj .\WinDebug/read.obj .\WinDebug/version.obj .\WinDebug/getopt.obj .\WinDebug/arscan.obj .\WinDebug/remake.obj .\WinDebug/hash.obj .\WinDebug/strcache.obj .\WinDebug/misc.obj .\WinDebug/ar.obj .\WinDebug/function.obj .\WinDebug/vpath.obj .\WinDebug/implicit.obj .\WinDebug/dirent.obj .\WinDebug/glob.obj .\WinDebug/fnmatch.obj .\WinDebug/pathstuff.obj
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 w32\subproc\windebug\subproc.lib >>link.dbg
link.exe /NOLOGO /SUBSYSTEM:console /INCREMENTAL:yes /PDB:.\WinDebug/%make%.pdb /DEBUG /OUT:.\WinDebug/%make%.exe @link.dbg
if not exist .\WinDebug/%make%.exe echo "WinDebug build failed"
if exist .\WinDebug/%make%.exe echo "WinDebug build succeeded!"
if not exist .\WinRel\nul mkdir .\WinRel
echo on
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /D TIVOLI /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c variable.c
echo WinRel\variable.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c rule.c
echo WinRel\rule.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c remote-stub.c
echo WinRel\remote-stub.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c commands.c
echo WinRel\commands.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c file.c
echo WinRel\file.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c getloadavg.c
echo WinRel\getloadavg.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c default.c
echo WinRel\default.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c signame.c
echo WinRel\signame.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c expand.c
echo WinRel\expand.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c dir.c
echo WinRel\dir.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 %GUILECFLAGS% /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c main.c
echo WinRel\main.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c getopt1.c
echo WinRel\getopt1.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c job.c
echo WinRel\job.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c output.c
echo WinRel\output.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c read.c
echo WinRel\read.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c version.c
echo WinRel\version.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c getopt.c
echo WinRel\getopt.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c arscan.c
echo WinRel\arscan.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c remake.c
echo WinRel\remake.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c hash.c
echo WinRel\hash.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c strcache.c
echo WinRel\strcache.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c misc.c
echo WinRel\misc.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c ar.c
echo WinRel\ar.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c function.c
echo WinRel\function.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c vpath.c
echo WinRel\vpath.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c implicit.c
echo WinRel\implicit.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c loadapi.c
echo WinRel\loadapi.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c load.c
echo WinRel\load.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c .\w32\compat\dirent.c
echo WinRel\dirent.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c .\w32\compat\posixfcn.c
echo WinRel\posixfcn.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c .\glob\glob.c
echo WinRel\glob.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c .\glob\fnmatch.c
echo WinRel\fnmatch.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c .\w32\pathstuff.c
echo WinRel\pathstuff.obj >>link.rel
if "%GUILESRC%" == "" GoTo LinkRel
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c guile.c
echo WinRel\guile.obj >>link.rel
:LinkRel
echo off
echo "Linking WinRel/%make%.exe"
rem link.exe %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 w32\subproc\winrel\subproc.lib /NOLOGO /SUBSYSTEM:console /INCREMENTAL:no /PDB:.\WinRel/%make%.pdb /OUT:.\WinRel/%make%.exe .\WinRel/variable.obj .\WinRel/rule.obj .\WinRel/remote-stub.obj .\WinRel/commands.obj .\WinRel/file.obj .\WinRel/getloadavg.obj .\WinRel/default.obj .\WinRel/signame.obj .\WinRel/expand.obj .\WinRel/dir.obj .\WinRel/main.obj .\WinRel/getopt1.obj .\WinRel/job.obj .\WinRel/output.obj .\WinRel/read.obj .\WinRel/version.obj .\WinRel/getopt.obj .\WinRel/arscan.obj .\WinRel/remake.obj .\WinRel/misc.obj .\WinRel/hash.obj .\WinRel/strcache.obj .\WinRel/ar.obj .\WinRel/function.obj .\WinRel/vpath.obj .\WinRel/implicit.obj .\WinRel/dirent.obj .\WinRel/glob.obj .\WinRel/fnmatch.obj .\WinRel/pathstuff.obj
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 w32\subproc\winrel\subproc.lib >>link.rel
link.exe /NOLOGO /SUBSYSTEM:console /INCREMENTAL:no /PDB:.\WinRel/%make%.pdb /OUT:.\WinRel/%make%.exe @link.rel
if not exist .\WinRel/%make%.exe echo "WinRel build failed"
if exist .\WinRel/%make%.exe echo "WinRel build succeeded!"
set make=
GoTo BuildEnd
:GCCBuild
echo on
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c variable.c
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c rule.c
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c remote-stub.c
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c commands.c
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c file.c
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c getloadavg.c
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c default.c
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c signame.c
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c expand.c
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c dir.c
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H %GUILECFLAGS% -c main.c
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c getopt1.c
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c job.c
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c output.c
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c read.c
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c version.c
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c getopt.c
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c arscan.c
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c remake.c
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c hash.c
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c strcache.c
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c misc.c
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c ar.c
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c function.c
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c vpath.c
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c implicit.c
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c loadapi.c
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c load.c
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c ./glob/glob.c -o glob.o
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c ./glob/fnmatch.c -o fnmatch.o
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c ./w32/pathstuff.c -o pathstuff.o
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c ./w32/compat/posixfcn.c -o posixfcn.o
cl.exe /nologo /MT /W4 /EHsc %OPTS% /I %OUTDIR% /I . /I glob /I w32/include /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR%OUTDIR% /Fp%OUTDIR%\%MAKE%.pch /Fo%OUTDIR%\%1.obj /Fd%OUTDIR%\%MAKE%.pdb %EXTRAS% /c %1.c
@echo off
set GUILEOBJ=
if "%GUILESRC%" == "" GoTo LinkGCC
set GUILEOBJ=guile.o
echo %OUTDIR%\%1.obj >>%OUTDIR%\link.sc
goto :EOF
:GccCompile
:: GCC Compile
echo on
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% %GUILECFLAGS% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c guile.c
:LinkGCC
gcc -mthreads -Wall -std=gnu99 -gdwarf-2 -g3 %OPTS% -I%OUTDIR% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H %EXTRAS% -o %OUTDIR%\%1.o -c %1.c
@echo off
Rem The version NN of libgnumake-NN.dll.a should be bumped whenever
Rem the API changes in binary-incompatible manner.
@echo on
gcc -mthreads -gdwarf-2 -g3 -o gnumake.exe variable.o rule.o remote-stub.o commands.o file.o getloadavg.o default.o signame.o expand.o dir.o main.o getopt1.o %GUILEOBJ% job.o output.o read.o version.o getopt.o arscan.o remake.o misc.o hash.o strcache.o ar.o function.o vpath.o implicit.o loadapi.o load.o glob.o fnmatch.o pathstuff.o posixfcn.o w32_misc.o sub_proc.o w32err.o %GUILELIBS% -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -luuid -lodbc32 -lodbccp32 -Wl,--out-implib=libgnumake-1.dll.a
@GoTo BuildEnd
goto :EOF
:Link
echo Linking %OUTDIR%/%MAKE%.exe
if "%COMPILER%" == "gcc" goto GccLink
:: 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:%OUTDIR%\%MAKE%.pdb %LINKOPTS% /OUT:%OUTDIR%\%MAKE%.exe @%OUTDIR%\link.sc
@echo off
goto :EOF
:GccLink
:: GCC Link
echo on
gcc -mthreads -gdwarf-2 -g3 -o %OUTDIR%\%MAKE%.exe %OUTDIR%\variable.o %OUTDIR%\rule.o %OUTDIR%\remote-stub.o %OUTDIR%\commands.o %OUTDIR%\file.o %OUTDIR%\getloadavg.o %OUTDIR%\default.o %OUTDIR%\signame.o %OUTDIR%\expand.o %OUTDIR%\dir.o %OUTDIR%\main.o %OUTDIR%\getopt1.o %OUTDIR%\guile.o %OUTDIR%\job.o %OUTDIR%\output.o %OUTDIR%\read.o %OUTDIR%\version.o %OUTDIR%\getopt.o %OUTDIR%\arscan.o %OUTDIR%\remake.o %OUTDIR%\misc.o %OUTDIR%\hash.o %OUTDIR%\strcache.o %OUTDIR%\ar.o %OUTDIR%\function.o %OUTDIR%\vpath.o %OUTDIR%\implicit.o %OUTDIR%\loadapi.o %OUTDIR%\load.o %OUTDIR%\glob\glob.o %OUTDIR%\glob\fnmatch.o %OUTDIR%\w32\pathstuff.o %OUTDIR%\w32\compat\posixfcn.o %OUTDIR%\w32\w32os.o %OUTDIR%\w32\subproc\misc.o %OUTDIR%\w32\subproc\sub_proc.o %OUTDIR%\w32\subproc\w32err.o %GUILELIBS% -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -luuid -lodbc32 -lodbccp32 -Wl,--out-implib=%OUTDIR%\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%\config.h.W32.sed
echo s,%%PACKAGE%%,make,g >> %OUTDIR%\config.h.W32.sed
sed -f %OUTDIR%\config.h.W32.sed config.h.W32.template > config.h.W32
echo static const char *const GUILE_module_defn = ^" \> gmk-default.h
sed -e "s/;.*//" -e "/^[ \t]*$/d" -e "s/\"/\\\\\"/g" -e "s/$/ \\\/" gmk-default.scm >> gmk-default.h
echo ^";>> gmk-default.h
goto :EOF
:ChkGuile
if not "%OS%" == "Windows_NT" goto NoGuile
pkg-config --help > %OUTDIR%\guile.tmp 2> NUL
if ERRORLEVEL 1 goto NoPkgCfg
echo Checking for Guile 2.0
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
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
pkg-config --libs --static --short-errors %PKGMSC% "guile-1.8" > %OUTDIR%\guile.tmp
if not ERRORLEVEL 1 set /P GUILELIBS= < %OUTDIR%\guile.tmp
if not "%GUILECFLAGS%" == "" goto GuileDone
echo No Guile found, building without Guile
goto GuileDone
:NoPkgCfg
echo pkg-config not found, building without Guile
:GuileDone
if "%GUILECFLAGS%" == "" goto :EOF
echo Guile found, building with Guile
set "GUILECFLAGS=%GUILECFLAGS% -DHAVE_GUILE"
goto :EOF
:Usage
echo Usage: %0 [options] [gcc]
echo Options:
@@ -308,14 +233,18 @@ echo. --debug For GCC only, make a debug build
echo. (MSVC build always makes both debug and release)
echo. --without-guile Do not compile Guile support even if found
echo. --help Display these instructions and exit
:BuildEnd
@echo off
set GUILEOBJ=
set GUILESRC=
set GUILELIBS=
set GUILECFLAGS=
set PKGMSC=
set OPT=
goto :EOF
:Reset
set COMPILER=
set DEBUG=
set GUILE=
set GUILECFLAGS=
set GUILELIBS=
set LINKOPTS=
set MAKE=
set NOGUILE=
echo on
set OPTS=
set OUTDIR=
set PKGMSC=
goto :EOF

View File

@@ -1,5 +1,5 @@
/* Command processing for GNU Make.
Copyright (C) 1988-2013 Free Software Foundation, Inc.
Copyright (C) 1988-2016 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,11 +14,9 @@ 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/>. */
#include <dlfcn.h>
#include "makeint.h"
#include "dep.h"
#include "filedef.h"
#include "dep.h"
#include "variable.h"
#include "job.h"
#include "commands.h"
@@ -28,13 +26,11 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#endif
#if VMS
# define FILE_LIST_SEPARATOR ','
# define FILE_LIST_SEPARATOR (vms_comma_separator ? ',' : ' ')
#else
# define FILE_LIST_SEPARATOR ' '
#endif
int remote_kill (int id, int sig);
#ifndef HAVE_UNISTD_H
int getpid ();
#endif
@@ -403,7 +399,7 @@ chop_commands (struct commands *cmds)
CMDS->any_recurse flag. */
if (nlines > USHRT_MAX)
fatal (&cmds->fileinfo, _("Recipe has too many lines (%ud)"), nlines);
ON (fatal, &cmds->fileinfo, _("Recipe has too many lines (%ud)"), nlines);
cmds->ncommand_lines = nlines;
cmds->command_lines = lines;
@@ -413,10 +409,10 @@ chop_commands (struct commands *cmds)
for (idx = 0; idx < nlines; ++idx)
{
int flags = 0;
unsigned char flags = 0;
const char *p = lines[idx];
while (isblank (*p) || *p == '-' || *p == '@' || *p == '+')
while (ISBLANK (*p) || *p == '-' || *p == '@' || *p == '+')
switch (*(p++))
{
case '+':
@@ -453,7 +449,7 @@ execute_file_commands (struct file *file)
the commands are nothing but whitespace. */
for (p = file->cmds->commands; *p != '\0'; ++p)
if (!isspace ((unsigned char)*p) && *p != '-' && *p != '@')
if (!ISSPACE (*p) && *p != '-' && *p != '@' && *p != '+')
break;
if (*p == '\0')
{
@@ -587,7 +583,7 @@ fatal_error_signal (int sig)
if (sig == SIGQUIT)
/* We don't want to send ourselves SIGQUIT, because it will
cause a core dump. Just exit instead. */
exit (EXIT_FAILURE);
exit (MAKE_TROUBLE);
#endif
#ifdef WINDOWS32
@@ -627,11 +623,13 @@ delete_target (struct file *file, const char *on_behalf_of)
if (ar_member_date (file->name) != file_date)
{
if (on_behalf_of)
error (NILF, _("*** [%s] Archive member '%s' may be bogus; not deleted"),
on_behalf_of, file->name);
OSS (error, NILF,
_("*** [%s] Archive member '%s' may be bogus; not deleted"),
on_behalf_of, file->name);
else
error (NILF, _("*** Archive member '%s' may be bogus; not deleted"),
file->name);
OS (error, NILF,
_("*** Archive member '%s' may be bogus; not deleted"),
file->name);
}
return;
}
@@ -643,9 +641,10 @@ delete_target (struct file *file, const char *on_behalf_of)
&& FILE_TIMESTAMP_STAT_MODTIME (file->name, st) != file->last_mtime)
{
if (on_behalf_of)
error (NILF, _("*** [%s] Deleting file '%s'"), on_behalf_of, file->name);
OSS (error, NILF,
_("*** [%s] Deleting file '%s'"), on_behalf_of, file->name);
else
error (NILF, _("*** Deleting file '%s'"), file->name);
OS (error, NILF, _("*** Deleting file '%s'"), file->name);
if (unlink (file->name) < 0
&& errno != ENOENT) /* It disappeared; so what. */
perror_with_name ("unlink: ", file->name);

View File

@@ -1,5 +1,5 @@
/* Definition of data structures describing shell commands for GNU Make.
Copyright (C) 1988-2013 Free Software Foundation, Inc.
Copyright (C) 1988-2016 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
@@ -19,10 +19,10 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
struct commands
{
gmk_floc fileinfo; /* Where commands were defined. */
floc fileinfo; /* Where commands were defined. */
char *commands; /* Commands text. */
char **command_lines; /* Commands chopped up into lines. */
char *lines_flags; /* One set of flag bits for each line. */
unsigned char *lines_flags; /* One set of flag bits for each line. */
unsigned short ncommand_lines;/* Number of command lines. */
char recipe_prefix; /* Recipe prefix for this command set. */
unsigned int any_recurse:1; /* Nonzero if any 'lines_flags' elt has */
@@ -34,6 +34,7 @@ struct commands
#define COMMANDS_SILENT 2 /* Silent: @. */
#define COMMANDS_NOERROR 4 /* No errors: -. */
RETSIGTYPE 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);

View File

@@ -1,5 +1,5 @@
/* config.h -- hand-massaged for Amiga -*-C-*-
Copyright (C) 1995-2013 Free Software Foundation, Inc.
Copyright (C) 1995-2016 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
@@ -318,9 +318,18 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Define if you have the kstat library (-lkstat). */
/* #undef HAVE_LIBKSTAT */
/* Define to 1 if you have the `isatty' function. */
/* #undef HAVE_ISATTY */
/* Define to 1 if you have the `ttyname' function. */
/* #undef HAVE_TTYNAME */
/* Define if you have the sun library (-lsun). */
/* #undef HAVE_LIBSUN */
/* Output sync sypport */
#define NO_OUTPUT_SYNC
/* Define for Case Insensitve behavior */
#define HAVE_CASE_INSENSITIVE_FS

View File

@@ -1,6 +1,6 @@
/* config.h-vms. Generated by hand by Klaus Kämpf <kkaempf@rmi.de> -*-C-*-
Copyright (C) 1996-2013 Free Software Foundation, Inc.
Copyright (C) 1996-2016 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
@@ -18,6 +18,12 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* config.h. Generated automatically by configure. */
/* config.h.in. Generated automatically from configure.ac by autoheader. */
/* Pull in types.h here to get __CRTL_VER defined for old versions of the
compiler which don't define it. */
#ifdef __DECC
# include <types.h>
#endif
/* Define to 1 if on AIX 3.
System headers sometimes define this.
We just want to avoid a redefinition error message. */
@@ -356,6 +362,12 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Define to 1 if you have the sun library (-lsun). */
/* #undef HAVE_LIBSUN */
/* Define to 1 if you have the `isatty' function. */
/* #undef HAVE_ISATTY */
/* Define to 1 if you have the `ttyname' function. */
/* #undef HAVE_TTYNAME */
/* Use high resolution file timestamps if nonzero. */
#define FILE_TIMESTAMP_HI_RES 0
@@ -372,15 +384,9 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* #undef HAVE_VMSDIR_H */
/* #undef _DIRENT_HAVE_D_NAMLEN */
/* On older systems without 7.0 backport of CRTL the first one is defined */
#ifdef __CRTL_VER
# if __CRTL_VER < 70000000
# define HAVE_VMSDIR_H 1
# endif
#else
# if __VMS_VER < 70000000
# define HAVE_VMSDIR_H 1
# endif
/* On older systems without 7.0 backport of CRTL use non-VMS code for opendir() etc. */
#if __CRTL_VER < 70000000
# define HAVE_VMSDIR_H 1
#endif
#if defined(HAVE_VMSDIR_H) && defined(HAVE_DIRENT_H)
@@ -411,5 +417,16 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#define alloca(n) __ALLOCA(n)
#endif
/* Output sync sypport */
#define NO_OUTPUT_SYNC
/* Define to 1 to write even short single-line actions into a VMS/DCL command
file; this also enables exporting make environment variables into the
(sub-)process, which executes the action.
The usual make rules apply whether a shell variable - here a DCL symbol or
VMS logical [see CRTL getenv()] - is added to the make environment and
is exported. */
#define USE_DCL_COM_FILE 1
/* Build host information. */
#define MAKE_HOST "VMS"

View File

@@ -1,6 +1,6 @@
/* config.h.W32 -- hand-massaged config.h file for Windows builds -*-C-*-
Copyright (C) 1996-2013 Free Software Foundation, Inc.
Copyright (C) 1996-2016 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
@@ -292,6 +292,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 `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 'n_un.n_name' is a member of 'struct nlist'. */
/* #undef HAVE_STRUCT_NLIST_N_UN_N_NAME */
@@ -523,5 +530,3 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#ifdef HAVE_CYGWIN_SHELL
#undef BATCH_MODE_ONLY_SHELL
#endif
#define OUTPUT_SYNC

1
config/.gitignore vendored
View File

@@ -1,3 +1,4 @@
ar-lib
compile
config.guess
config.rpath

View File

@@ -33,7 +33,7 @@
* Makefile.am: New file.
Copyright (C) 2002-2013 Free Software Foundation, Inc.
Copyright (C) 2002-2016 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

View File

@@ -1,5 +1,5 @@
# -*-Makefile-*-, or close enough
# Copyright (C) 2002-2013 Free Software Foundation, Inc.
# Copyright (C) 2002-2016 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

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-2013 Free Software Foundation, Inc.
# Copyright (C) 1993-2016 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

View File

@@ -1,6 +1,6 @@
/* configh.dos -- hand-massaged config.h file for MS-DOS builds -*-C-*-
Copyright (C) 1994-2013 Free Software Foundation, Inc.
Copyright (C) 1994-2016 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
@@ -100,8 +100,8 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Define to the version of this package. */
#define PACKAGE_VERSION "%VERSION%"
/* Define to 1 if the C compiler supports function prototypes. */
#define PROTOTYPES 1
/* Output sync sypport */
#define NO_OUTPUT_SYNC
/* Version number of package */
#define VERSION "%VERSION%"

View File

@@ -1,6 +1,6 @@
# Process this file with autoconf to produce a configure script.
#
# Copyright (C) 1993-2013 Free Software Foundation, Inc.
# Copyright (C) 1993-2016 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,9 +16,9 @@
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>.
AC_INIT([GNU make],[3.99.91],[bug-make@gnu.org])
AC_INIT([GNU make],[4.2],[bug-make@gnu.org])
AC_PREREQ([2.62])
AC_PREREQ([2.69])
# Autoconf setup
AC_CONFIG_AUX_DIR([config])
@@ -26,9 +26,13 @@ AC_CONFIG_SRCDIR([vpath.c])
AC_CONFIG_HEADERS([config.h])
# Automake setup
AM_INIT_AUTOMAKE([1.11.1 silent-rules])
# We have to enable "foreign" because ChangeLog is auto-generated
# We cannot enable -Werror because gettext 0.18.1 has invalid content
# When we update gettext to 0.18.3 or better we can add it again.
AM_INIT_AUTOMAKE([1.15 foreign -Werror -Wall])
# Checks for programs.
AC_USE_SYSTEM_EXTENSIONS
AC_PROG_CC
AC_PROG_INSTALL
AC_PROG_RANLIB
@@ -37,6 +41,9 @@ AC_CHECK_PROG([AR], [ar], [ar], [ar])
# Perl is needed for the test suite (only)
AC_CHECK_PROG([PERL], [perl], [perl], [perl])
# Needed for w32/Makefile.am
AM_PROG_AR
# Specialized system macros
AC_CANONICAL_HOST
AC_AIX
@@ -44,8 +51,7 @@ AC_ISC_POSIX
AC_MINIX
# Enable gettext, in "external" mode.
AM_GNU_GETTEXT_VERSION([0.18.1])
AM_GNU_GETTEXT_VERSION([0.19.4])
AM_GNU_GETTEXT([external])
# This test must come as early as possible after the compiler configuration
@@ -62,22 +68,18 @@ 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/time.h sys/timeb.h \
sys/select.h])
AM_PROG_CC_C_O
AC_C_CONST
AC_TYPE_SIGNAL
AC_TYPE_UID_T
AC_TYPE_PID_T
# Find some definition for uintmax_t
AC_CHECK_TYPE([uintmax_t],[],
[ uintmax_t="unsigned long"
AC_CHECK_TYPE([unsigned long long],[uintmax_t="unsigned long long"])
AC_DEFINE_UNQUOTED([uintmax_t], [$uintmax_t],
[Define uintmax_t if not defined in <stdint.h> or <inttypes.h>.])
])
AC_TYPE_OFF_T
AC_TYPE_SIZE_T
AC_TYPE_SSIZE_T
AC_TYPE_UINTMAX_T
# Find out whether our struct stat returns nanosecond resolution timestamps.
@@ -90,12 +92,12 @@ AC_CACHE_CHECK([whether to use high resolution file timestamps],
#if HAVE_INTTYPES_H
# include <inttypes.h>
#endif]],
[[char a[0x7fffffff < (uintmax_t)-1 >> 30 ? 1 : -1];]])],
[[char a[0x7fffffff < (uintmax_t)-1 >> 30 ? 1 : -1];]])],
[make_cv_file_timestamp_hi_res=yes])
])])
AS_IF([test "$make_cv_file_timestamp_hi_res" = yes], [val=1], [val=0])
AC_DEFINE_UNQUOTED([FILE_TIMESTAMP_HI_RES], [$val],
[Use high resolution file timestamps if nonzero.])
[Use high resolution file timestamps if nonzero.])
AS_IF([test "$make_cv_file_timestamp_hi_res" = yes],
[ # Solaris 2.5.1 needs -lposix4 to get the clock_gettime function.
@@ -103,7 +105,7 @@ AS_IF([test "$make_cv_file_timestamp_hi_res" = yes],
AC_SEARCH_LIBS([clock_gettime], [rt posix4])
AS_IF([test "$ac_cv_search_clock_gettime" != no],
[ AC_DEFINE([HAVE_CLOCK_GETTIME], [1],
[Define to 1 if you have the clock_gettime function.])
[Define to 1 if you have the clock_gettime function.])
])
])
@@ -117,24 +119,24 @@ AC_CACHE_CHECK([for standard gettimeofday], [ac_cv_func_gettimeofday],
[ac_cv_func_gettimeofday=no
AC_RUN_IFELSE([AC_LANG_SOURCE([[#include <sys/time.h>
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);
}]])],
[ac_cv_func_gettimeofday=yes],
[ac_cv_func_gettimeofday=no],
[ac_cv_func_gettimeofday="no (cross-compiling)"])])
{
struct timeval t; t.tv_sec = -1; t.tv_usec = -1;
exit (gettimeofday (&t, 0) != 0
|| t.tv_sec < 0 || t.tv_usec < 0);
}]])],
[ac_cv_func_gettimeofday=yes],
[ac_cv_func_gettimeofday=no],
[ac_cv_func_gettimeofday="no (cross-compiling)"])])
AS_IF([test "$ac_cv_func_gettimeofday" = yes],
[ AC_DEFINE([HAVE_GETTIMEOFDAY], [1],
[Define to 1 if you have a standard gettimeofday function])
[Define to 1 if you have a standard gettimeofday function])
])
AC_CHECK_FUNCS([strdup strndup mkstemp mktemp fdopen fileno \
dup dup2 getcwd realpath sigsetmask sigaction \
dup dup2 getcwd realpath sigsetmask sigaction \
getgroups seteuid setegid setlinebuf setreuid setregid \
getrlimit setrlimit setvbuf pipe strerror strsignal \
lstat readlink atexit])
lstat readlink atexit isatty ttyname pselect])
# We need to check declarations, not just existence, because on Tru64 this
# function is not declared without special flags, which themselves cause
@@ -142,6 +144,8 @@ AC_CHECK_FUNCS([strdup strndup mkstemp mktemp fdopen fileno \
AC_CHECK_DECLS([bsd_signal], [], [], [[#define _GNU_SOURCE 1
#include <signal.h>]])
AC_FUNC_FORK
AC_FUNC_SETVBUF_REVERSED
# Rumor has it that strcasecmp lives in -lresolv on some odd systems.
@@ -181,11 +185,11 @@ AC_FUNC_GETLOADAVG
AS_IF([test "$ac_cv_header_nlist_h" = yes],
[ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <nlist.h>]],
[[struct nlist nl;
[[struct nlist nl;
nl.n_name = "string";
return 0;]])],
[make_cv_nlist_struct=yes],
[make_cv_nlist_struct=no])
[make_cv_nlist_struct=yes],
[make_cv_nlist_struct=no])
AS_IF([test "$make_cv_nlist_struct" = yes],
[ AC_DEFINE([NLIST_STRUCT], [1],
[Define to 1 if struct nlist.n_name is a pointer rather than an array.])
@@ -243,8 +247,8 @@ 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])],
[AC_HELP_STRING([--with-customs=DIR],
[enable remote jobs via Customs--see README.customs])],
[ AS_CASE([$withval], [n|no], [:],
[make_cppflags="$CPPFLAGS"
AS_CASE([$withval],
@@ -254,7 +258,7 @@ AC_ARG_WITH([customs],
CF_NETLIBS
AC_CHECK_HEADER([customs.h],
[use_customs=true
REMOTE=cstms
REMOTE=cstms
LIBS="$LIBS -lcustoms" LDFLAGS="$make_ldflags"],
[with_customs=no
CPPFLAGS="$make_cppflags" make_badcust=yes])
@@ -268,7 +272,7 @@ AM_CONDITIONAL([USE_CUSTOMS], [test "$use_customs" = true])
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]),
[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.
@@ -317,20 +321,20 @@ AC_ARG_ENABLE([load],
[make_cv_load="$enableval" user_load="$enableval"],
[make_cv_load="yes"])
AS_CASE([/$ac_cv_func_dlopen/$ac_cv_func_dlsym/$ac_cv_func_dlerror/],
AS_CASE([/$ac_cv_have_decl_dlopen/$ac_cv_have_decl_dlsym/$ac_cv_have_decl_dlerror/],
[*/no/*], [make_cv_load=no])
# We might need -ldl
AS_IF([test "$make_cv_load" = yes], [
AC_SEARCH_LIBS([dlopen], [dl], [], [make_cv_load=])
])
AS_CASE([/$make_cv_load/$user_load/],
[*/no/*], [make_cv_load=no],
[AC_DEFINE(MAKE_LOAD, 1,
[Define to 1 to enable 'load' support in GNU make.])
])
# We might need -ldl
AS_IF([test "$make_cv_load" = yes], [
AC_SEARCH_LIBS([dlopen], [dl], [], [make_cv_load=])
])
# If we want load support, we might need to link with export-dynamic.
# See if we can figure it out. Unfortunately this is very difficult.
# For example passing -rdynamic to the SunPRO linker gives a warning
@@ -368,7 +372,7 @@ AC_CACHE_CHECK([for location of SCCS get command], [make_cv_path_sccs_get], [
[make_cv_path_sccs_get=get])
])
AC_DEFINE_UNQUOTED([SCCS_GET], ["$make_cv_path_sccs_get"],
[Define to the name of the SCCS 'get' command.])
[Define to the name of the SCCS 'get' command.])
ac_clean_files="$ac_clean_files s.conftest conftoast" # Remove these later.
AS_IF([(/usr/sccs/admin -n s.conftest || admin -n s.conftest) >/dev/null 2>&1 &&
@@ -428,7 +432,6 @@ AS_CASE([$host],
[AM_CONDITIONAL([WINDOWSENV], [true])
w32_target_env=yes
AC_DEFINE([WINDOWS32], [1], [Use platform specific coding])
AC_DEFINE([OUTPUT_SYNC], [1], [Support synchronized output])
AC_DEFINE([HAVE_DOS_PATHS], [1], [Use platform specific coding])
])
@@ -499,7 +502,7 @@ AS_IF([test "x$make_cv_load" = xno && test "x$user_load" = xyes],
# Specify what files are to be created.
AC_CONFIG_FILES([Makefile glob/Makefile po/Makefile.in config/Makefile \
doc/Makefile w32/Makefile])
doc/Makefile w32/Makefile tests/config-flags.pm])
# OK, do it!

View File

@@ -1,5 +1,5 @@
@echo off
rem Copyright (C) 1994-2013 Free Software Foundation, Inc.
rem Copyright (C) 1994-2016 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

View File

@@ -1,5 +1,5 @@
/* Debugging macros and interface.
Copyright (C) 1999-2013 Free Software Foundation, Inc.
Copyright (C) 1999-2016 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

172
default.c
View File

@@ -1,5 +1,5 @@
/* Data base of default implicit rules for GNU Make.
Copyright (C) 1988-2013 Free Software Foundation, Inc.
Copyright (C) 1988-2016 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
@@ -38,9 +38,11 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
static char default_suffixes[]
#ifdef VMS
= ".exe .olb .ln .obj .c .cxx .cc .pas .p .for .f .r .y .l .mar \
.s .ss .i .ii .mod .sym .def .h .info .dvi .tex .texinfo .texi .txinfo \
.w .ch .cweb .web .com .sh .elc .el";
/* VMS should include all UNIX/POSIX + some VMS extensions */
= ".out .exe .a .olb .hlb .tlb .mlb .ln .o .obj .c .cxx .cc .cpp .pas .p \
.for .f .r .y .l .ym .yl .mar .s .ss .i .ii .mod .sym .def .h .info .dvi \
.tex .texinfo .texi .txinfo .mem .hlp .brn .rnh .rno .rnt .rnx .w .ch .cweb \
.web .com .sh .elc .el";
#elif defined(__EMX__)
= ".out .a .ln .o .c .cc .C .cpp .p .f .F .m .r .y .l .ym .yl .s .S \
.mod .sym .def .h .info .dvi .tex .texinfo .texi .txinfo \
@@ -53,19 +55,35 @@ static char default_suffixes[]
static struct pspec default_pattern_rules[] =
{
#ifdef VMS
{ "(%)", "%",
"@if f$$search(\"$@\") .eqs. \"\" then $(LIBRARY)/CREATE/"
"$(or "
"$(patsubst %,TEXT,$(filter %.tlb %.TLB,$@)),"
"$(patsubst %,HELP,$(filter %.hlb %.HLB,$@)),"
"$(patsubst %,MACRO,$(filter %.mlb %.MLB,$@)),"
"$(and "
"$(patsubst %,SHARE,$(filter %.olb %.OLB,$@)),"
"$(patsubst %,SHARE,$(filter %.exe %.EXE,$<))),"
"OBJECT)"
" $@\n"
"$(AR) $(ARFLAGS) $@ $<" },
#else
{ "(%)", "%",
"$(AR) $(ARFLAGS) $@ $<" },
#endif
/* The X.out rules are only in BSD's default set because
BSD Make has no null-suffix rules, so 'foo.out' and
'foo' are the same thing. */
#ifdef VMS
{ "%.exe", "%",
"copy $< $@" },
#else
"$(CP) $< $@" },
#endif
{ "%.out", "%",
"@rm -f $@ \n cp $< $@" },
#endif
/* Syntax is "ctangle foo.w foo.ch foo.c". */
{ "%.c", "%.w %.ch",
"$(CTANGLE) $^ $@" },
@@ -78,18 +96,20 @@ static struct pspec default_pattern_rules[] =
static struct pspec default_terminal_rules[] =
{
#ifdef VMS
/* RCS. */
{ "%", "%$$5lv", /* Multinet style */
"if f$$search($@) .nes. \"\" then +$(CHECKOUT,v)" },
"if f$$search(\"$@\") .nes. \"\" then +$(CHECKOUT,v)" },
{ "%", "[.$$rcs]%$$5lv", /* Multinet style */
"if f$$search($@) .nes. \"\" then +$(CHECKOUT,v)" },
"if f$$search(\"$@\") .nes. \"\" then +$(CHECKOUT,v)" },
{ "%", "%_v", /* Normal style */
"if f$$search($@) .nes. \"\" then +$(CHECKOUT,v)" },
"if f$$search(\"$@\") .nes. \"\" then +$(CHECKOUT,v)" },
{ "%", "[.rcs]%_v", /* Normal style */
"if f$$search($@) .nes. \"\" then +$(CHECKOUT,v)" },
"if f$$search(\"$@\") .nes. \"\" then +$(CHECKOUT,v)" },
/* SCCS. */
/* ain't no SCCS on vms */
#else
/* RCS. */
{ "%", "%,v",
@@ -108,13 +128,50 @@ static struct pspec default_terminal_rules[] =
{ 0, 0, 0 }
};
static char *default_suffix_rules[] =
static const char *default_suffix_rules[] =
{
#ifdef VMS
".o",
"$(LINK.obj) $^ $(LOADLIBES) $(LDLIBS) -o $@",
".obj",
"$(LINK.obj) $^ $(LOADLIBES) $(LDLIBS) -o $@",
".s",
"$(LINK.s) $^ $(LOADLIBES) $(LDLIBS) -o $@",
".S",
"$(LINK.S) $^ $(LOADLIBES) $(LDLIBS) -o $@",
".c",
"$(LINK.c) $^ $(LOADLIBES) $(LDLIBS) -o $@",
".cc",
"$(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $@",
".C",
"$(LINK.C) $^ $(LOADLIBES) $(LDLIBS) -o $@",
".cpp",
"$(LINK.cpp) $^ $(LOADLIBES) $(LDLIBS) -o $@",
".f",
"$(LINK.f) $^ $(LOADLIBES) $(LDLIBS) -o $@",
".m",
"$(LINK.m) $^ $(LOADLIBES) $(LDLIBS) -o $@",
".p",
"$(LINK.p) $^ $(LOADLIBES) $(LDLIBS) -o $@",
".F",
"$(LINK.F) $^ $(LOADLIBES) $(LDLIBS) -o $@",
".r",
"$(LINK.r) $^ $(LOADLIBES) $(LDLIBS) -o $@",
".mod",
"$(COMPILE.mod) -o $@ -e $@ $^",
".def.sym",
"$(COMPILE.def) -o $@ $<",
".sh",
"copy $< >$@",
".obj.exe",
"$(LINK.obj) $^ $(LOADLIBES) $(LDLIBS) $(CRT0) /exe=$@",
".mar.exe",
"$(COMPILE.mar) $^ \n $(LINK.obj) $(subst .mar,.obj,$^) $(LOADLIBES) $(LDLIBS) $(CRT0) /exe=$@",
".s.o",
"$(COMPILE.s) -o $@ $<",
".s.exe",
"$(COMPILE.s) $^ \n $(LINK.obj) $(subst .s,.obj,$^) $(LOADLIBES) $(LDLIBS) $(CRT0) /exe=$@",
".c.exe",
@@ -149,6 +206,8 @@ static char *default_suffix_rules[] =
"$(COMPILE.c)/noprep/noobj/machine /list=$@ $<",
".c.obj",
"$(COMPILE.c) /obj=$@ $<",
".c.o",
"$(COMPILE.c) /obj=$@ $<",
".cc.ii",
"$(COMPILE.cc)/prep /list=$@ $<",
".cc.ss",
@@ -157,12 +216,20 @@ static char *default_suffix_rules[] =
"$(COMPILE.cc)/noprep/noobj/machine /list=$@ $<",
".cc.obj",
"$(COMPILE.cc) /obj=$@ $<",
".cc.o",
"$(COMPILE.cc) /obj=$@ $<",
".cxx.obj",
"$(COMPILE.cxx) /obj=$@ $<",
".cxx.o",
"$(COMPILE.cxx) /obj=$@ $<",
".for.obj",
"$(COMPILE.for) /obj=$@ $<",
".for.o",
"$(COMPILE.for) /obj=$@ $<",
".pas.obj",
"$(COMPILE.pas) /obj=$@ $<",
".pas.o",
"$(COMPILE.pas) /obj=$@ $<",
".y.c",
"$(YACC.y) $< \n rename y_tab.c $@",
@@ -175,6 +242,27 @@ static char *default_suffix_rules[] =
".tex.dvi",
"$(TEX) $<",
".cpp.o",
"$(COMPILE.cpp) $(OUTPUT_OPTION) $<",
".f.o",
"$(COMPILE.f) $(OUTPUT_OPTION) $<",
".m.o",
"$(COMPILE.m) $(OUTPUT_OPTION) $<",
".p.o",
"$(COMPILE.p) $(OUTPUT_OPTION) $<",
".r.o",
"$(COMPILE.r) $(OUTPUT_OPTION) $<",
".mod.o",
"$(COMPILE.mod) -o $@ $<",
".c.ln",
"$(LINT.c) -C$* $<",
".y.ln",
"$(YACC.y) $< \n rename y_tab.c $@",
".l.ln",
"@$(RM) $*.c\n $(LEX.l) $< > $*.c\n$(LINT.c) -i $*.c -o $@\n $(RM) $*.c",
#else /* ! VMS */
".o",
@@ -322,7 +410,8 @@ static const char *default_variables[] =
#ifdef __VAX
"ARCH", "VAX",
#endif
"AR", "library/obj",
"AR", "library",
"LIBRARY", "library",
"ARFLAGS", "/replace",
"AS", "macro",
"MACRO", "macro",
@@ -332,15 +421,21 @@ static const char *default_variables[] =
"CC", "cc",
#endif
"CD", "builtin_cd",
"MAKE", "make",
"ECHO", "write sys$$output \"",
"ECHO", "builtin_echo",
#ifdef GCC_IS_NATIVE
"C++", "gcc/plus",
"CXX", "gcc/plus",
#else
"C++", "cxx",
"CXX", "cxx",
#ifndef __ia64
"CXXLD", "cxxlink",
"CXXLINK", "cxxlink",
#else
/* CXXLINK is not used on VMS/IA64 */
"CXXLD", "link",
"CXXLINK", "link",
#endif
#endif
"CO", "co",
"CPP", "$(CC) /preprocess_only",
@@ -376,23 +471,49 @@ static const char *default_variables[] =
"LDLIBS", "",
#endif
"LINK.o", "$(LD) $(LDFLAGS)",
"LINK.obj", "$(LD) $(LDFLAGS)",
#ifndef GCC_IS_NATIVE
"CXXLINK.obj", "$(CXXLD) $(LDFLAGS)",
"COMPILE.cxx", "$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH)",
#endif
"COMPILE.c", "$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH)",
"LINK.c", "$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH)",
"COMPILE.m", "$(OBJC) $(OBJCFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c",
"LINK.m", "$(OBJC) $(OBJCFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)",
"COMPILE.cc", "$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH)",
"COMPILE.C", "$(COMPILE.cc)",
"COMPILE.cpp", "$(COMPILE.cc)",
"LINK.C", "$(LINK.cc)",
"LINK.cpp", "$(LINK.cc)",
"YACC.y", "$(YACC) $(YFLAGS)",
"LEX.l", "$(LEX) $(LFLAGS)",
"YACC.m", "$(YACC) $(YFLAGS)",
"LEX.m", "$(LEX) $(LFLAGS) -t",
"COMPILE.for", "$(FC) $(FFLAGS) $(TARGET_ARCH)",
"COMPILE.f", "$(FC) $(FFLAGS) $(TARGET_ARCH) -c",
"LINK.f", "$(FC) $(FFLAGS) $(LDFLAGS) $(TARGET_ARCH)",
"COMPILE.F", "$(FC) $(FFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c",
"LINK.F", "$(FC) $(FFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)",
"COMPILE.r", "$(FC) $(FFLAGS) $(RFLAGS) $(TARGET_ARCH) -c",
"LINK.r", "$(FC) $(FFLAGS) $(RFLAGS) $(LDFLAGS) $(TARGET_ARCH)",
"COMPILE.pas", "$(PC) $(PFLAGS) $(CPPFLAGS) $(TARGET_ARCH)",
"COMPILE.def", "$(M2C) $(M2FLAGS) $(DEFFLAGS) $(TARGET_ARCH)",
"COMPILE.mod", "$(M2C) $(M2FLAGS) $(MODFLAGS) $(TARGET_ARCH)",
"COMPILE.p", "$(PC) $(PFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c",
"LINK.p", "$(PC) $(PFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)",
"COMPILE.mar", "$(MACRO) $(MACROFLAGS)",
"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.F", "$(FC) $(FFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -F",
"PREPROCESS.r", "$(FC) $(FFLAGS) $(RFLAGS) $(TARGET_ARCH) -F",
"LINT.c", "$(LINT) $(LINTFLAGS) $(CPPFLAGS) $(TARGET_ARCH)",
"MV", "rename/new_version",
"CP", "copy",
".LIBPATTERNS", "%.olb lib%.a",
#else /* !VMS */
@@ -481,10 +602,21 @@ static const char *default_variables[] =
"COMPILE.m", "$(OBJC) $(OBJCFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c",
"LINK.m", "$(OBJC) $(OBJCFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)",
"COMPILE.cc", "$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c",
#ifndef HAVE_CASE_INSENSITIVE_FS
/* On case-insensitive filesystems, treat *.C files as *.c files,
to avoid erroneously compiling C sources as C++, which will
probably fail. */
"COMPILE.C", "$(COMPILE.cc)",
#else
"COMPILE.C", "$(COMPILE.c)",
#endif
"COMPILE.cpp", "$(COMPILE.cc)",
"LINK.cc", "$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)",
#ifndef HAVE_CASE_INSENSITIVE_FS
"LINK.C", "$(LINK.cc)",
#else
"LINK.C", "$(LINK.c)",
#endif
"LINK.cpp", "$(LINK.cc)",
"YACC.y", "$(YACC) $(YFLAGS)",
"LEX.l", "$(LEX) $(LFLAGS) -t",
@@ -523,6 +655,8 @@ static const char *default_variables[] =
".LIBPATTERNS", "lib%.a $(DJDIR)/lib/lib%.a",
#elif defined(__APPLE__)
".LIBPATTERNS", "lib%.dylib lib%.a",
#elif defined(__CYGWIN__) || defined(WINDOWS32)
".LIBPATTERNS", "lib%.dll.a %.dll.a lib%.a %.lib lib%.dll %.dll",
#else
".LIBPATTERNS", "lib%.so lib%.a",
#endif
@@ -546,8 +680,8 @@ set_default_suffixes (void)
else
{
struct dep *d;
char *p = default_suffixes;
suffix_file->deps = enter_prereqs (PARSE_SIMPLE_SEQ (&p, struct dep),
const char *p = default_suffixes;
suffix_file->deps = enter_prereqs (PARSE_SIMPLE_SEQ ((char **)&p, struct dep),
NULL);
for (d = suffix_file->deps; d; d = d->next)
d->file->builtin = 1;
@@ -564,7 +698,7 @@ set_default_suffixes (void)
void
install_default_suffix_rules (void)
{
char **s;
const char **s;
if (no_builtin_rules_flag)
return;
@@ -576,7 +710,7 @@ install_default_suffix_rules (void)
assert (f->cmds == 0);
f->cmds = xmalloc (sizeof (struct commands));
f->cmds->fileinfo.filenm = 0;
f->cmds->commands = s[1];
f->cmds->commands = xstrdup (s[1]);
f->cmds->command_lines = 0;
f->cmds->recipe_prefix = RECIPEPREFIX_DEFAULT;
f->builtin = 1;

99
dep.h
View File

@@ -1,5 +1,5 @@
/* Definitions of dependency data structures for GNU Make.
Copyright (C) 1988-2013 Free Software Foundation, Inc.
Copyright (C) 1988-2016 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,9 +14,21 @@ 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/>. */
/* Structure used in chains of names, for parsing and globbing. */
#define NAMESEQ(_t) \
_t *next; \
const char *name
struct nameseq
{
NAMESEQ (struct nameseq);
};
/* Flag bits for the second argument to 'read_makefile'.
These flags are saved in the 'changed' field of each
'struct dep' in the chain returned by 'read_all_makefiles'. */
These flags are saved in the 'flags' field of each
'struct goaldep' in the chain returned by 'read_all_makefiles'. */
#define RM_NO_DEFAULT_GOAL (1 << 0) /* Do not set default goal. */
#define RM_INCLUDED (1 << 1) /* Search makefile search path. */
@@ -25,34 +37,37 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#define RM_NOFLAG 0
/* Structure representing one dependency of a file.
Each struct file's 'deps' points to a chain of these,
chained through the 'next'. 'stem' is the stem for this
dep line of static pattern rule or NULL.
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. */
Note that the first two words of this match a struct nameseq. */
#define DEP(_t) \
NAMESEQ (_t); \
struct file *file; \
const char *stem; \
unsigned short flags : 8; \
unsigned short changed : 1; \
unsigned short ignore_mtime : 1; \
unsigned short staticpattern : 1; \
unsigned short need_2nd_expansion : 1
struct dep
{
struct dep *next;
const char *name;
const char *stem;
struct file *file;
unsigned int changed : 8;
unsigned int ignore_mtime : 1;
unsigned int staticpattern : 1;
unsigned int need_2nd_expansion : 1;
unsigned int dontcare : 1;
DEP (struct dep);
};
/* Structure representing one goal.
The goals to be built constitute a chain of these, chained through 'next'.
'stem' is not used, but it's simpler to include and ignore it. */
/* Structure used in chains of names, for parsing and globbing. */
struct nameseq
struct goaldep
{
struct nameseq *next;
const char *name;
DEP (struct goaldep);
unsigned short error;
floc floc;
};
/* Options for parsing lists of filenames. */
#define PARSEFS_NONE 0x0000
#define PARSEFS_NOSTRIP 0x0001
#define PARSEFS_NOAR 0x0002
@@ -78,15 +93,39 @@ char *tilde_expand (const char *name);
struct nameseq *ar_glob (const char *arname, const char *member_pattern, unsigned int size);
#endif
#define dep_name(d) ((d)->name == 0 ? (d)->file->name : (d)->name)
#define dep_name(d) ((d)->name ? (d)->name : (d)->file->name)
#define alloc_dep() (xcalloc (sizeof (struct dep)))
#define free_ns(_n) free (_n)
#define free_dep(_d) free_ns (_d)
#define alloc_seq_elt(_t) xcalloc (sizeof (_t))
void free_ns_chain (struct nameseq *n);
#if defined(MAKE_MAINTAINER_MODE) && defined(__GNUC__)
/* 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 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)
# define alloc_goaldep() alloc_seq_elt (struct goaldep)
# define free_ns(_n) free (_n)
# define free_dep(_d) free_ns (_d)
# define free_goaldep(_g) free_dep (_g)
# define free_dep_chain(_d) free_ns_chain ((struct nameseq *)(_d))
# define free_goal_chain(_g) free_ns_chain ((struct nameseq *)(_g))
#endif
struct dep *copy_dep_chain (const struct dep *d);
void free_dep_chain (struct dep *d);
void free_ns_chain (struct nameseq *n);
struct dep *read_all_makefiles (const char **makefiles);
void eval_buffer (char *buffer, const gmk_floc *floc);
enum update_status update_goal_chain (struct dep *goals);
struct goaldep *read_all_makefiles (const char **makefiles);
void eval_buffer (char *buffer, const floc *floc);
enum update_status update_goal_chain (struct goaldep *goals);

239
dir.c
View File

@@ -1,5 +1,5 @@
/* Directory hashing for GNU Make.
Copyright (C) 1988-2013 Free Software Foundation, Inc.
Copyright (C) 1988-2016 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
@@ -16,6 +16,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#include "makeint.h"
#include "hash.h"
#include "filedef.h"
#include "dep.h"
#ifdef HAVE_DIRENT_H
@@ -141,6 +142,32 @@ downcase (const char *filename)
#ifdef VMS
static char *
downcase_inplace(char *filename)
{
char *name;
name = filename;
while (*name != '\0')
{
*name = tolower ((unsigned char)*name);
++name;
}
return filename;
}
#ifndef _USE_STD_STAT
/* VMS 8.2 fixed the VMS stat output to have unique st_dev and st_ino
when _USE_STD_STAT is used on the compile line.
Prior to _USE_STD_STAT support, the st_dev is a pointer to thread
static memory containing the device of the last filename looked up.
Todo: find out if the ino_t still needs to be faked on a directory.
*/
/* Define this if the older VMS_INO_T is needed */
#define VMS_INO_T 1
static int
vms_hash (const char *name)
{
@@ -199,6 +226,10 @@ vmsstat_dir (const char *name, struct stat *st)
return 0;
}
# define stat(__path, __sbuf) vmsstat_dir (__path, __sbuf)
#endif /* _USE_STD_STAT */
#endif /* VMS */
/* Hash table of directories. */
@@ -217,14 +248,14 @@ struct directory_contents
* qualified name of the directory. Beware though, this is also
* unreliable. I'm open to suggestion on a better way to emulate inode. */
char *path_key;
int ctime;
int mtime; /* controls check for stale directory cache */
int fs_flags; /* FS_FAT, FS_NTFS, ... */
time_t ctime;
time_t mtime; /* controls check for stale directory cache */
int fs_flags; /* FS_FAT, FS_NTFS, ... */
# define FS_FAT 0x1
# define FS_NTFS 0x2
# define FS_UNKNOWN 0x4
#else
# ifdef VMS
# ifdef VMS_INO_T
ino_t ino[3];
# else
ino_t ino;
@@ -245,7 +276,7 @@ directory_contents_hash_1 (const void *key_0)
ISTRING_HASH_1 (key->path_key, hash);
hash ^= ((unsigned int) key->dev << 4) ^ (unsigned int) key->ctime;
#else
# ifdef VMS
# ifdef VMS_INO_T
hash = (((unsigned int) key->dev << 4)
^ ((unsigned int) key->ino[0]
+ (unsigned int) key->ino[1]
@@ -268,7 +299,7 @@ directory_contents_hash_2 (const void *key_0)
ISTRING_HASH_2 (key->path_key, hash);
hash ^= ((unsigned int) key->dev << 4) ^ (unsigned int) ~key->ctime;
#else
# ifdef VMS
# ifdef VMS_INO_T
hash = (((unsigned int) key->dev << 4)
^ ~((unsigned int) key->ino[0]
+ (unsigned int) key->ino[1]
@@ -307,7 +338,7 @@ directory_contents_hash_cmp (const void *xv, const void *yv)
if (result)
return result;
#else
# ifdef VMS
# ifdef VMS_INO_T
result = MAKECMP(x->ino[0], y->ino[0]);
if (result)
return result;
@@ -374,7 +405,7 @@ static unsigned int open_directories = 0;
struct dirfile
{
const char *name; /* Name of the file. */
short length;
size_t length;
short impossible; /* This file is impossible. */
};
@@ -418,13 +449,6 @@ find_directory (const char *name)
struct directory **dir_slot;
struct directory dir_key;
#ifdef VMS
if ((*name == '.') && (*(name+1) == 0))
name = "[]";
else
name = vmsify (name,1);
#endif
dir_key.name = name;
dir_slot = (struct directory **) hash_find_slot (&directories, &dir_key);
dir = *dir_slot;
@@ -438,7 +462,12 @@ find_directory (const char *name)
dir = xmalloc (sizeof (struct directory));
#if defined(HAVE_CASE_INSENSITIVE_FS) && defined(VMS)
dir->name = strcache_add_len (downcase (name), p - name);
/* Todo: Why is this only needed on VMS? */
{
char *lname = downcase_inplace (xstrdup (name));
dir->name = strcache_add_len (lname, p - name);
free (lname);
}
#else
dir->name = strcache_add_len (name, p - name);
#endif
@@ -446,9 +475,7 @@ find_directory (const char *name)
/* The directory is not in the name hash table.
Find its device and inode numbers, and look it up by them. */
#ifdef VMS
r = vmsstat_dir (name, &st);
#elif defined(WINDOWS32)
#if defined(WINDOWS32)
{
char tem[MAXPATHLEN], *tstart, *tend;
@@ -491,7 +518,7 @@ find_directory (const char *name)
dc_key.path_key = w32_path = w32ify (name, 1);
dc_key.ctime = st.st_ctime;
#else
# ifdef VMS
# 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];
@@ -536,7 +563,7 @@ find_directory (const char *name)
else
dc->fs_flags = FS_UNKNOWN;
#else
# ifdef VMS
# 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];
@@ -601,11 +628,6 @@ dir_contents_file_exists_p (struct directory_contents *dir,
if (filename != 0)
_fnlwr (filename); /* lower case for FAT drives */
#endif
#ifdef VMS
filename = vmsify (filename,0);
#endif
if (filename != 0)
{
struct dirfile dirfile_key;
@@ -673,12 +695,14 @@ dir_contents_file_exists_p (struct directory_contents *dir,
if (d == 0)
{
if (errno)
fatal (NILF, "INTERNAL: readdir: %s\n", strerror (errno));
pfatal_with_name ("INTERNAL: readdir");
break;
}
#if defined(VMS) && defined(HAVE_DIRENT_H)
/* In VMS we get file versions too, which have to be stripped off */
/* In VMS we get file versions too, which have to be stripped off.
Some versions of VMS return versions on Unix files even when
the feature option to strip them is set. */
{
char *p = strrchr (d->d_name, ';');
if (p)
@@ -702,7 +726,8 @@ dir_contents_file_exists_p (struct directory_contents *dir,
{
df = xmalloc (sizeof (struct dirfile));
#if defined(HAVE_CASE_INSENSITIVE_FS) && defined(VMS)
df->name = strcache_add_len (downcase (d->d_name), len);
/* TODO: Why is this only needed on VMS? */
df->name = strcache_add_len (downcase_inplace (d->d_name), len);
#else
df->name = strcache_add_len (d->d_name, len);
#endif
@@ -733,6 +758,15 @@ dir_contents_file_exists_p (struct directory_contents *dir,
int
dir_file_exists_p (const char *dirname, const char *filename)
{
#ifdef VMS
if ((filename != NULL) && (dirname != NULL))
{
int want_vmsify;
want_vmsify = (strpbrk (dirname, ":<[") != NULL);
if (want_vmsify)
filename = vmsify (filename, 0);
}
#endif
return dir_contents_file_exists_p (find_directory (dirname)->contents,
filename);
}
@@ -751,14 +785,24 @@ file_exists_p (const char *name)
return ar_member_date (name) != (time_t) -1;
#endif
#ifdef VMS
dirend = strrchr (name, ']');
if (dirend == 0)
dirend = strrchr (name, ':');
if (dirend == 0)
return dir_file_exists_p ("[]", name);
#else /* !VMS */
dirend = strrchr (name, '/');
#ifdef VMS
if (dirend == 0)
{
dirend = strrchr (name, ']');
dirend == NULL ? dirend : dirend++;
}
if (dirend == 0)
{
dirend = strrchr (name, '>');
dirend == NULL ? dirend : dirend++;
}
if (dirend == 0)
{
dirend = strrchr (name, ':');
dirend == NULL ? dirend : dirend++;
}
#endif /* VMS */
#ifdef HAVE_DOS_PATHS
/* Forward and backslashes might be mixed. We need the rightmost one. */
{
@@ -773,10 +817,9 @@ file_exists_p (const char *name)
if (dirend == 0)
#ifndef _AMIGA
return dir_file_exists_p (".", name);
#else /* !VMS && !AMIGA */
#else /* !AMIGA */
return dir_file_exists_p ("", name);
#endif /* AMIGA */
#endif /* VMS */
slash = dirend;
if (dirend == name)
@@ -795,7 +838,13 @@ file_exists_p (const char *name)
p[dirend - name] = '\0';
dirname = p;
}
return dir_file_exists_p (dirname, slash + 1);
#ifdef VMS
if (*slash == '/')
slash++;
#else
slash++;
#endif
return dir_file_exists_p (dirname, slash);
}
/* Mark FILENAME as 'impossible' for 'file_impossible_p'.
@@ -810,16 +859,25 @@ file_impossible (const char *filename)
struct directory *dir;
struct dirfile *new;
#ifdef VMS
dirend = strrchr (p, ']');
if (dirend == 0)
dirend = strrchr (p, ':');
dirend++;
if (dirend == (char *)1)
dir = find_directory ("[]");
#else
dirend = strrchr (p, '/');
# ifdef HAVE_DOS_PATHS
#ifdef VMS
if (dirend == NULL)
{
dirend = strrchr (p, ']');
dirend == NULL ? dirend : dirend++;
}
if (dirend == NULL)
{
dirend = strrchr (p, '>');
dirend == NULL ? dirend : dirend++;
}
if (dirend == NULL)
{
dirend = strrchr (p, ':');
dirend == NULL ? dirend : dirend++;
}
#endif
#ifdef HAVE_DOS_PATHS
/* Forward and backslashes might be mixed. We need the rightmost one. */
{
const char *bslash = strrchr (p, '\\');
@@ -829,14 +887,13 @@ file_impossible (const char *filename)
if (!dirend && p[0] && p[1] == ':')
dirend = p + 1;
}
# endif /* HAVE_DOS_PATHS */
#endif /* HAVE_DOS_PATHS */
if (dirend == 0)
# ifdef _AMIGA
#ifdef _AMIGA
dir = find_directory ("");
# else /* !VMS && !AMIGA */
#else /* !AMIGA */
dir = find_directory (".");
# endif /* AMIGA */
#endif /* VMS */
#endif /* AMIGA */
else
{
const char *dirname;
@@ -858,7 +915,14 @@ file_impossible (const char *filename)
dirname = cp;
}
dir = find_directory (dirname);
#ifdef VMS
if (*slash == '/')
filename = p = slash + 1;
else
filename = p = slash;
#else
filename = p = slash + 1;
#endif
}
if (dir->contents == 0)
@@ -877,6 +941,7 @@ file_impossible (const char *filename)
new = xmalloc (sizeof (struct dirfile));
new->length = strlen (filename);
#if defined(HAVE_CASE_INSENSITIVE_FS) && defined(VMS)
/* todo: Why is this only needed on VMS? */
new->name = strcache_add_len (downcase (filename), new->length);
#else
new->name = strcache_add_len (filename, new->length);
@@ -894,13 +959,22 @@ file_impossible_p (const char *filename)
struct directory_contents *dir;
struct dirfile *dirfile;
struct dirfile dirfile_key;
#ifdef VMS
dirend = strrchr (filename, ']');
if (dirend == 0)
dir = find_directory ("[]")->contents;
#else
int want_vmsify = 0;
#endif
dirend = strrchr (filename, '/');
#ifdef VMS
if (dirend == NULL)
{
want_vmsify = (strpbrk (filename, "]>:^") != NULL);
dirend = strrchr (filename, ']');
}
if (dirend == NULL && want_vmsify)
dirend = strrchr (filename, '>');
if (dirend == NULL && want_vmsify)
dirend = strrchr (filename, ':');
#endif
#ifdef HAVE_DOS_PATHS
/* Forward and backslashes might be mixed. We need the rightmost one. */
{
@@ -915,10 +989,9 @@ file_impossible_p (const char *filename)
if (dirend == 0)
#ifdef _AMIGA
dir = find_directory ("")->contents;
#else /* !VMS && !AMIGA */
#else /* !AMIGA */
dir = find_directory (".")->contents;
#endif /* AMIGA */
#endif /* VMS */
else
{
const char *dirname;
@@ -940,7 +1013,14 @@ file_impossible_p (const char *filename)
dirname = cp;
}
dir = find_directory (dirname)->contents;
#ifdef VMS
if (*slash == '/')
filename = slash + 1;
else
filename = slash;
#else
filename = slash + 1;
#endif
}
if (dir == 0 || dir->dirfiles.ht_vec == 0)
@@ -954,7 +1034,8 @@ file_impossible_p (const char *filename)
filename = downcase (filename);
#endif
#ifdef VMS
filename = vmsify (filename, 1);
if (want_vmsify)
filename = vmsify (filename, 1);
#endif
dirfile_key.name = filename;
@@ -1001,10 +1082,11 @@ print_dir_data_base (void)
else if (dir->contents->dirfiles.ht_vec == 0)
{
#ifdef WINDOWS32
printf (_("# %s (key %s, mtime %d): could not be opened.\n"),
dir->name, dir->contents->path_key,dir->contents->mtime);
printf (_("# %s (key %s, mtime %ull): could not be opened.\n"),
dir->name, dir->contents->path_key,
(unsigned long long)dir->contents->mtime);
#else /* WINDOWS32 */
#ifdef VMS
#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],
@@ -1037,10 +1119,11 @@ print_dir_data_base (void)
}
}
#ifdef WINDOWS32
printf (_("# %s (key %s, mtime %d): "),
dir->name, dir->contents->path_key, dir->contents->mtime);
printf (_("# %s (key %s, mtime %ull): "),
dir->name, dir->contents->path_key,
(unsigned long long)dir->contents->mtime);
#else /* WINDOWS32 */
#ifdef VMS
#ifdef VMS_INO_T
printf (_("# %s (device %d, inode [%d,%d,%d]): "),
dir->name, dir->contents->dev,
dir->contents->ino[0], dir->contents->ino[1],
@@ -1086,8 +1169,6 @@ print_dir_data_base (void)
/* Hooks for globbing. */
#include <glob.h>
/* Structure describing state of iterating through a directory hash table. */
struct dirstream
@@ -1171,13 +1252,6 @@ read_dirstream (__ptr_t stream)
return 0;
}
static void
ansi_free (void *p)
{
if (p)
free (p);
}
/* On 64 bit ReliantUNIX (5.44 and above) in LFS mode, stat() is actually a
* macro for stat64(). If stat is a macro, make a local wrapper function to
* invoke it.
@@ -1185,9 +1259,16 @@ ansi_free (void *p)
* On MS-Windows, stat() "succeeds" for foo/bar/. where foo/bar is a
* regular file; fix that here.
*/
#if !defined(stat) && !defined(WINDOWS32)
#if !defined(stat) && !defined(WINDOWS32) || defined(VMS)
# ifndef VMS
# ifndef HAVE_SYS_STAT_H
int stat (const char *path, struct stat *sbuf);
# endif
# else
/* We are done with the fake stat. Go back to the real stat */
# ifdef stat
# undef stat
# endif
# endif
# define local_stat stat
#else
@@ -1223,7 +1304,7 @@ dir_setup_glob (glob_t *gl)
{
gl->gl_opendir = open_dirstream;
gl->gl_readdir = read_dirstream;
gl->gl_closedir = ansi_free;
gl->gl_closedir = free;
gl->gl_stat = local_stat;
/* We don't bother setting gl_lstat, since glob never calls it.
The slot is only there for compatibility with 4.4 BSD. */

2
doc/.gitignore vendored
View File

@@ -1,3 +1,5 @@
manual/
gendocs_template
fdl.texi
make-stds.texi
stamp-vti

View File

@@ -1,5 +1,5 @@
# -*-Makefile-*-, or close enough
# Copyright (C) 2000-2013 Free Software Foundation, Inc.
# Copyright (C) 2000-2016 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
@@ -22,14 +22,3 @@ info_TEXINFOS = make.texi
make_TEXINFOS = fdl.texi make-stds.texi
CLEANFILES = make*.html
## ----------------------------- ##
## Other documentation formats. ##
## ----------------------------- ##
html: make_1.html
make_1.html: $(info_TEXINFOS) $(make_TEXINFOS)
$(TEXI2HTML) $(TEXI2HTML_FLAGS) $(srcdir)/make.texi
.PHONY: html

View File

@@ -3,7 +3,7 @@
@setfilename make.info
@include version.texi
@set EDITION 0.72
@set EDITION 0.74
@settitle GNU @code{make}
@setchapternewpage odd
@@ -26,7 +26,8 @@ of @cite{The GNU Make Manual}, for GNU @code{make} version @value{VERSION}.
Copyright @copyright{} 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007,
2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Free Software
Foundation, Inc.
@quotation
Permission is granted to copy, distribute and/or modify this document
@@ -100,6 +101,7 @@ Cover art by Etienne Suvasa.
based on their file names.
* Archives:: How @code{make} can update library archives.
* Extending make:: Using extensions to @code{make}.
* Integrating make:: Integrating @code{make} with other tools.
* Features:: Features GNU @code{make} has over other @code{make}s.
* Missing:: What GNU @code{make} lacks from other @code{make}s.
* Makefile Conventions:: Conventions for writing makefiles for
@@ -304,7 +306,7 @@ Using Implicit Rules
* Using Implicit:: How to use an existing implicit rule
to get the recipes for updating a file.
* Catalogue of Rules:: A list of built-in implicit rules.
* Catalogue of Rules:: A list of built-in rules.
* Implicit Variables:: How to change what predefined rules do.
* Chained Rules:: How to use a chain of implicit rules.
* Pattern Rules:: How to define new implicit rules.
@@ -356,6 +358,16 @@ Loading Dynamic Objects
* Loaded Object API:: Programmatic interface for loaded objects.
* Loaded Object Example:: Example of a loaded object
Integrating GNU @code{make}
* Job Slots:: Share job slots with GNU @code{make}.
* Terminal Output:: Control output to terminals.
Sharing Job Slots with GNU @code{make}
* POSIX Jobserver:: Using the jobserver on POSIX systems.
* Windows Jobserver:: Using the jobserver on Windows systems.
@end detailmenu
@end menu
@@ -1528,7 +1540,7 @@ A rule is always expanded the same way, regardless of the form:
@example
@var{immediate} : @var{immediate} ; @var{deferred}
@var{deferred}
@var{deferred}
@end example
That is, the target and prerequisite sections are expanded immediately,
@@ -2584,30 +2596,14 @@ will be executed every time you say @samp{make clean}.
@cindex @code{rm} (shell command)
@findex .PHONY
The phony target will cease to work if anything ever does create a file
named @file{clean} in this directory. Since it has no prerequisites, the
file @file{clean} would inevitably be considered up to date, and its
recipe would not be executed. To avoid this problem, you can explicitly
declare the target to be phony, using the special target @code{.PHONY}
In this example, the @file{clean} target will not work properly if a
file named @file{clean} is ever created in this directory. Since it
has no prerequisites, @file{clean} would always be considered up to
date and its recipe would not be executed. To avoid this problem you
can explicitly declare the target to be phony by making it a
prerequisite of the special target @code{.PHONY}
(@pxref{Special Targets, ,Special Built-in Target Names}) as follows:
@example
.PHONY : clean
@end example
@noindent
Once this is done, @samp{make clean} will run the recipe regardless of
whether there is a file named @file{clean}.
Since it knows that phony targets do not name actual files that could be
remade from other files, @code{make} skips the implicit rule search for
phony targets (@pxref{Implicit Rules}). This is why declaring a target
phony is good for performance, even if you are not worried about the
actual file existing.
Thus, you first write the line that states that @code{clean} is a
phony target, then you write the rule, like this:
@example
@group
.PHONY: clean
@@ -2616,12 +2612,16 @@ clean:
@end group
@end example
Another example of the usefulness of phony targets is in conjunction
with recursive invocations of @code{make} (for more information, see
@ref{Recursion, ,Recursive Use of @code{make}}). In this case the
makefile will often contain a variable which lists a number of
sub-directories to be built. One way to handle this is with one rule
whose recipe is a shell loop over the sub-directories, like this:
@noindent
Once this is done, @samp{make clean} will run the recipe regardless of
whether there is a file named @file{clean}.
Phony targets are also useful in conjunction with recursive
invocations of @code{make} (@pxref{Recursion, ,Recursive Use of @code{make}}).
In this situation the makefile will often contain a variable which
lists a number of sub-directories to be built. A simplistic way to
handle this is to define one rule with a recipe that loops over the
sub-directories, like this:
@example
@group
@@ -2644,9 +2644,9 @@ you cannot take advantage of @code{make}'s ability to build targets in
parallel (@pxref{Parallel, ,Parallel Execution}), since there is only
one rule.
By declaring the sub-directories as phony targets (you must do this as
the sub-directory obviously always exists; otherwise it won't be built)
you can remove these problems:
By declaring the sub-directories as @code{.PHONY} targets (you must do
this as the sub-directory obviously always exists; otherwise it won't
be built) you can remove these problems:
@example
@group
@@ -2668,6 +2668,11 @@ built until after the @file{baz} sub-directory is complete; this kind of
relationship declaration is particularly important when attempting
parallel builds.
The implicit rule search (@pxref{Implicit Rules}) is skipped for
@code{.PHONY} targets. This is why declaring a target as
@code{.PHONY} is good for performance, even if you are not worried
about the actual file existing.
A phony target should not be a prerequisite of a real target file; if it
is, its recipe will be run every time @code{make} goes to update that
file. As long as a phony target is never a prerequisite of a real
@@ -4716,9 +4721,9 @@ doesn't count against the total jobs (otherwise we could get @samp{N}
sub-@code{make}s running and have no slots left over for any real work!)
If your operating system doesn't support the above communication, then
@samp{-j 1} is always put into @code{MAKEFLAGS} instead of the value you
specified. This is because if the @w{@samp{-j}} option were passed down
to sub-@code{make}s, you would get many more jobs running in parallel
no @samp{-j} is added to @code{MAKEFLAGS}, so that sub-@code{make}s
run in non-parallel mode. If the @w{@samp{-j}} option were passed down
to sub-@code{make}s you would get many more jobs running in parallel
than you asked for. If you give @samp{-j} with no numeric argument,
meaning to run as many jobs as possible in parallel, this is passed
down, since multiple infinities are no more than one.@refill
@@ -4808,10 +4813,17 @@ to GNU @code{make}, and hence do not want to add GNU
@code{make}-specific flags to the @code{MAKEFLAGS} variable, you can
add them to the @code{GNUMAKEFLAGS} variable instead. This variable
is parsed just before @code{MAKEFLAGS}, in the same way as
@code{MAKEFLAGS}. Note, however, that when @code{make} constructs
@code{MAKEFLAGS} to pass to a recursive @code{make} it will include
all flags. GNU @code{make} never sets the @code{GNUMAKEFLAGS}
variable itself.
@code{MAKEFLAGS}. When @code{make} constructs @code{MAKEFLAGS} to
pass to a recursive @code{make} it will include all flags, even those
taken from @code{GNUMAKEFLAGS}. As a result, after parsing
@code{GNUMAKEFLAGS} GNU @code{make} sets this variable to the empty
string to avoid duplicating flags during recursion.
It's best to use @code{GNUMAKEFLAGS} only with flags which won't
materially change the behavior of your makefiles. If your makefiles
require GNU make anyway then simply use @code{MAKEFLAGS}. Flags such
as @samp{--no-print-directory} or @samp{--output-sync} may be
appropriate for @code{GNUMAKEFLAGS}.
@node -w Option, , Options/Recursion, Recursion
@subsection The @samp{--print-directory} Option
@@ -4970,27 +4982,24 @@ beginning with a recipe prefix character to define an empty recipe,
but this would be confusing because such a line looks empty.
@findex .DEFAULT@r{, and empty recipes}
You may be wondering why you would want to define a recipe that
does nothing. The only reason this is useful is to prevent a target
from getting implicit recipes (from implicit rules or the
@code{.DEFAULT} special target; @pxref{Implicit Rules} and
@pxref{Last Resort, ,Defining Last-Resort Default Rules}).@refill
You may be wondering why you would want to define a recipe that does
nothing. One reason this is useful is to prevent a target from
getting implicit recipes (from implicit rules or the @code{.DEFAULT}
special target; @pxref{Implicit Rules} and @pxref{Last Resort,
,Defining Last-Resort Default Rules}).@refill
@c !!! another reason is for canonical stamp files:
@ignore
@example
foo: stamp-foo ;
stamp-foo: foo.in
create foo frm foo.in
touch $@
@end example
@end ignore
Empty recipes can also be used to avoid errors for targets that will
be created as a side-effect of another recipe: if the target does not
exist the empty recipe ensures that @code{make} won't complain that it
doesn't know how to build the target, and @code{make} will assume the
target is out of date.
You may be inclined to define empty recipes for targets that are
not actual files, but only exist so that their prerequisites can be
You may be inclined to define empty recipes for targets that are not
actual files, but only exist so that their prerequisites can be
remade. However, this is not the best way to do that, because the
prerequisites may not be remade properly if the target file actually does exist.
@xref{Phony Targets, ,Phony Targets}, for a better way to do this.
prerequisites may not be remade properly if the target file actually
does exist. @xref{Phony Targets, ,Phony Targets}, for a better way to
do this.
@node Using Variables, Conditionals, Recipes, Top
@chapter How to Use Variables
@@ -5616,7 +5625,7 @@ Several variables have constant initial values.
@cindex !=
To set a variable from the makefile, write a line starting with the
variable name followed by @samp{=} @samp{:=}, or @samp{::=}. Whatever
variable name followed by @samp{=}, @samp{:=}, or @samp{::=}. Whatever
follows the @samp{=}, @samp{:=}, or @samp{::=} on the line becomes the
value. For example,
@@ -5669,7 +5678,7 @@ endif
@end example
The shell assignment operator @samp{!=} can be used to execute a
program and set a variable to its output. This operator first
shell script and set a variable to its output. This operator first
evaluates the right-hand side, then passes that result to the shell
for execution. If the result of the execution ends in a newline, that
one newline is removed; all other newlines are replaced by spaces.
@@ -5694,6 +5703,9 @@ hash := $(shell printf '\043')
var := $(shell find . -name "*.c")
@end example
As with the @code{shell} function, the exit status of the just-invoked
shell script is stored in the @code{.SHELLSTATUS} variable.
@node Appending, Override Directive, Setting, Using Variables
@section Appending More Text to Variables
@@ -5802,7 +5814,7 @@ CFLAGS += -pg # enable profiling
@noindent
The first line defines the @code{CFLAGS} variable with a reference to another
variable, @code{includes}. (@code{CFLAGS} is used by the rules for C
compilation; @pxref{Catalogue of Rules, ,Catalogue of Implicit Rules}.)
compilation; @pxref{Catalogue of Rules, ,Catalogue of Built-In Rules}.)
Using @samp{=} for the definition makes @code{CFLAGS} a recursively-expanded
variable, meaning @w{@samp{$(includes) -O}} is @emph{not} expanded when
@code{make} processes the definition of @code{CFLAGS}. Thus, @code{includes}
@@ -6321,6 +6333,28 @@ will contain the number of times this instance has restarted. Note
this is not the same as recursion (counted by the @code{MAKELEVEL}
variable). You should not set, modify, or export this variable.
@vindex MAKE_TERMOUT @r{(whether stdout is a terminal)}
@vindex MAKE_TERMERR @r{(whether stderr is a terminal)}
@item MAKE_TERMOUT
@itemx MAKE_TERMERR
When @code{make} starts it will check whether stdout and stderr will
show their output on a terminal. If so, it will set
@code{MAKE_TERMOUT} and @code{MAKE_TERMERR}, respectively, to the name
of the terminal device (or @code{true} if this cannot be determined).
If set these variables will be marked for export. These variables
will not be changed by @code{make} and they will not be modified if
already set.
These values can be used (particularly in combination with output
synchronization (@pxref{Parallel Output, ,Output During Parallel
Execution}) to determine whether @code{make} itself is writing to a
terminal; they can be tested to decide whether to force recipe
commands to generate colorized output for example.
If you invoke a sub-@code{make} and redirect its stdout or stderr it
is your responsibility to reset or unexport these variables as well,
if your makefiles rely on them.
@vindex .RECIPEPREFIX @r{(change the recipe prefix character)}
@item .RECIPEPREFIX
The first character of the value of this variable is used as the
@@ -6614,12 +6648,12 @@ effective; otherwise, the @var{text-if-false}, if any, is effective.
@item ifdef @var{variable-name}
The @code{ifdef} form takes the @emph{name} of a variable as its
argument, not a reference to a variable. The value of that variable
has a non-empty value, the @var{text-if-true} is effective; otherwise,
the @var{text-if-false}, if any, is effective. Variables that have
never been defined have an empty value. The text @var{variable-name}
is expanded, so it could be a variable or function that expands
to the name of a variable. For example:
argument, not a reference to a variable. If the value of that
variable has a non-empty value, the @var{text-if-true} is effective;
otherwise, the @var{text-if-false}, if any, is effective. Variables
that have never been defined have an empty value. The text
@var{variable-name} is expanded, so it could be a variable or function
that expands to the name of a variable. For example:
@example
bar = true
@@ -7498,34 +7532,46 @@ no?), but it is more likely to be a mistake.
@findex file
@cindex writing to a file
@cindex file, writing to
@cindex reading from a file
@cindex file, reading from
The @code{file} function allows the makefile to write to a file. Two
modes of writing are supported: overwrite, where the text is written
to the beginning of the file and any existing content is lost, and
append, where the text is written to the end of the file, preserving
the existing content. In all cases the file is created if it does not
exist.
The @code{file} function allows the makefile to write to or read from
a file. Two modes of writing are supported: overwrite, where the text
is written to the beginning of the file and any existing content is
lost, and append, where the text is written to the end of the file,
preserving the existing content. In both cases the file is created if
it does not exist. It is a fatal error if the file cannot be opened
for writing, or if the write operation fails. The @code{file}
function expands to the empty string when writing to a file.
When reading from a file, the @code{file} function expands to the
verbatim contents of the file, except that the final newline (if there
is one) will be stripped. Attempting to read from a non-existent file
expands to the empty string.
The syntax of the @code{file} function is:
@example
$(file @var{op} @var{filename},@var{text})
$(file @var{op} @var{filename}[,@var{text}])
@end example
The operator @var{op} can be either @code{>} which indicates overwrite
mode, or @code{>>} which indicates append mode. The @var{filename}
indicates the file to be written to. There may optionally be
When the @code{file} function is evaluated all its arguments are
expanded first, then the file indicated by @var{filename} will be
opened in the mode described by @var{op}.
The operator @var{op} can be @code{>} to indicate the file will be
overwritten with new content, @code{>>} to indicate the current
contents of the file will be appended to, or @code{<} to indicate the
contents of the file will be read in. The @var{filename} specifies
the file to be written to or read from. There may optionally be
whitespace between the operator and the file name.
When the @code{file} function is expanded all its arguments are
expanded first, then the file indicated by @var{filename} will be
opened in the mode described by @var{op}. Finally @var{text} will be
written to the file. If @var{text} does not already end in a newline,
a final newline will be written. The result of evaluating the
@code{file} function is always the empty string.
When reading files, it is an error to provide a @var{text} value.
It is a fatal error if the file cannot be opened for writing, or if
the write operation fails.
When writing files, @var{text} will be written to the file. If
@var{text} does not already end in a newline a final newline will be
written (even if @var{text} is the empty string). If the @var{text}
argument is not given at all, nothing will be written.
For example, the @code{file} function can be useful if your build
system has a limited command line size and your recipe runs a command
@@ -7549,7 +7595,7 @@ input file, you might write your recipe like this:
@example
@group
program: $(OBJECTS)
$(file >$@@.in,) $(foreach O,$^,$(file >>$@@.in,$O))
$(file >$@@.in) $(foreach O,$^,$(file >>$@@.in,$O))
$(CMD) $(CMDFLAGS) @@$@@.in
@@rm $@@.in
@end group
@@ -8001,6 +8047,10 @@ implications of using the @code{shell} function within recursively
expanded variables vs.@: simply expanded variables (@pxref{Flavors, ,The
Two Flavors of Variables}).
@vindex .SHELLSTATUS
After the @code{shell} function or @samp{!=} assignment operator is
used, its exit status is placed in the @code{.SHELLSTATUS} variable.
Here are some examples of the use of the @code{shell} function:
@example
@@ -8927,7 +8977,7 @@ retained for compatibility.
@menu
* Using Implicit:: How to use an existing implicit rule
to get the recipes for updating a file.
* Catalogue of Rules:: A list of built-in implicit rules.
* Catalogue of Rules:: A list of built-in rules.
* Implicit Variables:: How to change what predefined rules do.
* Chained Rules:: How to use a chain of implicit rules.
* Pattern Rules:: How to define new implicit rules.
@@ -8979,7 +9029,7 @@ compiler; and so on.
Of course, when you write the makefile, you know which implicit rule you
want @code{make} to use, and you know it will choose that one because you
know which possible prerequisite files are supposed to exist.
@xref{Catalogue of Rules, ,Catalogue of Implicit Rules},
@xref{Catalogue of Rules, ,Catalogue of Built-In Rules},
for a catalogue of all the predefined implicit rules.
Above, we said an implicit rule applies if the required prerequisites ``exist
@@ -9009,7 +9059,7 @@ make an object file, a @file{.o} file, from a Pascal source file, a
@file{.p} file. For example, if @file{foo.c} also exists, the implicit
rule to make an object file from a C source file is used instead,
because it appears before the Pascal rule in the list of predefined
implicit rules (@pxref{Catalogue of Rules, , Catalogue of Implicit
implicit rules (@pxref{Catalogue of Rules, , Catalogue of Built-In
Rules}).
If you do not want an implicit rule to be used for a target that has no
@@ -9017,7 +9067,7 @@ recipe, you can give that target an empty recipe by writing a semicolon
(@pxref{Empty Recipes, ,Defining Empty Recipes}).
@node Catalogue of Rules, Implicit Variables, Using Implicit, Implicit Rules
@section Catalogue of Implicit Rules
@section Catalogue of Built-In Rules
@cindex implicit rule, predefined
@cindex rule, implicit, predefined
@@ -10667,7 +10717,7 @@ in the normal way (@pxref{Suffix Rules}). Thus a double-suffix rule
@w{@samp{.@var{x}.a}} produces two pattern rules: @samp{@w{(%.o):}
@w{%.@var{x}}} and @samp{@w{%.a}: @w{%.@var{x}}}.@refill
@node Extending make, Features, Archives, Top
@node Extending make, Integrating make, Archives, Top
@chapter Extending GNU @code{make}
@cindex make extensions
@@ -10910,7 +10960,8 @@ The @code{load} directive and extension capability is considered a
``technology preview'' in this release of GNU make. We encourage you
to experiment with this feature and we appreciate any feedback on it.
However we cannot guarantee to maintain backward-compatibility in the
next release.
next release. Consider using GNU Guile instead for extending GNU make
(@pxref{Guile Function, ,The @code{guile} Function}).
@end quotation
@end cartouche
@@ -10978,7 +11029,9 @@ same directive.
The initializing function will be provided the file name and line
number of the invocation of the @code{load} operation. It should
return a value of type @code{int}, which must be @code{0} on failure
and non-@code{0} on success.
and non-@code{0} on success. If the return value is @code{-1}, then
GNU make will @emph{not} attempt to rebuild the object file
(@pxref{Remaking Loaded Objects, ,How Loaded Objects Are Remade}).
For example:
@@ -11105,16 +11158,14 @@ arguments are as follows:
@table @code
@item name
The function name. This is what the makefile should use to invoke the
function. The name must be between 1 and 255 characters long.
function. The name must be between 1 and 255 characters long and it
may only contain alphanumeric, period (@samp{.}), dash (@samp{-}), and
underscore (@samp{_}) characters. It may not begin with a period.
@item func_ptr
A pointer to a function that @code{make} will invoke when it expands
the function in a makefile. This function must be defined by the
loaded object. GNU @code{make} will call it with three arguments:
@code{name} (the same name as above), @code{argc} (the number of
arguments to the function), and @code{argv} (the list of arguments to
the function). The last argument (that is, @code{argv[argc]} will be
null (@code{0}).
loaded object.
@item min_args
The minimum number of arguments the function will accept. Must be
@@ -11130,12 +11181,30 @@ arguments. If the value is 0, then any number of arguments is
accepted. If the value is greater than 0, then it must be greater
than or equal to @code{min_args}.
@item expand_args
If this value is 0, then @code{make} will not expand the arguments to
the function before passing them to @code{func_ptr}. If the value is
non-0, then the arguments will be expanded first.
@item flags
Flags that specify how this function will operate; the desired flags
should be OR'd together. If the @code{GMK_FUNC_NOEXPAND} flag is
given then the function arguments will not be expanded before the
function is called; otherwise they will be expanded first.
@end table
@subsubheading Registered Function Interface
@findex gmk_func_ptr
A function registered with @code{make} must match the
@code{gmk_func_ptr} type. It will be invoked with three parameters:
@code{name} (the name of the function), @code{argc} (the number of
arguments to the function), and @code{argv} (an array of pointers to
arguments to the function). The last pointer (that is,
@code{argv[argc]}) will be null (@code{0}).
The return value of the function is the result of expanding the
function. If the function expands to nothing the return value may be
null. Otherwise, it must be a pointer to a string created with
@code{gmk_alloc}. Once the function returns, @code{make} owns this
string and will free it when appropriate; it cannot be accessed by the
loaded object.
@subsubheading GNU @code{make} Facilities
There are some facilities exported by GNU @code{make} for use by
@@ -11174,6 +11243,12 @@ should never pass memory that you've allocated directly to any
memory returned to you by any @code{make} function. Instead, use the
@code{gmk_alloc} and @code{gmk_free} functions.
In particular, the string returned to @code{make} by a function
registered using @code{gmk_add_function} @emph{must} be allocated
using @code{gmk_alloc}, and the string returned from the @code{make}
@code{gmk_expand} function @emph{must} be freed (when no longer
needed) using @code{gmk_free}.
@table @code
@item gmk_alloc
@findex gmk_alloc
@@ -11283,7 +11358,225 @@ cc -shared -fPIC -o mk_temp.so mk_temp.c
Temporary filename: tmpfile.A7JEwd
@end example
@node Features, Missing, Extending make, Top
@node Integrating make, Features, Extending make, Top
@chapter Integrating GNU @code{make}
@cindex make integration
GNU @code{make} is often one component in a larger system of tools,
including integrated development environments, compiler toolchains,
and others. The role of @code{make} is to start commands and
determine whether they succeeded or not: no special integration is
needed to accomplish that. However, sometimes it is convenient to
bind @code{make} more tightly with other parts of the system, both
higher-level (tools that invoke @code{make}) and lower-level (tools
that @code{make} invokes).
@menu
* Job Slots:: Share job slots with GNU @code{make}.
* Terminal Output:: Control output to terminals.
@end menu
@node Job Slots, Terminal Output, Integrating make, Integrating make
@section Sharing Job Slots with GNU @code{make}
@cindex job slots, sharing
@cindex tools, sharing job slots
GNU @code{make} has the ability to run multiple recipes in parallel
(@pxref{Parallel, ,Parallel Execution}) and to cap the total number of
parallel jobs even across recursive invocations of @code{make}
(@pxref{Options/Recursion, ,Communicating Options to a
Sub-@code{make}}). Tools that @code{make} invokes which are also able
to run multiple operations in parallel, either using multiple threads
or multiple processes, can be enhanced to participate in GNU
@code{make}'s job management facility to ensure that the total number
of active threads/processes running on the system does not exceed the
maximum number of slots provided to GNU @code{make}. @refill
@cindex jobserver
GNU @code{make} uses a method called the ``jobserver'' to control the
number of active jobs across recursive invocations. The actual
implementation of the jobserver varies across different operating
systems, but some fundamental aspects are always true.
First, only command lines that @code{make} understands to be recursive
invocations of @code{make} (@pxref{MAKE Variable, ,How the @code{MAKE}
Variable Works}) will have access to the jobserver. When writing
makefiles you must be sure to mark the command as recursive (most
commonly by prefixing the command line with the @code{+} indicator
(@pxref{Recursion, ,Recursive Use of @code{make}}).
Second, @code{make} will provide information necessary for accessing
the jobserver through the environment to its children, in the
@code{MAKEFLAGS} environment variable. Tools which want to
participate in the jobserver protocol will need to parse this
environment variable, as described in subsequent sections.
Third, every command @code{make} starts has one implicit job slot
reserved for it before it starts. Any tool which wants to participate
in the jobserver protocol should assume it can always run one job
without having to contact the jobserver at all.
Finally, it's critical that tools that participate in the jobserver
protocol return the exact number of slots they obtained from the
jobserver back to the jobserver before they exit, even under error
conditions. Remember that the implicit job slot should @strong{not}
be returned to the jobserver! Returning too few slots means that
those slots will be lost for the rest of the build process; returning
too many slots means that extra slots will be available. The
top-level @code{make} command will print an error message at the end
of the build if it detects an incorrect number of slots available in
the jobserver.
As an example, suppose you are implementing a linker which provides
for multithreaded operation. You would like to enhance the linker so
that if it is invoked by GNU @code{make} it can participate in the
jobserver protocol to control how many threads are used during link.
First you will need to modify the linker to determine if the
@code{MAKEFLAGS} environment variable is set. Next you will need to
parse the value of that variable to determine if the jobserver is
available, and how to access it. If it is available then you can
access it to obtain job slots controlling how much parallelism your
tool can use. Once done your tool must return those job slots back to
the jobserver.
@menu
* POSIX Jobserver:: Using the jobserver on POSIX systems.
* Windows Jobserver:: Using the jobserver on Windows systems.
@end menu
@node POSIX Jobserver, Windows Jobserver, Job Slots, Job Slots
@subsection POSIX Jobserver Interaction
@cindex jobserver on POSIX
On POSIX systems the jobserver is implemented as a simple UNIX pipe.
The pipe will be pre-loaded with one single-character token for each
available job. To obtain an extra slot you must read a single
character from the jobserver pipe; to release a slot you must write a
single character back into the jobserver pipe.
To access the pipe you must parse the @code{MAKEFLAGS} variable and
look for the argument string @code{--jobserver-auth=R,W} where
@samp{R} and @samp{W} are non-negative integers representing file
descriptors: @samp{R} is the read file descriptor and @samp{W} is the
write file descriptor.
It's important that when you release the job slot, you write back the
same character you read from the pipe for that slot. Don't assume
that all tokens are the same character; different characters may have
different meanings to GNU @code{make}. The order is not important,
since @code{make} has no idea in what order jobs will complete anyway.
There are various error conditions you must consider to ensure your
implementation is robust:
@itemize @bullet
@item
Usually you will have a command-line argument controlling the parallel
operation of your tool. Consider whether your tool should detect
situations where both the jobserver and the command-line argument are
specified, and how it should react.
@item
If your tool determines that the @code{--jobserver-auth} option is
available in @code{MAKEFLAGS} but that the file descriptors specified
are closed, this means that the calling @code{make} process did not
think that your tool was a recursive @code{make} invocation (e.g., the
command line was not prefixed with a @code{+} character). You should
notify your users of this situation.
@item
Your tool should also examine the first word of the @code{MAKEFLAGS}
variable and look for the character @code{n}. If this character is
present then @code{make} was invoked with the @samp{-n} option and
your tool should stop without performing any operations.
@item
Your tool should be sure to write back the tokens it read, even under
error conditions. This includes not only errors in your tool but also
outside influences such as interrupts (@code{SIGINT}), etc. You may
want to install signal handlers to manage this write-back.
@end itemize
@node Windows Jobserver, , POSIX Jobserver, Job Slots
@subsection Windows Jobserver Interaction
@cindex jobserver on Windows
On Windows systems the jobserver is implemented as a named semaphore.
The semaphore will be set with an initial count equal to the number of
available slots; to obtain a slot you must wait on the semaphore (with
or without a timeout). To release a slot, release the semaphore.
To access the semaphore you must parse the @code{MAKEFLAGS} variable and
look for the argument string @code{--jobserver-auth=NAME} where
@samp{NAME} is the name of the named semaphore. Use this name with
@code{OpenSemaphore} to create a handle to the semaphore.
There are various error conditions you must consider to ensure your
implementation is robust:
@itemize @bullet
@item
Usually you will have a command-line argument controlling the parallel
operation of your tool. Consider whether your tool should detect
situations where both the jobserver and the command-line argument are
specified, and how it should react.
@item
Your tool should be sure to release the semaphore for the tokens it
read, even under error conditions. This includes not only errors in
your tool but also outside influences such as interrupts
(@code{SIGINT}), etc. You may want to install signal handlers to
manage this write-back.
@end itemize
@node Terminal Output, , Job Slots, Integrating make
@section Synchronized Terminal Output
@cindex parallel output to terminal
@cindex terminal, output to
Normally GNU @code{make} will invoke all commands with access to the
same standard and error outputs that @code{make} itself was started
with. A number of tools will detect whether the output is a terminal
or not-a-terminal, and use this information to change the output
style. For example if the output goes to a terminal the tool may add
control characters that set color, or even change the location of the
cursor. If the output is not going to a terminal then these special
control characters are not emitted so that they don't corrupt log
files, etc.
The @code{--output-sync} (@pxref{Parallel Output, ,Output During
Parallel Output}) option will defeat the terminal detection. When
output synchronization is enabled GNU @code{make} arranges for all
command output to be written to a file, so that its output can be
written as a block without interference from other commands. This
means that all tools invoked by @code{make} will believe that their
output is not going to be displayed on a terminal, even when it will
be (because @code{make} will display it there after the command is
completed).
In order to facilitate tools which would like to determine whether or
not their output will be displayed on a terminal, GNU @code{make} will
set the @code{MAKE_TERMOUT} and @code{MAKE_TERMERR} environment
variables before invoking any commands. Tools which would like to
determine whether standard or error output (respectively) will be
displayed on a terminal can check these environment variables to
determine if they exist and contain a non-empty value. If so the tool
can assume that the output will (eventually) be displayed on a
terminal. If the variables are not set or have an empty value, then
the tool should fall back to its normal methods of detecting whether
output is going to a terminal or not.
The content of the variables can be parsed to determine the type of
terminal which will be used to display the output.
Similarly, environments which invoke @code{make} and would like to
capture the output and eventually display it on a terminal (or some
display which can interpret terminal control characters) can set these
variables before invoking @code{make}. GNU @code{make} will not
modify these environment variables if they already exist when it
starts.
@node Features, Missing, Integrating make, Top
@chapter Features of GNU @code{make}
@cindex features of GNU @code{make}
@cindex portability
@@ -11540,7 +11833,7 @@ functionality in that it will check out SCCS files for makefiles.
@item
Various new built-in implicit rules.
@xref{Catalogue of Rules, ,Catalogue of Implicit Rules}.
@xref{Catalogue of Rules, ,Catalogue of Built-In Rules}.
@item
Load dynamic objects which can modify the behavior of @code{make}.
@@ -11663,7 +11956,7 @@ special treatment.
This appendix summarizes the directives, text manipulation functions,
and special variables which GNU @code{make} understands.
@xref{Special Targets}, @ref{Catalogue of Rules, ,Catalogue of Implicit Rules},
@xref{Special Targets}, @ref{Catalogue of Rules, ,Catalogue of Built-In Rules},
and @ref{Options Summary, ,Summary of Options},
for other summaries.
@@ -12039,9 +12332,9 @@ variable has no effect on the operation of @code{make}.@*
@item CURDIR
Set to the pathname of the current working directory (after all
@code{-C} options are processed, if any). Setting this variable has no
effect on the operation of @code{make}.@*
Set to the absolute pathname of the current working directory (after
all @code{-C} options are processed, if any). Setting this variable
has no effect on the operation of @code{make}.@*
@xref{Recursion, ,Recursive Use of @code{make}}.
@item SUFFIXES

View File

@@ -1,5 +1,5 @@
@echo off
rem Copyright (C) 1998-2013 Free Software Foundation, Inc.
rem Copyright (C) 1998-2016 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

View File

@@ -1,5 +1,5 @@
/* Variable expansion functions for GNU Make.
Copyright (C) 1988-2013 Free Software Foundation, Inc.
Copyright (C) 1988-2016 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
@@ -26,7 +26,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Initially, any errors reported when expanding strings will be reported
against the file where the error appears. */
const gmk_floc **expanding_var = &reading_file;
const floc **expanding_var = &reading_file;
/* The next two describe the variable output buffer.
This buffer is used to hold the variable-expansion of a line of the
@@ -96,8 +96,8 @@ char *
recursively_expand_for_file (struct variable *v, struct file *file)
{
char *value;
const gmk_floc *this_var;
const gmk_floc **saved_varp;
const floc *this_var;
const floc **saved_varp;
struct variable_set_list *save = 0;
int set_reading = 0;
@@ -121,9 +121,9 @@ recursively_expand_for_file (struct variable *v, struct file *file)
{
if (!v->exp_count)
/* Expanding V causes infinite recursion. Lose. */
fatal (*expanding_var,
_("Recursive variable '%s' references itself (eventually)"),
v->name);
OS (fatal, *expanding_var,
_("Recursive variable '%s' references itself (eventually)"),
v->name);
--v->exp_count;
}
@@ -235,8 +235,10 @@ variable_expand_string (char *line, const char *string, long length)
switch (*p)
{
case '$':
/* $$ seen means output one $ to the variable output buffer. */
o = variable_buffer_output (o, p, 1);
case '\0':
/* $$ or $ at the end of the string means output one $ to the
variable output buffer. */
o = variable_buffer_output (o, p1, 1);
break;
case '(':
@@ -266,7 +268,7 @@ variable_expand_string (char *line, const char *string, long length)
end = strchr (beg, closeparen);
if (end == 0)
/* Unterminated variable reference. */
fatal (*expanding_var, _("unterminated variable reference"));
O (fatal, *expanding_var, _("unterminated variable reference"));
p1 = lindex (beg, end, '$');
if (p1 != 0)
{
@@ -377,16 +379,12 @@ variable_expand_string (char *line, const char *string, long length)
Look up the value of the variable. */
o = reference_variable (o, beg, end - beg);
if (abeg)
free (abeg);
}
break;
case '\0':
break;
default:
if (isblank ((unsigned char)p[-1]))
if (ISSPACE (p[-1]))
break;
/* A $ followed by a random char is a variable reference:
@@ -447,8 +445,7 @@ expand_argument (const char *str, const char *end)
r = allocated_variable_expand (tmp);
if (alloc)
free (alloc);
free (alloc);
return r;
}
@@ -461,7 +458,7 @@ variable_expand_for_file (const char *line, struct file *file)
{
char *result;
struct variable_set_list *savev;
const gmk_floc *savef;
const floc *savef;
if (file == 0)
return variable_expand (line);

66
file.c
View File

@@ -1,5 +1,5 @@
/* Target file management for GNU Make.
Copyright (C) 1988-2013 Free Software Foundation, Inc.
Copyright (C) 1988-2016 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
@@ -18,8 +18,8 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#include <assert.h>
#include "dep.h"
#include "filedef.h"
#include "dep.h"
#include "job.h"
#include "commands.h"
#include "variable.h"
@@ -57,9 +57,6 @@ file_hash_cmp (const void *x, const void *y)
((struct file const *) y)->hname);
}
#ifndef FILE_BUCKETS
#define FILE_BUCKETS 1007
#endif
static struct hash_table files;
/* Whether or not .SECONDARY with no prerequisites was given. */
@@ -75,8 +72,11 @@ lookup_file (const char *name)
{
struct file *f;
struct file file_key;
#if defined(VMS) && !defined(WANT_CASE_SENSITIVE_TARGETS)
#ifdef VMS
int want_vmsify;
#ifndef WANT_CASE_SENSITIVE_TARGETS
char *lname;
#endif
#endif
assert (*name != '\0');
@@ -85,6 +85,7 @@ lookup_file (const char *name)
for names read from makefiles. It is here for names passed
on the command line. */
#ifdef VMS
want_vmsify = (strpbrk (name, "]>:^") != NULL);
# ifndef WANT_CASE_SENSITIVE_TARGETS
if (*name != '.')
{
@@ -100,6 +101,8 @@ lookup_file (const char *name)
while (name[0] == '[' && name[1] == ']' && name[2] != '\0')
name += 2;
while (name[0] == '<' && name[1] == '>' && name[2] != '\0')
name += 2;
#endif
while (name[0] == '.'
#ifdef HAVE_DOS_PATHS
@@ -120,15 +123,19 @@ lookup_file (const char *name)
}
if (*name == '\0')
/* It was all slashes after a dot. */
#if defined(VMS)
name = "[]";
#elif defined(_AMIGA)
name = "";
{
/* It was all slashes after a dot. */
#if defined(_AMIGA)
name = "";
#else
name = "./";
name = "./";
#endif
#if defined(VMS)
/* TODO - This section is probably not needed. */
if (want_vmsify)
name = "[]";
#endif
}
file_key.hname = name;
f = hash_find_item (&files, &file_key);
#if defined(VMS) && !defined(WANT_CASE_SENSITIVE_TARGETS)
@@ -261,22 +268,25 @@ rehash_file (struct file *from_file, const char *to_hname)
to_file->cmds = from_file->cmds;
else if (from_file->cmds != to_file->cmds)
{
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,
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);
else
error (&from_file->cmds->fileinfo,
error (&from_file->cmds->fileinfo, l,
_("Recipe for file '%s' was found by implicit rule search,"),
from_file->name);
error (&from_file->cmds->fileinfo,
l += strlen (to_hname);
error (&from_file->cmds->fileinfo, l,
_("but '%s' is now considered the same file as '%s'."),
from_file->name, to_hname);
error (&from_file->cmds->fileinfo,
error (&from_file->cmds->fileinfo, l,
_("Recipe for '%s' will be ignored in favor of the one for '%s'."),
to_hname, from_file->name);
}
@@ -297,13 +307,14 @@ rehash_file (struct file *from_file, const char *to_hname)
merge_variable_set_lists (&to_file->variables, from_file->variables);
if (to_file->double_colon && from_file->is_target && !from_file->double_colon)
fatal (NILF, _("can't rename single-colon '%s' to double-colon '%s'"),
from_file->name, to_hname);
OSS (fatal, NILF, _("can't rename single-colon '%s' to double-colon '%s'"),
from_file->name, to_hname);
if (!to_file->double_colon && from_file->double_colon)
{
if (to_file->is_target)
fatal (NILF, _("can't rename double-colon '%s' to single-colon '%s'"),
from_file->name, to_hname);
OSS (fatal, NILF,
_("can't rename double-colon '%s' to single-colon '%s'"),
from_file->name, to_hname);
else
to_file->double_colon = from_file->double_colon;
}
@@ -393,7 +404,8 @@ remove_intermediates (int sig)
if (!f->dontcare)
{
if (sig)
error (NILF, _("*** Deleting intermediate file '%s'"), f->name);
OS (error, NILF,
_("*** Deleting intermediate file '%s'"), f->name);
else
{
if (! doneany)
@@ -803,10 +815,11 @@ file_timestamp_cons (const char *fname, time_t stamp, long int ns)
&& product <= ts && ts <= ORDINARY_MTIME_MAX))
{
char buf[FILE_TIMESTAMP_PRINT_LEN_BOUND + 1];
const char *f = fname ? fname : _("Current time");
ts = s <= OLD_MTIME ? ORDINARY_MTIME_MIN : ORDINARY_MTIME_MAX;
file_timestamp_sprintf (buf, ts);
error (NILF, _("%s: Timestamp out of range; substituting %s"),
fname ? fname : _("Current time"), buf);
OSS (error, NILF,
_("%s: Timestamp out of range; substituting %s"), f, buf);
}
return ts;
@@ -1046,9 +1059,10 @@ print_file_data_base (void)
/* Verify the integrity of the data base of files. */
#define VERIFY_CACHED(_p,_n) \
do{\
if (_p->_n && _p->_n[0] && !strcache_iscached (_p->_n)) \
error (NULL, _("%s: Field '%s' not cached: %s"), _p->name, # _n, _p->_n); \
do{ \
if (_p->_n && _p->_n[0] && !strcache_iscached (_p->_n)) \
error (NULL, strlen (_p->name) + CSTRLEN (# _n) + strlen (_p->_n), \
_("%s: Field '%s' not cached: %s"), _p->name, # _n, _p->_n); \
}while(0)
static void

View File

@@ -1,5 +1,5 @@
/* Definition of target file data structures for GNU Make.
Copyright (C) 1988-2013 Free Software Foundation, Inc.
Copyright (C) 1988-2016 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
@@ -103,7 +103,7 @@ struct file
};
extern struct file *suffix_file, *default_file;
extern struct file *default_file;
struct file *lookup_file (const char *name);
@@ -117,9 +117,12 @@ void rehash_file (struct file *file, const char *name);
void set_command_state (struct file *file, enum cmd_state state);
void notice_finished_file (struct file *file);
void init_hash_files (void);
void verify_file_data_base (void);
char *build_target_list (char *old_list);
void print_prereqs (const struct dep *deps);
void print_file_data_base (void);
int try_implicit_rule (struct file *file, unsigned int depth);
int stemlen_compare (const void *v1, const void *v2);
#if FILE_TIMESTAMP_HI_RES
# define FILE_TIMESTAMP_STAT_MODTIME(fname, st) \
@@ -143,7 +146,7 @@ void print_file_data_base (void);
& ((1 << FILE_TIMESTAMP_LO_BITS) - 1)))
/* Upper bound on length of string "YYYY-MM-DD HH:MM:SS.NNNNNNNNN"
representing a file timestamp. The upper bound is not necessarily 19,
representing a file timestamp. The upper bound is not necessarily 29,
since the year might be less than -999 or greater than 9999.
Subtract one for the sign bit if in case file timestamps can be negative;

View File

@@ -1,5 +1,5 @@
/* Builtin function expansion for GNU Make.
Copyright (C) 1988-2013 Free Software Foundation, Inc.
Copyright (C) 1988-2016 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
@@ -31,7 +31,7 @@ struct function_table_entry
{
union {
char *(*func_ptr) (char *output, char **argv, const char *fname);
char *(*alloc_func_ptr) (const char *fname, int argc, char **argv);
gmk_func_ptr alloc_func_ptr;
} fptr;
const char *name;
unsigned char len;
@@ -115,8 +115,8 @@ subst_expand (char *o, const char *text, const char *subst, const char *replace,
/* If we're substituting only by fully matched words,
or only at the ends of words, check that this case qualifies. */
if (by_word
&& ((p > text && !isblank ((unsigned char)p[-1]))
|| ! STOP_SET (p[slen], MAP_BLANK|MAP_NUL)))
&& ((p > text && !ISSPACE (p[-1]))
|| ! STOP_SET (p[slen], MAP_SPACE|MAP_NUL)))
/* Struck out. Output the rest of the string that is
no longer to be replaced. */
o = variable_buffer_output (o, subst, slen);
@@ -269,19 +269,19 @@ patsubst_expand (char *o, const char *text, char *pattern, char *replace)
static const struct function_table_entry *
lookup_function (const char *s)
{
struct function_table_entry function_table_entry_key;
const char *e = s;
while (*e && ( (*e >= 'a' && *e <= 'z') || *e == '-'))
while (STOP_SET (*e, MAP_USERFUNC))
e++;
if (*e == '\0' || isblank ((unsigned char) *e))
{
struct function_table_entry function_table_entry_key;
function_table_entry_key.name = s;
function_table_entry_key.len = e - s;
return hash_find_item (&function_table, &function_table_entry_key);
}
return 0;
if (e == s || !STOP_SET(*e, MAP_NUL|MAP_SPACE))
return NULL;
function_table_entry_key.name = s;
function_table_entry_key.len = e - s;
return hash_find_item (&function_table, &function_table_entry_key);
}
@@ -519,8 +519,25 @@ func_notdir_suffix (char *o, char **argv, const char *funcname)
int is_suffix = funcname[0] == 's';
int is_notdir = !is_suffix;
int stop = MAP_PATHSEP | (is_suffix ? MAP_DOT : 0);
int stop = MAP_DIRSEP | (is_suffix ? MAP_DOT : 0);
#ifdef VMS
/* For VMS list_iterator points to a comma separated list. To use the common
[find_]next_token, create a local copy and replace the commas with
spaces. Obviously, there is a problem if there is a ',' in the VMS filename
(can only happen on ODS5), the same problem as with spaces in filenames,
which seems to be present in make on all platforms. */
char *vms_list_iterator = alloca(strlen(list_iterator) + 1);
int i;
for (i = 0; list_iterator[i]; i++)
if (list_iterator[i] == ',')
vms_list_iterator[i] = ' ';
else
vms_list_iterator[i] = list_iterator[i];
vms_list_iterator[i] = list_iterator[i];
while ((p2 = find_next_token((const char**) &vms_list_iterator, &len)) != 0)
#else
while ((p2 = find_next_token (&list_iterator, &len)) != 0)
#endif
{
const char *p = p2 + len - 1;
@@ -548,7 +565,13 @@ func_notdir_suffix (char *o, char **argv, const char *funcname)
if (is_notdir || p >= p2)
{
#ifdef VMS
if (vms_comma_separator)
o = variable_buffer_output (o, ",", 1);
else
#endif
o = variable_buffer_output (o, " ", 1);
doneany = 1;
}
}
@@ -572,8 +595,21 @@ func_basename_dir (char *o, char **argv, const char *funcname)
int is_basename = funcname[0] == 'b';
int is_dir = !is_basename;
int stop = MAP_PATHSEP | (is_basename ? MAP_DOT : 0) | MAP_NUL;
int stop = MAP_DIRSEP | (is_basename ? MAP_DOT : 0) | MAP_NUL;
#ifdef VMS
/* As in func_notdir_suffix ... */
char *vms_p3 = alloca (strlen(p3) + 1);
int i;
for (i = 0; p3[i]; i++)
if (p3[i] == ',')
vms_p3[i] = ' ';
else
vms_p3[i] = p3[i];
vms_p3[i] = p3[i];
while ((p2 = find_next_token((const char**) &vms_p3, &len)) != 0)
#else
while ((p2 = find_next_token (&p3, &len)) != 0)
#endif
{
const char *p = p2 + len - 1;
while (p >= p2 && ! STOP_SET (*p, stop))
@@ -590,7 +626,13 @@ func_basename_dir (char *o, char **argv, const char *funcname)
#endif
else if (is_dir)
#ifdef VMS
o = variable_buffer_output (o, "[]", 2);
{
extern int vms_report_unix_paths;
if (vms_report_unix_paths)
o = variable_buffer_output (o, "./", 2);
else
o = variable_buffer_output (o, "[]", 2);
}
#else
#ifndef _AMIGA
o = variable_buffer_output (o, "./", 2);
@@ -602,7 +644,13 @@ func_basename_dir (char *o, char **argv, const char *funcname)
/* The entire name is the basename. */
o = variable_buffer_output (o, p2, len);
o = variable_buffer_output (o, " ", 1);
#ifdef VMS
if (vms_comma_separator)
o = variable_buffer_output (o, ",", 1);
else
#endif
o = variable_buffer_output (o, " ", 1);
doneany = 1;
}
@@ -707,9 +755,9 @@ func_words (char *o, char **argv, const char *funcname UNUSED)
char *
strip_whitespace (const char **begpp, const char **endpp)
{
while (*begpp <= *endpp && isspace ((unsigned char)**begpp))
while (*begpp <= *endpp && ISSPACE (**begpp))
(*begpp) ++;
while (*endpp >= *begpp && isspace ((unsigned char)**endpp))
while (*endpp >= *begpp && ISSPACE (**endpp))
(*endpp) --;
return (char *)*begpp;
}
@@ -726,7 +774,7 @@ check_numeric (const char *s, const char *msg)
break;
if (s <= end || end - beg < 0)
fatal (*expanding_var, "%s: '%s'", msg, beg);
OSS (fatal, *expanding_var, "%s: '%s'", msg, beg);
}
@@ -743,8 +791,8 @@ func_word (char *o, char **argv, const char *funcname UNUSED)
i = atoi (argv[0]);
if (i == 0)
fatal (*expanding_var,
_("first argument to 'word' function must be greater than 0"));
O (fatal, *expanding_var,
_("first argument to 'word' function must be greater than 0"));
end_p = argv[1];
while ((p = find_next_token (&end_p, 0)) != 0)
@@ -770,8 +818,8 @@ func_wordlist (char *o, char **argv, const char *funcname UNUSED)
start = atoi (argv[0]);
if (start < 1)
fatal (*expanding_var,
"invalid first argument to 'wordlist' function: '%d'", start);
ON (fatal, *expanding_var,
"invalid first argument to 'wordlist' function: '%d'", start);
count = atoi (argv[1]) - start + 1;
@@ -822,8 +870,12 @@ func_foreach (char *o, char **argv, const char *funcname UNUSED)
unsigned int len;
struct variable *var;
/* Clean up the variable name by removing whitespace. */
char *vp = next_token (varname);
end_of_token (vp)[0] = '\0';
push_new_variable_scope ();
var = define_variable (varname, strlen (varname), "", o_automatic, 0);
var = define_variable (vp, strlen (vp), "", o_automatic, 0);
/* loop through LIST, put the value in VAR and expand BODY */
while ((p = find_next_token (&list_iterator, &len)) != 0)
@@ -1033,10 +1085,9 @@ func_strip (char *o, char **argv, const char *funcname UNUSED)
int i=0;
const char *word_start;
while (isspace ((unsigned char)*p))
++p;
NEXT_TOKEN (p);
word_start = p;
for (i=0; *p != '\0' && !isspace ((unsigned char)*p); ++p, ++i)
for (i=0; *p != '\0' && !ISSPACE (*p); ++p, ++i)
{}
if (!i)
break;
@@ -1082,10 +1133,10 @@ func_error (char *o, char **argv, const char *funcname)
switch (*funcname)
{
case 'e':
fatal (reading_file, "%s", msg);
OS (fatal, reading_file, "%s", msg);
case 'w':
error (reading_file, "%s", msg);
OS (error, reading_file, "%s", msg);
break;
case 'i':
@@ -1094,7 +1145,7 @@ func_error (char *o, char **argv, const char *funcname)
break;
default:
fatal (*expanding_var, "Internal error: func_error: '%s'", funcname);
OS (fatal, *expanding_var, "Internal error: func_error: '%s'", funcname);
}
/* The warning function expands to the empty string. */
@@ -1402,10 +1453,23 @@ fold_newlines (char *buffer, unsigned int *length, int trim_newlines)
*length = last_nonnl - buffer;
}
pid_t shell_function_pid = 0;
static int shell_function_completed;
void
shell_completed (int exit_code, int exit_sig)
{
char buf[256];
int shell_function_pid = 0, shell_function_completed;
shell_function_pid = 0;
if (exit_sig == 0 && exit_code == 127)
shell_function_completed = -1;
else
shell_function_completed = 1;
sprintf (buf, "%d", exit_code);
define_variable_cname (".SHELLSTATUS", buf, o_override, 0);
}
#ifdef WINDOWS32
/*untested*/
@@ -1416,7 +1480,7 @@ int shell_function_pid = 0, shell_function_completed;
int
windows32_openpipe (int *pipedes, pid_t *pid_p, char **command_argv, char **envp)
windows32_openpipe (int *pipedes, int errfd, pid_t *pid_p, char **command_argv, char **envp)
{
SECURITY_ATTRIBUTES saAttr;
HANDLE hIn = INVALID_HANDLE_VALUE;
@@ -1457,11 +1521,12 @@ windows32_openpipe (int *pipedes, pid_t *pid_p, char **command_argv, char **envp
}
if (hIn == INVALID_HANDLE_VALUE)
{
error (NILF, _("windows32_openpipe: DuplicateHandle(In) failed (e=%ld)\n"), e);
ON (error, NILF,
_("windows32_openpipe: DuplicateHandle(In) failed (e=%ld)\n"), e);
return -1;
}
}
tmpErr = GetStdHandle (STD_ERROR_HANDLE);
tmpErr = (HANDLE)_get_osfhandle (errfd);
if (DuplicateHandle (GetCurrentProcess (), tmpErr,
GetCurrentProcess (), &hErr,
0, TRUE, DUPLICATE_SAME_ACCESS) == FALSE)
@@ -1480,14 +1545,15 @@ windows32_openpipe (int *pipedes, pid_t *pid_p, char **command_argv, char **envp
}
if (hErr == INVALID_HANDLE_VALUE)
{
error (NILF, _("windows32_openpipe: DuplicateHandle(Err) failed (e=%ld)\n"), e);
ON (error, NILF,
_("windows32_openpipe: DuplicateHandle(Err) failed (e=%ld)\n"), e);
return -1;
}
}
if (! CreatePipe (&hChildOutRd, &hChildOutWr, &saAttr, 0))
{
error (NILF, _("CreatePipe() failed (e=%ld)\n"), GetLastError());
ON (error, NILF, _("CreatePipe() failed (e=%ld)\n"), GetLastError());
return -1;
}
@@ -1495,7 +1561,7 @@ windows32_openpipe (int *pipedes, pid_t *pid_p, char **command_argv, char **envp
if (!hProcess)
{
error (NILF, _("windows32_openpipe(): process_init_fd() failed\n"));
O (error, NILF, _("windows32_openpipe(): process_init_fd() failed\n"));
return -1;
}
@@ -1552,8 +1618,7 @@ msdos_openpipe (int* pipedes, int *pidp, char *text)
extern int dos_command_running, dos_status;
/* Make sure not to bother processing an empty line. */
while (isblank ((unsigned char)*text))
++text;
NEXT_TOKEN (text);
if (*text == '\0')
return 0;
@@ -1583,14 +1648,15 @@ msdos_openpipe (int* pipedes, int *pidp, char *text)
errno = EINTR;
else if (errno == 0)
errno = ENOMEM;
shell_function_completed = -1;
if (fpipe)
pclose (fpipe);
shell_completed (127, 0);
}
else
{
pipedes[0] = fileno (fpipe);
*pidp = 42; /* Yes, the Meaning of Life, the Universe, and Everything! */
errno = e;
shell_function_completed = 1;
}
return fpipe;
}
@@ -1608,7 +1674,7 @@ char *
func_shell_base (char *o, char **argv, int trim_newlines)
{
fprintf (stderr, "This platform does not support shell\n");
die (EXIT_FAILURE);
die (MAKE_TROUBLE);
return NULL;
}
@@ -1620,7 +1686,7 @@ char *
func_shell_base (char *o, char **argv, int trim_newlines)
{
char *batch_filename = NULL;
int errfd;
#ifdef __MSDOS__
FILE *fpipe;
#endif
@@ -1636,9 +1702,9 @@ func_shell_base (char *o, char **argv, int trim_newlines)
are used to run the commands, because we normally refrain from
creating batch files under -n. */
int j_p_f = just_print_flag;
just_print_flag = 0;
#endif
/* Construct the argument list. */
command_argv = construct_command_argv (argv[0], NULL, NULL, 0,
&batch_filename);
@@ -1649,18 +1715,18 @@ func_shell_base (char *o, char **argv, int trim_newlines)
#endif
return o;
}
#endif
#endif /* !__MSDOS__ */
/* Using a target environment for 'shell' loses in cases like:
export var = $(shell echo foobie)
because target_environment hits a loop trying to expand $(var)
to put it in the environment. This is even more confusing when
var was not explicitly exported, but just appeared in the
calling environment.
export var = $(shell echo foobie)
bad := $(var)
because target_environment hits a loop trying to expand $(var) to put it
in the environment. This is even more confusing when 'var' was not
explicitly exported, but just appeared in the calling environment.
See Savannah bug #10593.
envp = target_environment (NILF);
envp = target_environment (NULL);
*/
envp = environ;
@@ -1669,7 +1735,8 @@ func_shell_base (char *o, char **argv, int trim_newlines)
if (reading_file && reading_file->filenm)
{
char *p = alloca (strlen (reading_file->filenm)+11+4);
sprintf (p, "%s:%lu: ", reading_file->filenm, reading_file->lineno);
sprintf (p, "%s:%lu: ", reading_file->filenm,
reading_file->lineno + reading_file->offset);
error_prefix = p;
}
else
@@ -1678,6 +1745,9 @@ func_shell_base (char *o, char **argv, int trim_newlines)
/* Set up the output in case the shell writes something. */
output_start ();
errfd = (output_context && output_context->err >= 0
? output_context->err : FD_STDERR);
#if defined(__MSDOS__)
fpipe = msdos_openpipe (pipedes, &pid, argv[0]);
if (pipedes[0] < 0)
@@ -1685,19 +1755,20 @@ func_shell_base (char *o, char **argv, int trim_newlines)
perror_with_name (error_prefix, "pipe");
return o;
}
#elif defined(WINDOWS32)
windows32_openpipe (pipedes, &pid, command_argv, envp);
windows32_openpipe (pipedes, errfd, &pid, command_argv, envp);
/* Restore the value of just_print_flag. */
just_print_flag = j_p_f;
if (pipedes[0] < 0)
{
/* Open of the pipe failed, mark as failed execution. */
shell_function_completed = -1;
shell_completed (127, 0);
perror_with_name (error_prefix, "pipe");
return o;
}
else
#else
if (pipe (pipedes) < 0)
{
@@ -1705,115 +1776,113 @@ func_shell_base (char *o, char **argv, int trim_newlines)
return o;
}
# ifdef __EMX__
/* close some handles that are unnecessary for the child process */
/* Close handles that are unnecessary for the child process. */
CLOSE_ON_EXEC(pipedes[1]);
CLOSE_ON_EXEC(pipedes[0]);
/* Never use fork()/exec() here! Use spawn() instead in exec_command() */
pid = child_execute_job (0, pipedes[1], command_argv, envp);
if (pid < 0)
perror_with_name (error_prefix, "spawn");
# else /* ! __EMX__ */
pid = fork ();
if (pid < 0)
perror_with_name (error_prefix, "fork");
else if (pid == 0)
{
#ifdef SET_STACK_SIZE
/* Reset limits, if necessary. */
if (stack_limit.rlim_cur)
setrlimit (RLIMIT_STACK, &stack_limit);
#endif
child_execute_job (0, pipedes[1], command_argv, envp);
}
else
# endif
#endif
{
/* We are the parent. */
char *buffer;
unsigned int maxlen, i;
int cc;
/* Record the PID for reap_children. */
shell_function_pid = pid;
{
struct output out;
out.syncout = 1;
out.out = pipedes[1];
out.err = errfd;
pid = child_execute_job (&out, 1, command_argv, envp);
}
if (pid < 0)
{
perror_with_name (error_prefix, "fork");
return o;
}
#endif
{
char *buffer;
unsigned int maxlen, i;
int cc;
/* Record the PID for reap_children. */
shell_function_pid = pid;
#ifndef __MSDOS__
shell_function_completed = 0;
shell_function_completed = 0;
/* Free the storage only the child needed. */
free (command_argv[0]);
free (command_argv);
/* Free the storage only the child needed. */
free (command_argv[0]);
free (command_argv);
/* Close the write side of the pipe. We test for -1, since
pipedes[1] is -1 on MS-Windows, and some versions of MS
libraries barf when 'close' is called with -1. */
if (pipedes[1] >= 0)
close (pipedes[1]);
/* Close the write side of the pipe. We test for -1, since
pipedes[1] is -1 on MS-Windows, and some versions of MS
libraries barf when 'close' is called with -1. */
if (pipedes[1] >= 0)
close (pipedes[1]);
#endif
/* Set up and read from the pipe. */
/* Set up and read from the pipe. */
maxlen = 200;
buffer = xmalloc (maxlen + 1);
maxlen = 200;
buffer = xmalloc (maxlen + 1);
/* Read from the pipe until it gets EOF. */
for (i = 0; ; i += cc)
{
if (i == maxlen)
{
maxlen += 512;
buffer = xrealloc (buffer, maxlen + 1);
}
/* Read from the pipe until it gets EOF. */
for (i = 0; ; i += cc)
{
if (i == maxlen)
{
maxlen += 512;
buffer = xrealloc (buffer, maxlen + 1);
}
EINTRLOOP (cc, read (pipedes[0], &buffer[i], maxlen - i));
if (cc <= 0)
break;
}
buffer[i] = '\0';
EINTRLOOP (cc, read (pipedes[0], &buffer[i], maxlen - i));
if (cc <= 0)
break;
}
buffer[i] = '\0';
/* Close the read side of the pipe. */
/* Close the read side of the pipe. */
#ifdef __MSDOS__
if (fpipe)
(void) pclose (fpipe);
if (fpipe)
{
int st = pclose (fpipe);
shell_completed (st, 0);
}
#else
(void) close (pipedes[0]);
(void) close (pipedes[0]);
#endif
/* Loop until child_handler or reap_children() sets
shell_function_completed to the status of our child shell. */
while (shell_function_completed == 0)
reap_children (1, 0);
/* Loop until child_handler or reap_children() sets
shell_function_completed to the status of our child shell. */
while (shell_function_completed == 0)
reap_children (1, 0);
if (batch_filename)
{
DB (DB_VERBOSE, (_("Cleaning up temporary batch file %s\n"),
batch_filename));
remove (batch_filename);
free (batch_filename);
}
shell_function_pid = 0;
if (batch_filename)
{
DB (DB_VERBOSE, (_("Cleaning up temporary batch file %s\n"),
batch_filename));
remove (batch_filename);
free (batch_filename);
}
shell_function_pid = 0;
/* The child_handler function will set shell_function_completed
to 1 when the child dies normally, or to -1 if it
dies with status 127, which is most likely an exec fail. */
/* shell_completed() will set shell_function_completed to 1 when the
child dies normally, or to -1 if it dies with status 127, which is
most likely an exec fail. */
if (shell_function_completed == -1)
{
/* This likely means that the execvp failed, so we should just
write the error message in the pipe from the child. */
fputs (buffer, stderr);
fflush (stderr);
}
else
{
/* The child finished normally. Replace all newlines in its output
with spaces, and put that in the variable output buffer. */
fold_newlines (buffer, &i, trim_newlines);
o = variable_buffer_output (o, buffer, i);
}
if (shell_function_completed == -1)
{
/* This likely means that the execvp failed, so we should just
write the error message in the pipe from the child. */
fputs (buffer, stderr);
fflush (stderr);
}
else
{
/* The child finished normally. Replace all newlines in its output
with spaces, and put that in the variable output buffer. */
fold_newlines (buffer, &i, trim_newlines);
o = variable_buffer_output (o, buffer, i);
}
free (buffer);
}
free (buffer);
}
return o;
}
@@ -1907,7 +1976,7 @@ func_shell_base (char *o, char **argv, int trim_newlines)
}
#endif /* _AMIGA */
char *
static char *
func_shell (char *o, char **argv, const char *funcname UNUSED)
{
return func_shell_base (o, argv, 1);
@@ -1936,8 +2005,7 @@ func_not (char *o, char **argv, char *funcname UNUSED)
{
const char *s = argv[0];
int result = 0;
while (isspace ((unsigned char)*s))
s++;
NEXT_TOKEN (s);
result = ! (*s);
o = variable_buffer_output (o, result ? "1" : "", result);
return o;
@@ -1946,8 +2014,12 @@ func_not (char *o, char **argv, char *funcname UNUSED)
#ifdef HAVE_DOS_PATHS
#define IS_ABSOLUTE(n) (n[0] && n[1] == ':')
#define ROOT_LEN 3
# ifdef __CYGWIN__
# define IS_ABSOLUTE(n) ((n[0] && n[1] == ':') || STOP_SET (n[0], MAP_DIRSEP))
# else
# define IS_ABSOLUTE(n) (n[0] && n[1] == ':')
# endif
# define ROOT_LEN 3
#else
#define IS_ABSOLUTE(n) (n[0] == '/')
#define ROOT_LEN 1
@@ -1977,9 +2049,9 @@ abspath (const char *name, char *apath)
strcpy (apath, starting_directory);
#ifdef HAVE_DOS_PATHS
if (STOP_SET (name[0], MAP_PATHSEP))
if (STOP_SET (name[0], MAP_DIRSEP))
{
if (STOP_SET (name[1], MAP_PATHSEP))
if (STOP_SET (name[1], MAP_DIRSEP))
{
/* A UNC. Don't prepend a drive letter. */
apath[0] = name[0];
@@ -1998,13 +2070,17 @@ abspath (const char *name, char *apath)
}
else
{
#if defined(__CYGWIN__) && defined(HAVE_DOS_PATHS)
if (STOP_SET (name[0], MAP_DIRSEP))
root_len = 1;
#endif
strncpy (apath, name, root_len);
apath[root_len] = '\0';
dest = apath + root_len;
/* Get past the root, since we already copied it. */
name += root_len;
#ifdef HAVE_DOS_PATHS
if (! STOP_SET (apath[2], MAP_PATHSEP))
if (! STOP_SET (apath[root_len - 1], MAP_DIRSEP))
{
/* Convert d:foo into d:./foo and increase root_len. */
apath[2] = '.';
@@ -2015,7 +2091,7 @@ abspath (const char *name, char *apath)
name--;
}
else
apath[2] = '/'; /* make sure it's a forward slash */
apath[root_len - 1] = '/'; /* make sure it's a forward slash */
#endif
}
@@ -2024,11 +2100,11 @@ abspath (const char *name, char *apath)
unsigned long len;
/* Skip sequence of multiple path-separators. */
while (STOP_SET (*start, MAP_PATHSEP))
while (STOP_SET (*start, MAP_DIRSEP))
++start;
/* Find end of path component. */
for (end = start; ! STOP_SET (*end, MAP_PATHSEP|MAP_NUL); ++end)
for (end = start; ! STOP_SET (*end, MAP_DIRSEP|MAP_NUL); ++end)
;
len = end - start;
@@ -2041,12 +2117,12 @@ abspath (const char *name, char *apath)
{
/* Back up to previous component, ignore if at root already. */
if (dest > apath + root_len)
for (--dest; ! STOP_SET (dest[-1], MAP_PATHSEP); --dest)
for (--dest; ! STOP_SET (dest[-1], MAP_DIRSEP); --dest)
;
}
else
{
if (! STOP_SET (dest[-1], MAP_PATHSEP))
if (! STOP_SET (dest[-1], MAP_DIRSEP))
*dest++ = '/';
if (dest + len >= apath_limit)
@@ -2059,7 +2135,7 @@ abspath (const char *name, char *apath)
}
/* Unless it is root strip trailing separator. */
if (dest > apath + root_len && STOP_SET (dest[-1], MAP_PATHSEP))
if (dest > apath + root_len && STOP_SET (dest[-1], MAP_DIRSEP))
--dest;
*dest = '\0';
@@ -2133,24 +2209,70 @@ func_file (char *o, char **argv, const char *funcname UNUSED)
mode = "a";
++fn;
}
fn = next_token (fn);
NEXT_TOKEN (fn);
fp = fopen (fn, mode);
if (fn[0] == '\0')
O (fatal, *expanding_var, _("file: missing filename"));
ENULLLOOP (fp, fopen (fn, mode));
if (fp == NULL)
fatal (reading_file, _("open: %s: %s"), fn, strerror (errno));
else
OSS (fatal, reading_file, _("open: %s: %s"), fn, strerror (errno));
if (argv[1])
{
int l = strlen (argv[1]);
int nl = (l == 0 || argv[1][l-1] != '\n');
int nl = l == 0 || argv[1][l-1] != '\n';
if (fputs (argv[1], fp) == EOF || (nl && fputc ('\n', fp) == EOF))
fatal (reading_file, _("write: %s: %s"), fn, strerror (errno));
fclose (fp);
OSS (fatal, reading_file, _("write: %s: %s"), fn, strerror (errno));
}
if (fclose (fp))
OSS (fatal, reading_file, _("close: %s: %s"), fn, strerror (errno));
}
else if (fn[0] == '<')
{
char *preo = o;
FILE *fp;
++fn;
NEXT_TOKEN (fn);
if (fn[0] == '\0')
O (fatal, *expanding_var, _("file: missing filename"));
if (argv[1])
O (fatal, *expanding_var, _("file: too many arguments"));
ENULLLOOP (fp, fopen (fn, "r"));
if (fp == NULL)
{
if (errno == ENOENT)
return o;
OSS (fatal, reading_file, _("open: %s: %s"), fn, strerror (errno));
}
while (1)
{
char buf[1024];
size_t l = fread (buf, 1, sizeof (buf), fp);
if (l > 0)
o = variable_buffer_output (o, buf, l);
if (ferror (fp))
if (errno != EINTR)
OSS (fatal, reading_file, _("read: %s: %s"), fn, strerror (errno));
if (feof (fp))
break;
}
if (fclose (fp))
OSS (fatal, reading_file, _("close: %s: %s"), fn, strerror (errno));
/* Remove trailing newline. */
if (o > preo && o[-1] == '\n')
if (--o > preo && o[-1] == '\r')
--o;
}
else
fatal (reading_file, _("Invalid file operation: %s"), fn);
OS (fatal, *expanding_var, _("file: invalid file operation: %s"), fn);
return o;
}
@@ -2264,7 +2386,7 @@ expand_builtin_function (char *o, int argc, char **argv,
char *p;
if (argc < (int)entry_p->minimum_args)
fatal (*expanding_var,
fatal (*expanding_var, strlen (entry_p->name),
_("insufficient number of arguments (%d) to function '%s'"),
argc, entry_p->name);
@@ -2276,8 +2398,8 @@ expand_builtin_function (char *o, int argc, char **argv,
return o;
if (!entry_p->fptr.func_ptr)
fatal (*expanding_var,
_("unimplemented on this platform: function '%s'"), entry_p->name);
OS (fatal, *expanding_var,
_("unimplemented on this platform: function '%s'"), entry_p->name);
if (!entry_p->alloc_fn)
return entry_p->fptr.func_ptr (o, argv, entry_p->name);
@@ -2323,7 +2445,8 @@ handle_function (char **op, const char **stringp)
/* We found a builtin function. Find the beginning of its arguments (skip
whitespace after the name). */
beg = next_token (beg + entry_p->len);
beg += entry_p->len;
NEXT_TOKEN (beg);
/* Find the end of the function invocation, counting nested use of
whichever kind of parens we use. Since we're looking, count commas
@@ -2339,7 +2462,7 @@ handle_function (char **op, const char **stringp)
break;
if (count >= 0)
fatal (*expanding_var,
fatal (*expanding_var, strlen (entry_p->name),
_("unterminated call to function '%s': missing '%c'"),
entry_p->name, closeparen);
@@ -2407,7 +2530,7 @@ handle_function (char **op, const char **stringp)
if (entry_p->expand_args)
for (argvp=argv; *argvp != 0; ++argvp)
free (*argvp);
else if (abeg)
else
free (abeg);
return 1;
@@ -2423,7 +2546,6 @@ func_call (char *o, char **argv, const char *funcname UNUSED)
{
static int max_args = 0;
char *fname;
char *cp;
char *body;
int flen;
int i;
@@ -2431,16 +2553,9 @@ func_call (char *o, char **argv, const char *funcname UNUSED)
const struct function_table_entry *entry_p;
struct variable *v;
/* There is no way to define a variable with a space in the name, so strip
leading and trailing whitespace as a favor to the user. */
fname = argv[0];
while (*fname != '\0' && isspace ((unsigned char)*fname))
++fname;
cp = fname + strlen (fname) - 1;
while (cp > fname && isspace ((unsigned char)*cp))
--cp;
cp[1] = '\0';
/* Clean up the name of the variable to be invoked. */
fname = next_token (argv[0]);
end_of_token (fname)[0] = '\0';
/* Calling nothing is a no-op */
if (*fname == '\0')
@@ -2519,28 +2634,37 @@ func_call (char *o, char **argv, const char *funcname UNUSED)
}
void
define_new_function (const gmk_floc *flocp,
const char *name, int min, int max, int expand,
char *(*func)(const char *, int, char **))
define_new_function (const floc *flocp, const char *name,
unsigned int min, unsigned int max, unsigned int flags,
gmk_func_ptr func)
{
const char *e = name;
struct function_table_entry *ent;
size_t len = strlen (name);
size_t len;
while (STOP_SET (*e, MAP_USERFUNC))
e++;
len = e - name;
if (len == 0)
O (fatal, flocp, _("Empty function name"));
if (*name == '.' || *e != '\0')
OS (fatal, flocp, _("Invalid function name: %s"), name);
if (len > 255)
fatal (flocp, _("Function name too long: %s\n"), name);
if (min < 0 || min > 255)
fatal (flocp, _("Invalid minimum argument count (%d) for function %s\n"),
min, name);
if (max < 0 || max > 255 || (max && max < min))
fatal (flocp, _("Invalid maximum argument count (%d) for function %s\n"),
max, name);
OS (fatal, flocp, _("Function name too long: %s"), name);
if (min > 255)
ONS (fatal, flocp,
_("Invalid minimum argument count (%u) for function %s"), min, name);
if (max > 255 || (max && max < min))
ONS (fatal, flocp,
_("Invalid maximum argument count (%u) for function %s"), max, name);
ent = xmalloc (sizeof (struct function_table_entry));
ent->name = name;
ent->len = len;
ent->minimum_args = min;
ent->maximum_args = max;
ent->expand_args = expand ? 1 : 0;
ent->expand_args = ANY_SET(flags, GMK_FUNC_NOEXPAND) ? 0 : 1;
ent->alloc_fn = 1;
ent->fptr.alloc_func_ptr = func;

View File

@@ -1,5 +1,5 @@
/* Get the system load averages.
Copyright (C) 1985-2013 Free Software Foundation, Inc.
Copyright (C) 1985-2016 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 Software

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-2013 Free Software Foundation, Inc.
Copyright (C) 1987-2016 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.

View File

@@ -1,5 +1,5 @@
/* Declarations for getopt.
Copyright (C) 1989-2013 Free Software Foundation, Inc.
Copyright (C) 1989-2016 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.

View File

@@ -1,5 +1,5 @@
/* getopt_long and getopt_long_only entry points for GNU getopt.
Copyright (C) 1987-1994, 1996-2013 Free Software Foundation, Inc.
Copyright (C) 1987-1994, 1996-2016 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.

View File

@@ -1,5 +1,5 @@
/* Convenience header for conditional use of GNU <libintl.h>.
Copyright (C) 1995-2013 Free Software Foundation, Inc.
Copyright (C) 1995-2016 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

View File

@@ -1,3 +1,9 @@
2013-10-20 Paul Smith <psmith@gnu.org>
* glob.c (glob): Cherry-pick a471e96a5352a5f0bde6d32dd36d33524811a2b1
from git://sourceware.org/git/glibc.git to fix SV 18123,
https://sourceware.org/bugzilla/show_bug.cgi?id=10278
2008-09-28 Juan Manuel Guerrero <juan.guerrero@gmx.de>
* glob.c (my_realloc) [__DJGPP__]: Don't define, and don't

View File

@@ -377,6 +377,11 @@ glob (pattern, flags, errfunc, pglob)
return -1;
}
/* POSIX requires all slashes to be matched. This means that with
a trailing slash we must match only directories. */
if (pattern[0] && pattern[strlen (pattern) - 1] == '/')
flags |= GLOB_ONLYDIR;
if (flags & GLOB_BRACE)
{
const char *begin = strchr (pattern, '{');

View File

@@ -1,5 +1,5 @@
;; Contents of the (gnu make) Guile module
;; Copyright (C) 2011-2013 Free Software Foundation, Inc.
;; Copyright (C) 2011-2016 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

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 Free Software Foundation, Inc.
Copyright (C) 2013-2016 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
@@ -26,6 +26,7 @@ typedef struct
unsigned long lineno;
} gmk_floc;
typedef char *(*gmk_func_ptr)(const char *nm, unsigned int argc, char **argv);
#ifdef _WIN32
# ifdef GMK_BUILDING_MAKE
@@ -38,17 +39,17 @@ typedef struct
#endif
/* Free memory returned by the gmk_expand() function. */
void GMK_EXPORT gmk_free (char *str);
GMK_EXPORT void gmk_free (char *str);
/* Allocate memory in GNU make's context. */
char * GMK_EXPORT gmk_alloc (unsigned int len);
GMK_EXPORT char *gmk_alloc (unsigned int len);
/* Run $(eval ...) on the provided string BUFFER. */
void GMK_EXPORT gmk_eval (const char *buffer, const gmk_floc *floc);
GMK_EXPORT void gmk_eval (const char *buffer, const gmk_floc *floc);
/* Run GNU make expansion on the provided string STR.
Returns an allocated buffer that the caller must free with gmk_free(). */
char * GMK_EXPORT gmk_expand (const char *str);
GMK_EXPORT char *gmk_expand (const char *str);
/* Register a new GNU make function NAME (maximum of 255 chars long).
When the function is expanded in the makefile, FUNC will be invoked with
@@ -60,14 +61,19 @@ char * GMK_EXPORT gmk_expand (const char *str);
MIN_ARGS is the minimum number of arguments the function requires.
MAX_ARGS is the maximum number of arguments (or 0 if there's no maximum).
MIN_ARGS and MAX_ARGS must be >= 0 and <= 255.
MIN_ARGS and MAX_ARGS may not exceed 255.
If EXPAND_ARGS is 0, the arguments to the function will not be expanded
before FUNC is called. If EXPAND_ARGS is non-0, they will be expanded.
The FLAGS value may be GMK_FUNC_DEFAULT, or one or more of the following
flags OR'd together:
GMK_FUNC_NOEXPAND: the arguments to the function will be not be expanded
before FUNC is called.
*/
void GMK_EXPORT gmk_add_function (const char *name,
char *(*func)(const char *nm,
int argc, char **argv),
int min_args, int max_args, int expand_args);
GMK_EXPORT void gmk_add_function (const char *name, gmk_func_ptr func,
unsigned int min_args, unsigned int max_args,
unsigned int flags);
#define GMK_FUNC_DEFAULT 0x00
#define GMK_FUNC_NOEXPAND 0x01
#endif /* _GNUMAKE_H_ */

50
guile.c
View File

@@ -1,5 +1,5 @@
/* GNU Guile interface for GNU Make.
Copyright (C) 2011-2013 Free Software Foundation, Inc.
Copyright (C) 2011-2016 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
@@ -15,14 +15,28 @@ You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
#include "makeint.h"
#ifdef HAVE_GUILE
#include "gnumake.h"
#include "debug.h"
#include "filedef.h"
#include "dep.h"
#include "variable.h"
#include <libguile.h>
/* Pre-2.0 versions of Guile don't have a typedef for gsubr function types. */
#if SCM_MAJOR_VERSION < 2
# define GSUBR_TYPE SCM (*) ()
/* Guile 1.x doesn't really support i18n. */
# define EVAL_STRING(_s) scm_c_eval_string (_s)
#else
# define GSUBR_TYPE scm_t_subr
# define EVAL_STRING(_s) scm_eval_string (scm_from_utf8_string (_s))
#endif
static SCM make_mod = SCM_EOL;
static SCM obj_to_str = SCM_EOL;
@@ -71,10 +85,10 @@ guile_define_module (void *data UNUSED)
#include "gmk-default.h"
/* Register a subr for GNU make's eval capability. */
scm_c_define_gsubr ("gmk-expand", 1, 0, 0, guile_expand_wrapper);
scm_c_define_gsubr ("gmk-expand", 1, 0, 0, (GSUBR_TYPE) guile_expand_wrapper);
/* Register a subr for GNU make's eval capability. */
scm_c_define_gsubr ("gmk-eval", 1, 0, 0, guile_eval_wrapper);
scm_c_define_gsubr ("gmk-eval", 1, 0, 0, (GSUBR_TYPE) guile_eval_wrapper);
/* Define the rest of the module. */
scm_c_eval_string (GUILE_module_defn);
@@ -99,13 +113,22 @@ guile_init (void *arg UNUSED)
static void *
internal_guile_eval (void *arg)
{
return cvt_scm_to_str (scm_c_eval_string (arg));
return cvt_scm_to_str (EVAL_STRING (arg));
}
/* This is the function registered with make */
static char *
func_guile (const char *funcname UNUSED, int argc UNUSED, char **argv)
func_guile (const char *funcname UNUSED, unsigned int argc UNUSED, char **argv)
{
static int init = 0;
if (! init)
{
/* Initialize the Guile interpreter. */
scm_with_guile (guile_init, NULL);
init = 1;
}
if (argv[0] && argv[0][0] != '\0')
return scm_with_guile (internal_guile_eval, argv[0]);
@@ -117,13 +140,20 @@ func_guile (const char *funcname UNUSED, int argc UNUSED, char **argv)
/* We could send the flocp to define_new_function(), but since guile is
"kind of" built-in, that didn't seem so useful. */
int
guile_gmake_setup (const gmk_floc *flocp UNUSED)
guile_gmake_setup (const floc *flocp UNUSED)
{
/* Initialize the Guile interpreter. */
scm_with_guile (guile_init, NULL);
/* Create a make function "guile". */
gmk_add_function ("guile", func_guile, 0, 1, 1);
gmk_add_function ("guile", func_guile, 0, 1, GMK_FUNC_DEFAULT);
return 1;
}
#else
int
guile_gmake_setup (const floc *flocp UNUSED)
{
return 1;
}
#endif

2
hash.c
View File

@@ -48,7 +48,7 @@ hash_init (struct hash_table *ht, unsigned long size,
{
fprintf (stderr, _("can't allocate %lu bytes for hash table: memory exhausted"),
ht->ht_size * (unsigned long) sizeof (struct token *));
exit (1);
exit (MAKE_TROUBLE);
}
ht->ht_capacity = ht->ht_size - (ht->ht_size / 16); /* 93.75% loading factor */

View File

@@ -1,5 +1,5 @@
/* Implicit rule searching for GNU Make.
Copyright (C) 1988-2013 Free Software Foundation, Inc.
Copyright (C) 1988-2016 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
@@ -72,8 +72,7 @@ get_next_word (const char *buffer, unsigned int *length)
char c;
/* Skip any leading whitespace. */
while (isblank ((unsigned char)*p))
++p;
NEXT_TOKEN (p);
beg = p;
c = *(p++);
@@ -266,12 +265,15 @@ 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/.) */
#ifdef VMS
lastslash = strrchr (filename, ']');
if (lastslash == 0)
lastslash = strrchr (filename, ':');
#else
lastslash = strrchr (filename, '/');
#ifdef VMS
if (lastslash == NULL)
lastslash = strrchr (filename, ']');
if (lastslash == NULL)
lastslash = strrchr (filename, '>');
if (lastslash == NULL)
lastslash = strrchr (filename, ':');
#endif
#ifdef HAVE_DOS_PATHS
/* Handle backslashes (possibly mixed with forward slashes)
and the case of "d:file". */
@@ -282,7 +284,6 @@ pattern_search (struct file *file, int archive,
if (lastslash == 0 && filename[0] && filename[1] == ':')
lastslash = filename + 1;
}
#endif
#endif
if (lastslash != 0 && lastslash[1] == '\0')
lastslash = 0;
@@ -315,7 +316,7 @@ pattern_search (struct file *file, int archive,
{
const char *target = rule->targets[ti];
const char *suffix = rule->suffixes[ti];
int check_lastslash;
char check_lastslash;
/* Rules that can match any filename and are not terminal
are ignored if we're recursing, so that they cannot be
@@ -339,10 +340,10 @@ pattern_search (struct file *file, int archive,
if (lastslash)
{
#ifdef VMS
check_lastslash = (strchr (target, ']') == 0
&& strchr (target, ':') == 0);
check_lastslash = strpbrk (target, "/]>:") == NULL;
#else
check_lastslash = strchr (target, '/') == 0;
#endif
#ifdef HAVE_DOS_PATHS
/* Didn't find it yet: check for DOS-type directories. */
if (check_lastslash)
@@ -350,7 +351,6 @@ pattern_search (struct file *file, int archive,
char *b = strchr (target, '\\');
check_lastslash = !(b || (target[0] && target[1] == ':'));
}
#endif
#endif
}
if (check_lastslash)
@@ -437,7 +437,7 @@ pattern_search (struct file *file, int archive,
for (ri = 0; ri < nrules; ri++)
{
struct dep *dep;
int check_lastslash;
char check_lastslash;
unsigned int failed = 0;
int file_variables_set = 0;
unsigned int deps_found = 0;
@@ -574,6 +574,7 @@ pattern_search (struct file *file, int archive,
{
int add_dir = 0;
unsigned int len;
struct dep **dptr;
nptr = get_next_word (nptr, &len);
if (nptr == 0)
@@ -616,6 +617,9 @@ pattern_search (struct file *file, int archive,
add_dir = 1;
}
/* Set up for the next word. */
nptr += len;
/* Initialize and set file variables if we haven't already
done so. */
if (!file_vars_initialized)
@@ -634,20 +638,33 @@ pattern_search (struct file *file, int archive,
/* Perform the 2nd expansion. */
p = variable_expand_for_file (depname, file);
dptr = &dl;
/* Parse the expanded string. */
dl = PARSE_FILE_SEQ (&p, struct dep, order_only ? MAP_NUL : MAP_PIPE,
add_dir ? dir : NULL, PARSEFS_NONE);
for (d = dl; d != NULL; d = d->next)
/* Parse the results into a deps list. */
do
{
++deps_found;
if (order_only)
d->ignore_mtime = 1;
}
/* 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);
*dptr = dp;
/* Set up for the next word. */
nptr += len;
for (d = dp; d != NULL; d = d->next)
{
++deps_found;
if (order_only)
d->ignore_mtime = 1;
dptr = &d->next;
}
/* If we stopped due to an order-only token, note it. */
if (*p == '|')
{
order_only = 1;
++p;
}
}
while (*p != '\0');
}
/* If there are more than max_pattern_deps prerequisites (due to
@@ -846,9 +863,10 @@ pattern_search (struct file *file, int archive,
/* We don't want to delete an intermediate file that happened
to be a prerequisite of some (other) target. Mark it as
precious. */
secondary. We don't want it to be precious as that disables
DELETE_ON_ERROR etc. */
if (f != 0)
f->precious = 1;
f->secondary = 1;
else
f = enter_file (imf->name);

942
job.c

File diff suppressed because it is too large Load Diff

32
job.h
View File

@@ -1,5 +1,5 @@
/* Definitions for managing subprocesses in GNU Make.
Copyright (C) 1992-2013 Free Software Foundation, Inc.
Copyright (C) 1992-2016 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
@@ -24,7 +24,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* How to set close-on-exec for a file descriptor. */
#if !defined F_SETFD
#if !defined(F_SETFD) || !defined(F_GETFD)
# ifdef WINDOWS32
# define CLOSE_ON_EXEC(_d) process_noinherit(_d)
# else
@@ -37,7 +37,11 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
# define CLOSE_ON_EXEC(_d) (void) fcntl ((_d), F_SETFD, FD_CLOEXEC)
#endif
#ifdef OUTPUT_SYNC
#ifdef NO_OUTPUT_SYNC
# define RECORD_SYNC_MUTEX(m) \
O (error, NILF, \
_("-O[TYPE] (--output-sync[=TYPE]) is not configured for this build."));
#else
# ifdef WINDOWS32
/* For emulations in w32/compat/posixfcn.c. */
# define F_GETFD 1
@@ -69,7 +73,6 @@ int same_stream (FILE *f1, FILE *f2);
# define RECORD_SYNC_MUTEX(m) record_sync_mutex(m)
void record_sync_mutex (const char *str);
void prepare_mutex_handle_string (intptr_t hdl);
# else /* !WINDOWS32 */
typedef int sync_handle_t; /* file descriptor */
@@ -77,11 +80,7 @@ typedef int sync_handle_t; /* file descriptor */
# define RECORD_SYNC_MUTEX(m) (void)(m)
# endif
#else /* !OUTPUT_SYNC */
#define RECORD_SYNC_MUTEX(m) \
error (NILF, \
_("-O[TYPE] (--output-sync[=TYPE]) is not configured for this build."));
#endif /* OUTPUT_SYNC */
#endif /* !NO_OUTPUT_SYNC */
/* Structure describing a running or dead child process. */
@@ -100,6 +99,7 @@ struct child
char *comname; /* Temporary command file name */
int efn; /* Completion event flag number */
int cstatus; /* Completion status */
int vms_launch_status; /* non-zero if lib$spawn, etc failed */
#endif
unsigned int command_line; /* Index into command_lines. */
@@ -109,11 +109,14 @@ struct child
unsigned int noerror:1; /* Nonzero if commands contained a '-'. */
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 dontcare:1; /* Saved dontcare flag. */
};
extern struct child *children;
/* A signal handler for SIGCHLD, if needed. */
RETSIGTYPE 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);
@@ -121,13 +124,16 @@ void start_waiting_jobs (void);
char **construct_command_argv (char *line, char **restp, struct file *file,
int cmd_flags, char** batch_file);
#ifdef VMS
int child_execute_job (char *argv, struct child *child);
#elif defined(__EMX__)
int child_execute_job (int stdin_fd, int stdout_fd, char **argv, char **envp);
int child_execute_job (struct child *child, char *argv);
#else
void child_execute_job (int stdin_fd, int stdout_fd, char **argv, char **envp);
# define FD_STDIN (fileno (stdin))
# define FD_STDOUT (fileno (stdout))
# define FD_STDERR (fileno (stderr))
int child_execute_job (struct output *out, int good_stdin, char **argv, char **envp);
#endif
#ifdef _AMIGA
void exec_command (char **argv) __attribute__ ((noreturn));
#elif defined(__EMX__)

69
load.c
View File

@@ -1,5 +1,5 @@
/* Loading dynamic objects for GNU Make.
Copyright (C) 2012-2013 Free Software Foundation, Inc.
Copyright (C) 2012-2016 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
@@ -30,6 +30,11 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#include "filedef.h"
#include "variable.h"
/* Tru64 V4.0 does not have this flag */
#ifndef RTLD_GLOBAL
# define RTLD_GLOBAL 0
#endif
struct load_list
{
struct load_list *next;
@@ -40,8 +45,8 @@ struct load_list
static struct load_list *loaded_syms = NULL;
static load_func_t
load_object (const gmk_floc *flocp, int noerror,
const char *ldname, const char *symname)
load_object (const floc *flocp, int noerror, const char *ldname,
const char *symname)
{
static void *global_dl = NULL;
load_func_t symp;
@@ -50,7 +55,10 @@ load_object (const gmk_floc *flocp, int noerror,
{
global_dl = dlopen (NULL, RTLD_NOW|RTLD_GLOBAL);
if (! global_dl)
fatal (flocp, _("Failed to open global symbol table: %s"), dlerror ());
{
const char *err = dlerror ();
OS (fatal, flocp, _("Failed to open global symbol table: %s"), err);
}
}
symp = (load_func_t) dlsym (global_dl, symname);
@@ -74,23 +82,28 @@ load_object (const gmk_floc *flocp, int noerror,
/* Still no? Then fail. */
if (! dlp)
{
const char *err = dlerror ();
if (noerror)
DB (DB_BASIC, ("%s", dlerror ()));
DB (DB_BASIC, ("%s", err));
else
error (flocp, "%s", dlerror ());
OS (error, flocp, "%s", err);
return NULL;
}
/* Assert that the GPL license symbol is defined. */
symp = dlsym (dlp, "plugin_is_GPL_compatible");
symp = (load_func_t) dlsym (dlp, "plugin_is_GPL_compatible");
if (! symp)
fatal (flocp, _("Loaded object %s is not declared to be GPL compatible"),
ldname);
OS (fatal, flocp,
_("Loaded object %s is not declared to be GPL compatible"),
ldname);
symp = dlsym (dlp, symname);
symp = (load_func_t) dlsym (dlp, symname);
if (! symp)
fatal (flocp, _("Failed to load symbol %s from %s: %s"),
symname, ldname, dlerror ());
{
const char *err = dlerror ();
OSSS (fatal, flocp, _("Failed to load symbol %s from %s: %s"),
symname, ldname, err);
}
/* Add this symbol to a trivial lookup table. This is not efficient but
it's highly unlikely we'll be loading lots of objects, and we only
@@ -106,7 +119,7 @@ load_object (const gmk_floc *flocp, int noerror,
}
int
load_file (const gmk_floc *flocp, const char **ldname, int noerror)
load_file (const floc *flocp, const char **ldname, int noerror)
{
int nmlen = strlen (*ldname);
char *new = alloca (nmlen + CSTRLEN (SYMBOL_EXTENSION) + 1);
@@ -133,12 +146,13 @@ load_file (const gmk_floc *flocp, const char **ldname, int noerror)
++fp;
if (fp == ep)
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);
new[l] = '\0';
*ldname = new;
nmlen = l;
/* Make a copy of the symbol name part. */
symname = new + l + 1;
@@ -154,9 +168,8 @@ load_file (const gmk_floc *flocp, const char **ldname, int noerror)
loaded = allocated_variable_expand ("$(.LOADED)");
fp = strstr (loaded, *ldname);
r = fp && (fp==loaded || fp[-1]==' ') && (fp[nmlen]=='\0' || fp[nmlen]==' ');
free (loaded);
if (r)
return 1;
goto exit;
/* If we didn't find a symbol name yet, construct it from the ldname. */
if (! symname)
@@ -200,8 +213,21 @@ load_file (const gmk_floc *flocp, const char **ldname, int noerror)
/* If it succeeded, add the load file to the loaded variable. */
if (r > 0)
do_variable_definition (flocp, ".LOADED", *ldname, o_default, f_append, 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);
}
exit:
free (loaded);
return r;
}
@@ -223,18 +249,19 @@ unload_file (const char *name)
#else
int
load_file (const gmk_floc *flocp, const char **ldname, int noerror)
load_file (const floc *flocp, const char **ldname UNUSED, int noerror)
{
if (! noerror)
fatal (flocp, _("The 'load' operation is not supported on this platform."));
O (fatal, flocp,
_("The 'load' operation is not supported on this platform."));
return 0;
}
void
unload_file (const char *name)
unload_file (const char *name UNUSED)
{
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 Free Software Foundation, Inc.
Copyright (C) 2013-2016 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
@@ -37,11 +37,32 @@ gmk_free (char *s)
/* Evaluate a buffer as make syntax.
Ideally eval_buffer() will take const char *, but not yet. */
void
gmk_eval (const char *buffer, const gmk_floc *floc)
gmk_eval (const char *buffer, const gmk_floc *gfloc)
{
char *s = xstrdup (buffer);
eval_buffer (s, floc);
/* Preserve existing variable buffer context. */
char *pbuf;
unsigned int plen;
char *s;
floc fl;
floc *flp;
if (gfloc)
{
fl.filenm = gfloc->filenm;
fl.lineno = gfloc->lineno;
fl.offset = 0;
flp = &fl;
}
else
flp = NULL;
install_variable_buffer (&pbuf, &plen);
s = xstrdup (buffer);
eval_buffer (s, flp);
free (s);
restore_variable_buffer (pbuf, plen);
}
/* Expand a string and return an allocated buffer.
@@ -54,9 +75,8 @@ gmk_expand (const char *ref)
/* Register a function to be called from makefiles. */
void
gmk_add_function (const char *name,
char *(*func)(const char *nm, int argc, char **argv),
int min, int max, int expand)
gmk_add_function (const char *name, gmk_func_ptr func,
unsigned int min, unsigned int max, unsigned int flags)
{
define_new_function (reading_file, name, min, max, expand, func);
define_new_function (reading_file, name, min, max, flags, func);
}

1062
main.c

File diff suppressed because it is too large Load Diff

View File

@@ -2,8 +2,25 @@
# only if you have the full copy of the GNU make sources from the Git
# tree, not a dist copy.
BUGLIST := bug-make@gnu.org
# These are related to my personal setup.
GPG_FINGERPRINT := 6338B6D4
# 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
# We like mondo-warnings!
AM_CFLAGS += -Wall -Wextra -Wdeclaration-after-statement -Wshadow -Wpointer-arith -Wbad-function-cast
AM_CFLAGS += -Wall -Wwrite-strings -Wextra -Wdeclaration-after-statement -Wshadow -Wpointer-arith -Wbad-function-cast
MAKE_MAINTAINER_MODE := -DMAKE_MAINTAINER_MODE
AM_CPPFLAGS += $(MAKE_MAINTAINER_MODE)
@@ -22,6 +39,10 @@ MTEMPLATES = Makefile.DOS SMakefile
# These are built as a side-effect of the dist rule
#all-am: $(TEMPLATES) $(MTEMPLATES) build.sh.in
# 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
@@ -97,23 +118,40 @@ git-very-clean: git-clean
-$(GIT) clean -fd
# ----------------------------------------------------------------------
#
# The sections below were stolen from the Makefile.maint used by fileutils,
# sh-utils, textutils, CPPI, Bison, and Autoconf.
## ---------------------- ##
## Generating ChangeLog. ##
## ---------------------- ##
gl2cl-date := 2013-10-10
gl2cl := $(GNULIBDIR)/build-aux/gitlog-to-changelog
# Rebuild the changelog whenever a new commit is added
ChangeLog: .check-git-HEAD
if test -f '$(gl2cl)'; then \
'$(gl2cl)' --since='$(gl2cl-date)' > '$@'; \
else \
echo "WARNING: $(gl2cl) is not available. No $@ generated."; \
fi
.PHONY: .check-git-HEAD
.check-git-HEAD:
sha="`git rev-parse HEAD`"; \
[ -f '$@' ] && [ "`cat '$@' 2>/dev/null`" = "$$sha" ] \
|| echo "$$sha" > '$@'
## ---------------- ##
## Updating files. ##
## ---------------- ##
WGET = wget --passive-ftp -nv
WGET = wget --passive-ftp -np -nv
ftp-gnu = ftp://ftp.gnu.org/gnu
move_if_change = if test -r $(target) && cmp -s $(target).t $(target); then \
echo $(target) is unchanged; rm -f $(target).t; \
else \
mv $(target).t $(target); \
mv -f $(target).t $(target); \
fi
# ------------------- #
@@ -125,8 +163,7 @@ move_if_change = if test -r $(target) && cmp -s $(target).t $(target); then \
# http://translation.sf.net/maint/
# ftp://tiger.informatik.hu-berlin.de/pub/po/maint/
po_wget_flags = --recursive --level=1 --no-directories --no-parent \
--no-check-certificate
po_wget_flags = --recursive --level=1 --no-directories --no-check-certificate
po_repo = http://translationproject.org/latest/$(PACKAGE)
.PHONY: do-po-update po-update
do-po-update:
@@ -135,7 +172,8 @@ do-po-update:
&& mkdir "$$tmppo" \
&& (cd "$$tmppo" \
&& $(WGET) $(po_wget_flags) -A '*.po' $(po_repo)) \
&& cp "$$tmppo"/*.po $(top_srcdir)/po && rm -rf "$$tmppo"
&& cp "$$tmppo"/*.po $(top_srcdir)/po \
&& rm -rf "$$tmppo"
cd po && $(MAKE) update-po
$(MAKE) po-check
@@ -184,10 +222,48 @@ scm-update: get-config/texinfo.tex get-config/config.guess get-config/config.sub
update: po-update scm-update
# ---------------------------------- #
# Alternative configuration checks. #
# ---------------------------------- #
.PHONY: check-alt-config
check-alt-config: \
checkcfg.--disable-job-server \
checkcfg.--disable-load \
checkcfg.--without-guile \
checkcfg.CPPFLAGS^-DNO_OUTPUT_SYNC \
checkcfg.CPPFLAGS^-DNO_ARCHIVES
# Trick GNU make so it doesn't run the submake as a recursive make.
NR_MAKE = $(MAKE)
# Check builds both with build.sh and with make
checkcfg.%: distdir
@echo "Building $@ (output in checkcfg.$*.log)"
@exec >'checkcfg.$*.log' 2>&1; \
rm -rf $(distdir)/_build \
&& mkdir $(distdir)/_build \
&& cd $(distdir)/_build \
&& echo "Testing configure with $(subst ^,=,$*)" \
&& ../configure --srcdir=.. $(subst ^,=,$*) \
$(AM_DISTCHECK_CONFIGURE_FLAGS) $(DISTCHECK_CONFIGURE_FLAGS) \
CFLAGS='$(AM_CFLAGS)' \
&& ./build.sh \
&& ./make $(AM_MAKEFLAGS) check \
&& rm -f *.o make \
&& $(NR_MAKE) $(AM_MAKEFLAGS) \
&& ./make $(AM_MAKEFLAGS) check
## --------------- ##
## Sanity checks. ##
## --------------- ##
# Before we build a distribution be sure we run our local checks
#distdir: local-check
.PHONY: local-check po-check changelog-check
# Checks that don't require Git. Run 'changelog-check' last as
# previous test may reveal problems requiring new ChangeLog entries.
local-check: po-check changelog-check
@@ -207,11 +283,66 @@ changelog-check:
po-check:
if test -f po/POTFILES.in; then \
grep '^[^#]' po/POTFILES.in | sort > $@-1; \
$(PERL) -wn -e 'if (/\b_\(/) { $$ARGV eq "makeint.h" || print "$$ARGV\n" and close ARGV }' *.c *.h | sort > $@-2; \
$(PERL) -wn -e 'if (/\b_\(/) { $$ARGV eq "./makeint.h" || print "$$ARGV\n" and close ARGV }' `find . -name '*.[ch]'` | sed 's,^\./,,' | sort > $@-2; \
diff -u $@-1 $@-2 || exit 1; \
rm -f $@-1 $@-2; \
fi
## --------------- ##
## Generate docs. ##
## --------------- ##
.PHONY: update-makeweb gendocs
CVS = cvs
makeweb-repo = $(USER)@cvs.sv.gnu.org:/web/make
gnuweb-repo = :pserver:anonymous@cvs.sv.gnu.org:/web/www
gnuweb-dir = www/server/standards
# Get the GNU make web page boilerplate etc.
update-makeweb:
[ -d '$(MAKEWEBDIR)' ] || mkdir -p '$(MAKEWEBDIR)'
[ -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 ] \
&& { cd '$(GNUWEBDIR)/$(gnuweb-dir)' && $(CVS) update; } \
|| { cd '$(GNUWEBDIR)' && $(CVS) -d $(gnuweb-repo) co '$(gnuweb-dir)'; }
gendocs: update-gnuweb update-makeweb
cp $(GNULIBDIR)/doc/gendocs_template doc
cd doc \
&& rm -rf doc/manual \
&& $(GNULIBDIR)/build-aux/gendocs.sh --email '$(BUGLIST)' \
make 'GNU Make 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)' \
&& cvs -q -n update | grep -v '^M ' \
&& echo '- cvs add <new files>' \
&& echo '- cvs remove <deleted files>' \
&& echo '- cvs commit' \
&& echo '- cvs tag make-$(subst .,-,$(VERSION))'
## ------------------------- ##
## Make release targets. ##
## ------------------------- ##
.PHONY: tag-release
tag-release:
case '$(VERSION)' in \
(*.*.9*) message=" candidate" ;; \
(*) message= ;; \
esac; \
$(GIT) tag -m "GNU Make release$$message $(VERSION)" -u '$(GPG_FINGERPRINT)' '$(VERSION)'
## ------------------------- ##
## GNU FTP upload artifacts. ##
## ------------------------- ##
@@ -221,7 +352,7 @@ po-check:
# you're SOL! :)
GPG = gpg
GPGFLAGS = -u 6338B6D4
GPGFLAGS = -u $(GPG_FINGERPRINT)
DIST_ARCHIVES_SIG = $(addsuffix .sig,$(DIST_ARCHIVES))
DIST_ARCHIVES_DIRECTIVE = $(addsuffix .directive.asc,$(DIST_ARCHIVES))
@@ -258,7 +389,10 @@ $(UPLOADS): $(DIST_ARCHIVES) $(DIST_ARCHIVES_SIG) $(DIST_ARCHIVES_DIRECTIVE)
$(FTPPUT) "$(gnu-upload-host)" "$(gnu-upload-dir)/$(@:upload-%=%)" $^
# Copyright (C) 1997-2013 Free Software Foundation, Inc.
# Rebuild Makefile.in if this file is modifed.
Makefile.in: maintMakefile
# Copyright (C) 1997-2016 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

4
make.1
View File

@@ -1,4 +1,4 @@
.TH MAKE 1 "03 March 2012" "GNU" "User Commands"
.TH MAKE 1 "28 February 2016" "GNU" "User Commands"
.SH NAME
make \- GNU make utility to maintain groups of programs
.SH SYNOPSIS
@@ -363,7 +363,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-2013 Free Software Foundation, Inc.
Copyright \(co 1992-1993, 1996-2016 Free Software Foundation, Inc.
This file is part of
.IR "GNU make" .
.LP

View File

@@ -154,11 +154,11 @@
<File
RelativePath=".\getopt1.c">
</File>
<!--
<File
RelativePath=".\guile.c">
</File>
-->
<File
RelativePath=".\hash.c">
</File>
@@ -171,6 +171,9 @@
<File
RelativePath=".\job.c">
</File>
<File
RelativePath=".\load.c">
</File>
<File
RelativePath=".\output.c">
</File>
@@ -210,6 +213,9 @@
<File
RelativePath=".\w32\compat\dirent.c">
</File>
<File
RelativePath=".\w32\compat\posixfcn.c">
</File>
<File
RelativePath=".\w32\subproc\misc.c">
<FileConfiguration
@@ -228,6 +234,9 @@
<File
RelativePath=".\w32\pathstuff.c">
</File>
<File
RelativePath=".\w32\w32os.c">
</File>
<File
RelativePath=".\w32\subproc\sub_proc.c">
</File>

View File

@@ -1,8 +1,7 @@
$!
$! Makefile.com - builds GNU Make for VMS
$!
$! P1 is non-empty if you want to link with the VAXCRTL library instead
$! of the shareable executable
$! P1 = LIST will provide compiler listings.
$! P2 = DEBUG will build an image with debug information
$! P3 = WALL will enable all warning messages (some are suppressed since
$! one macro intentionally causes an error condition)
@@ -50,6 +49,12 @@ $ endif
$ endif
$ endif
$!
$!
$ if (p1 .eqs. "LIST")
$ then
$ ccopt = ccopt + "/list/show=(expan,inclu)"
$ endif
$!
$! Should we build a debug image
$!
$ if (p2.eqs."DEBUG")
@@ -67,9 +72,12 @@ $ then
$ gosub check_cc_qual
$ endif
$ filelist = "alloca ar arscan commands default dir expand file function " + -
"hash implicit job load main misc read remake remote-stub rule " + -
"signame variable version vmsfunctions vmsify vpath " + -
"[.glob]glob [.glob]fnmatch getopt1 getopt strcache"
"guile hash implicit job load main misc read remake " + -
"remote-stub rule output signame variable version " + -
"vmsfunctions vmsify vpath vms_progname vms_exit " + -
"vms_export_symbol [.glob]glob [.glob]fnmatch getopt1 " + -
"getopt strcache"
$!
$ copy config.h-vms config.h
$ n=0
$ open/write optf make.opt
@@ -77,18 +85,14 @@ $ loop:
$ cfile = f$elem(n," ",filelist)
$ if cfile .eqs. " " then goto linkit
$ write sys$output "Compiling ''cfile'..."
$ call compileit 'cfile' 'p1'
$ call compileit 'cfile'
$ n = n + 1
$ goto loop
$ linkit:
$ close optf
$ if p1 .nes. "" then goto link_using_library
$ link/exe=make make.opt/opt'lopt
$ goto cleanup
$
$ link_using_library:
$ link/exe=make make.opt/opt,sys$library:vaxcrtl/lib'lopt
$
$ cleanup:
$ if f$trnlnm("SYS").nes."" then $ deassign sys
$ if f$trnlnm("OPTF").nes."" then $ close optf
@@ -128,17 +132,24 @@ $!-----------------------------------------------------------------------------
$!
$ compileit : subroutine
$ ploc = f$locate("]",p1)
$ filnam = p1
$ if ploc .lt. f$length(p1) then filnam=f$extract(ploc+1,100,p1)
$ write optf "''filnam'"
$ cc'ccopt'/include=([],[.glob]) -
/define=("allocated_variable_expand_for_file=alloc_var_expand_for_file","unlink=remove","HAVE_CONFIG_H","VMS") -
$! filnam = p1
$ if ploc .lt. f$length(p1)
$ then
$ objdir = f$extract(0, ploc+1, p1)
$ write optf p1
$ else
$ objdir := []
$ write optf objdir+p1
$ endif
$ cc'ccopt'/nested=none/include=([],[.glob])/obj='objdir' -
/define=("allocated_variable_expand_for_file=alloc_var_expand_for_file",-
"unlink=remove","HAVE_CONFIG_H","VMS") -
'p1'
$ exit
$ endsubroutine : compileit
$!
$!-----------------------------------------------------------------------------
$!Copyright (C) 1996-2013 Free Software Foundation, Inc.
$!Copyright (C) 1996-2016 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

View File

@@ -1,6 +1,6 @@
# -*-Makefile-*- to build GNU make on VMS
#
# Copyright (C) 1996-2013 Free Software Foundation, Inc.
# Copyright (C) 1996-2016 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
@@ -32,9 +32,12 @@ CP = copy
#
ifeq ($(CC),cc)
CFLAGS = $(defines) /include=([],[.glob])/prefix=(all,except=(glob,globfree))/standard=relaxed/warn=(disable=questcompare)
cinclude = /nested=none/include=([],[.glob])
cprefix = /prefix=(all,except=(glob,globfree))
cwarn = /standard=relaxed/warn=(disable=questcompare)
CFLAGS = $(defines) $(cinclude)$(cprefix)$(cwarn)
else
CFLAGS = $(defines) /include=([],[.glob])
CFLAGS = $(defines) $(cinclude)
endif
#LDFLAGS = /deb
LDFLAGS =
@@ -88,18 +91,19 @@ mandir = []
# Number to put on the man page filename.
manext = 1
#guile = ,guile.obj
guile = ,guile.obj
objs = commands.obj,job.obj,output.obj,dir.obj,file.obj,misc.obj,hash.obj,\
load.obj,main.obj,read.obj,remake.obj,rule.obj,implicit.obj,\
default.obj,variable.obj,expand.obj,function.obj,strcache.obj,\
vpath.obj,version.obj\
$(ARCHIVES)$(ALLOCA)$(extras)$(getopt)$(glob)$(guile)
vpath.obj,version.obj,vms_progname.obj,vms_exit.obj,\
vms_export_symbol.obj$(guile)$(ARCHIVES)$(extras)$(getopt)$(glob)
srcs = commands.c job.c output.c dir.c file.c misc.c guile.c hash.c \
load.c main.c read.c remake.c rule.c implicit.c \
default.c variable.c expand.c function.c strcache.c \
vpath.c version.c vmsfunctions.c vmsify.c $(ARCHIVES_SRC) $(ALLOCASRC) \
vpath.c version.c vmsfunctions.c vmsify.c vms_progname.c vms_exit.c \
vms_export_symbol.c $(ARCHIVES_SRC) $(ALLOCASRC) \
commands.h dep.h filedef.h job.h output.h makeint.h rule.h variable.h
@@ -118,40 +122,59 @@ clean:
-$(RM) make.exe;,*.obj;
-$(RM) [.glob]*.obj;
# Automatically generated dependencies.
# makeint.h: config.h gnumake.h gettext.h
# filedef.h: hash.h
ar.obj: ar.c makeint.h filedef.h dep.h [.glob]fnmatch.h
arscan.obj: arscan.c makeint.h
commands.obj: commands.c makeint.h dep.h commands.h filedef.h variable.h job.h
default.obj: default.c makeint.h rule.h dep.h job.h filedef.h commands.h variable.h
dir.obj: dir.c makeint.h hash.h [.glob]glob.h
expand.obj: expand.c makeint.h commands.h filedef.h job.h rule.h variable.h
file.obj: file.c makeint.h commands.h dep.h filedef.h variable.h job.h debug.h
function.obj: function.c makeint.h variable.h dep.h commands.h filedef.h debug.h job.h
getopt.obj: getopt.c getopt.h config.h gettext.h
getopt1.obj: getopt1.c getopt.h config.h
guile.obj: guile.c makeint.h debug.h dep.h gmk-default.h
hash.obj: hash.c makeint.h hash.h
implicit.obj: implicit.c makeint.h rule.h dep.h filedef.h debug.h variable.h job.h commands.h
job.obj: job.c vmsjobs.c makeint.h commands.h job.h filedef.h variable.h debug.h
output.obj: output.c vmsjobs.c makeint.h output.h filedef.h debug.h
load.obj: load.c makeint.h debug.h filedef.h variable.h
main.obj: main.c makeint.h commands.h dep.h filedef.h variable.h job.h rule.h debug.h getopt.h
misc.obj: misc.c makeint.h dep.h debug.h
read.obj: read.c makeint.h commands.h dep.h filedef.h variable.h [.glob]glob.h debug.h rule.h job.h
remake.obj: remake.c makeint.h commands.h job.h dep.h filedef.h variable.h debug.h
remote-stub.obj: remote-stub.c makeint.h filedef.h job.h commands.h
rule.obj: rule.c makeint.h commands.h dep.h filedef.h variable.h rule.h job.h
signame.obj: signame.c makeint.h
strcache.obj: strcache.c makeint.h hash.h
variable.obj: variable.c makeint.h commands.h variable.h dep.h filedef.h job.h rule.h
ar.obj: ar.c makeint.h config.h gnumake.h gettext.h filedef.h hash.h dep.h \
[.glob]fnmatch.h
arscan.obj: arscan.c makeint.h config.h gnumake.h gettext.h
commands.obj: commands.c makeint.h config.h gnumake.h gettext.h filedef.h \
hash.h dep.h variable.h job.h output.h commands.h
default.obj: default.c makeint.h config.h gnumake.h gettext.h filedef.h \
hash.h variable.h rule.h dep.h job.h output.h commands.h
dir.obj: dir.c makeint.h config.h gnumake.h gettext.h hash.h filedef.h \
dep.h [.glob]glob.h
expand.obj: expand.c makeint.h config.h gnumake.h gettext.h filedef.h \
hash.h job.h output.h commands.h variable.h rule.h
file.obj: file.c makeint.h config.h gnumake.h gettext.h filedef.h hash.h \
dep.h job.h output.h commands.h variable.h debug.h
[.glob]fnmatch.obj: [.glob]fnmatch.c config.h [.glob]fnmatch.h
function.obj: function.c makeint.h config.h gnumake.h gettext.h filedef.h \
hash.h variable.h dep.h job.h output.h commands.h debug.h
getopt.obj: getopt.c config.h gettext.h getopt.h
getopt1.obj: getopt1.c config.h getopt.h
[.glob]glob.obj: [.glob]glob.c config.h [.glob]fnmatch.h [.glob]glob.h
guile.obj: guile.c makeint.h config.h gnumake.h gettext.h
hash.obj: hash.c makeint.h config.h gnumake.h gettext.h hash.h
implicit.obj: implicit.c makeint.h config.h gnumake.h gettext.h filedef.h \
hash.h rule.h dep.h debug.h variable.h job.h output.h commands.h
job.obj: job.c makeint.h config.h gnumake.h gettext.h job.h output.h debug.h \
filedef.h hash.h commands.h variable.h debug.h vmsjobs.c
load.obj: load.c makeint.h config.h gnumake.h gettext.h
main.obj: main.c makeint.h config.h gnumake.h gettext.h filedef.h hash.h \
dep.h variable.h job.h output.h commands.h rule.h debug.h getopt.h
misc.obj: misc.c makeint.h config.h gnumake.h gettext.h filedef.h hash.h \
dep.h debug.h
output.obj: output.c makeint.h config.h gnumake.h gettext.h job.h output.h
read.obj: read.c makeint.h config.h gnumake.h gettext.h [.glob]glob.h \
filedef.h hash.h dep.h job.h output.h commands.h variable.h rule.h \
debug.h
remake.obj: remake.c makeint.h config.h gnumake.h gettext.h filedef.h \
hash.h job.h output.h commands.h dep.h variable.h debug.h
remote-stub.obj: remote-stub.c makeint.h config.h gnumake.h gettext.h \
filedef.h hash.h job.h output.h commands.h
rule.obj: rule.c makeint.h config.h gnumake.h gettext.h filedef.h hash.h \
dep.h job.h output.h commands.h variable.h rule.h
signame.obj: signame.c makeint.h config.h gnumake.h gettext.h
strcache.obj: strcache.c makeint.h config.h gnumake.h gettext.h hash.h
variable.obj: variable.c makeint.h config.h gnumake.h gettext.h filedef.h \
hash.h dep.h job.h output.h commands.h variable.h rule.h
version.obj: version.c config.h
vmsfunctions.obj: vmsfunctions.c makeint.h vmsdir.h debug.h job.h
vmsfunctions.obj: vmsfunctions.c makeint.h config.h gnumake.h gettext.h \
debug.h job.h output.h vmsdir.h
vmsify.obj: vmsify.c
vpath.obj: vpath.c makeint.h filedef.h variable.h
[.glob]fnmatch.obj: [.glob]fnmatch.c [.glob]fnmatch.h config.h
[.glob]glob.obj: [.glob]glob.c [.glob]glob.h [.glob]fnmatch.h config.h
vpath.obj: vpath.c makeint.h config.h gnumake.h gettext.h filedef.h hash.h \
variable.h
vms_progname.obj: vms_progname.c
vms_exit.obj: vms_exit.c
vms_export_symbol.obj: vms_export_symbol.c
config.h: config.h-vms
$(CP) $< $@

248
makeint.h
View File

@@ -1,5 +1,5 @@
/* Miscellaneous global declarations and portability cruft for GNU Make.
Copyright (C) 1988-2013 Free Software Foundation, Inc.
Copyright (C) 1988-2016 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
@@ -95,8 +95,13 @@ char *alloca ();
extern int errno;
#endif
#ifndef isblank
# define isblank(c) ((c) == ' ' || (c) == '\t')
#ifdef __VMS
/* In strict ANSI mode, VMS compilers should not be defining the
VMS macro. Define it here instead of a bulk edit for the correct code.
*/
# ifndef VMS
# define VMS
# endif
#endif
#ifdef HAVE_UNISTD_H
@@ -129,6 +134,10 @@ extern int errno;
# define SA_RESTART 0
#endif
#ifdef HAVE_VFORK_H
# include <vfork.h>
#endif
#ifdef HAVE_LIMITS_H
# include <limits.h>
#endif
@@ -173,9 +182,6 @@ unsigned int get_path_max (void);
(! INTEGER_TYPE_SIGNED (t) ? (t) 0 : ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1))
#define INTEGER_TYPE_MAXIMUM(t) (~ (t) 0 - INTEGER_TYPE_MINIMUM (t))
/* The maximum number of digits needed to represent the largest integer. */
#define INTEGER_LENGTH sizeof("18446744073709551616")
#ifndef CHAR_MAX
# define CHAR_MAX INTEGER_TYPE_MAXIMUM (char)
#endif
@@ -204,6 +210,13 @@ unsigned int get_path_max (void);
# include <perror.h>
/* Needed to use alloca on VMS. */
# include <builtins.h>
extern int vms_use_mcr_command;
extern int vms_always_use_cmd_file;
extern int vms_gnv_shell;
extern int vms_comma_separator;
extern int vms_legacy_behavior;
extern int vms_unix_simulation;
#endif
#ifndef __attribute__
@@ -328,21 +341,6 @@ char *strsignal (int signum);
#define N_(msgid) gettext_noop (msgid)
#define S_(msg1,msg2,num) ngettext (msg1,msg2,num)
/* Handle other OSs.
To overcome an issue parsing paths in a DOS/Windows environment when
built in a unix based environment, override the PATH_SEPARATOR_CHAR
definition unless being built for Cygwin. */
#if defined(HAVE_DOS_PATHS) && !defined(__CYGWIN__)
# undef PATH_SEPARATOR_CHAR
# define PATH_SEPARATOR_CHAR ';'
#elif !defined(PATH_SEPARATOR_CHAR)
# if defined (VMS)
# define PATH_SEPARATOR_CHAR ','
# else
# define PATH_SEPARATOR_CHAR ':'
# endif
#endif
/* This is needed for getcwd() and chdir(), on some W32 systems. */
#if defined(HAVE_DIRECT_H)
# include <direct.h>
@@ -353,8 +351,8 @@ char *strsignal (int signum);
# include <malloc.h>
# define pipe(_p) _pipe((_p), 512, O_BINARY)
# define kill(_pid,_sig) w32_kill((_pid),(_sig))
/* MSVC doesn't have ftruncate. */
# ifdef _MSC_VER
/* MSVC and Watcom C don't have ftruncate. */
# if defined(_MSC_VER) || defined(__WATCOMC__)
# define ftruncate(_fd,_len) _chsize(_fd,_len)
# endif
/* MinGW64 doesn't have _S_ISDIR. */
@@ -378,7 +376,7 @@ extern int unixy_shell;
# endif
/* Include only the minimal stuff from windows.h. */
#define WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
#endif /* WINDOWS32 */
#define ANY_SET(_v,_m) (((_v)&(_m)) != 0)
@@ -386,7 +384,7 @@ extern int unixy_shell;
#define MAP_NUL 0x0001
#define MAP_BLANK 0x0002
#define MAP_SPACE 0x0004
#define MAP_NEWLINE 0x0004
#define MAP_COMMENT 0x0008
#define MAP_SEMI 0x0010
#define MAP_EQUALS 0x0020
@@ -396,10 +394,12 @@ extern int unixy_shell;
#define MAP_DOT 0x0200
#define MAP_COMMA 0x0400
/* These are the valid characters for a user-defined function. */
#define MAP_USERFUNC 0x2000
/* This means not only a '$', but skip the variable reference. */
#define MAP_VARIABLE 0x4000
/* The set of characters which are path separators is OS-specific. */
#define MAP_PATHSEP 0x8000
/* The set of characters which are directory separators is OS-specific. */
#define MAP_DIRSEP 0x8000
#ifdef VMS
# define MAP_VMSCOMMA MAP_COMMA
@@ -407,7 +407,40 @@ extern int unixy_shell;
# define MAP_VMSCOMMA 0x0000
#endif
#define STOP_SET(_v,_m) ANY_SET (stopchar_map[(int)(_v)],(_m))
#define MAP_SPACE (MAP_BLANK|MAP_NEWLINE)
/* Handle other OSs.
To overcome an issue parsing paths in a DOS/Windows environment when
built in a unix based environment, override the PATH_SEPARATOR_CHAR
definition unless being built for Cygwin. */
#if defined(HAVE_DOS_PATHS) && !defined(__CYGWIN__)
# undef PATH_SEPARATOR_CHAR
# define PATH_SEPARATOR_CHAR ';'
# define MAP_PATHSEP MAP_SEMI
#elif !defined(PATH_SEPARATOR_CHAR)
# if defined (VMS)
# define PATH_SEPARATOR_CHAR (vms_comma_separator ? ',' : ':')
# define MAP_PATHSEP (vms_comma_separator ? MAP_COMMA : MAP_SEMI)
# else
# define PATH_SEPARATOR_CHAR ':'
# define MAP_PATHSEP MAP_COLON
# endif
#elif PATH_SEPARATOR_CHAR == ':'
# define MAP_PATHSEP MAP_COLON
#elif PATH_SEPARATOR_CHAR == ';'
# define MAP_PATHSEP MAP_SEMI
#elif PATH_SEPARATOR_CHAR == ','
# define MAP_PATHSEP MAP_COMMA
#else
# error "Unknown PATH_SEPARATOR_CHAR"
#endif
#define STOP_SET(_v,_m) ANY_SET(stopchar_map[(unsigned char)(_v)],(_m))
#define ISBLANK(c) STOP_SET((c),MAP_BLANK)
#define ISSPACE(c) STOP_SET((c),MAP_SPACE)
#define NEXT_TOKEN(s) while (ISSPACE (*(s))) ++(s)
#define END_OF_TOKEN(s) while (! STOP_SET (*(s), MAP_SPACE|MAP_NUL)) ++(s)
#if defined(HAVE_SYS_RESOURCE_H) && defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT)
# define SET_STACK_SIZE
@@ -417,19 +450,56 @@ extern int unixy_shell;
extern struct rlimit stack_limit;
#endif
#define NILF ((gmk_floc *)0)
#include <glob.h>
#define CSTRLEN(_s) (sizeof (_s)-1)
#define NILF ((floc *)0)
#define CSTRLEN(_s) (sizeof (_s)-1)
#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")
#define DEFAULT_TTYNAME "true"
#ifdef HAVE_TTYNAME
# define TTYNAME(_f) ttyname (_f)
#else
# define TTYNAME(_f) DEFAULT_TTYNAME
#endif
/* Specify the location of elements read from makefiles. */
typedef struct
{
const char *filenm;
unsigned long lineno;
unsigned long offset;
} floc;
const char *concat (unsigned int, ...);
void message (int prefix, const char *fmt, ...)
__attribute__ ((__format__ (__printf__, 2, 3)));
void error (const gmk_floc *flocp, const char *fmt, ...)
__attribute__ ((__format__ (__printf__, 2, 3)));
void fatal (const gmk_floc *flocp, const char *fmt, ...)
__attribute__ ((noreturn, __format__ (__printf__, 2, 3)));
void message (int prefix, size_t length, const char *fmt, ...)
__attribute__ ((__format__ (__printf__, 3, 4)));
void error (const floc *flocp, size_t length, const char *fmt, ...)
__attribute__ ((__format__ (__printf__, 3, 4)));
void fatal (const floc *flocp, size_t length, const char *fmt, ...)
__attribute__ ((noreturn, __format__ (__printf__, 3, 4)));
#define O(_t,_a,_f) _t((_a), 0, (_f))
#define OS(_t,_a,_f,_s) _t((_a), strlen (_s), (_f), (_s))
#define OSS(_t,_a,_f,_s1,_s2) _t((_a), strlen (_s1) + strlen (_s2), \
(_f), (_s1), (_s2))
#define OSSS(_t,_a,_f,_s1,_s2,_s3) _t((_a), strlen (_s1) + strlen (_s2) + strlen (_s3), \
(_f), (_s1), (_s2), (_s3))
#define ON(_t,_a,_f,_n) _t((_a), INTSTR_LENGTH, (_f), (_n))
#define ONN(_t,_a,_f,_n1,_n2) _t((_a), INTSTR_LENGTH*2, (_f), (_n1), (_n2))
#define OSN(_t,_a,_f,_s,_n) _t((_a), strlen (_s) + INTSTR_LENGTH, \
(_f), (_s), (_n))
#define ONS(_t,_a,_f,_n,_s) _t((_a), INTSTR_LENGTH + strlen (_s), \
(_f), (_n), (_s))
#define OUT_OF_MEM() O (fatal, NILF, _("virtual memory exhausted"))
void die (int) __attribute__ ((noreturn));
void pfatal_with_name (const char *) __attribute__ ((noreturn));
@@ -459,7 +529,8 @@ time_t ar_member_date (const char *);
typedef long int (*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,
int gid, int mode, const void *arg);
int gid, unsigned int mode,
const void *arg);
long int 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);
@@ -473,6 +544,8 @@ int file_exists_p (const char *);
int file_impossible_p (const char *);
void file_impossible (const char *);
const char *dir_name (const char *);
void print_dir_data_base (void);
void dir_setup_glob (glob_t *);
void hash_init_directories (void);
void define_default_variables (void);
@@ -495,22 +568,21 @@ void child_access (void);
char *strip_whitespace (const char **begpp, const char **endpp);
void show_goal_error (void);
/* String caching */
void strcache_init (void);
void strcache_print_stats (const char *prefix);
int strcache_iscached (const char *str);
const char *strcache_add (const char *str);
const char *strcache_add_len (const char *str, unsigned int len);
int strcache_setbufsize (unsigned int size);
/* Guile support */
#ifdef HAVE_GUILE
int guile_gmake_setup (const gmk_floc *flocp);
#endif
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 gmk_floc *flocp);
int load_file (const gmk_floc *flocp, const char **filename, int noerror);
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);
/* We omit these declarations on non-POSIX systems which define _POSIX_VERSION,
@@ -523,16 +595,16 @@ long int atol ();
long int lseek ();
# endif
#endif /* Not GNU C library or POSIX. */
#ifdef HAVE_GETCWD
# if !defined(VMS) && !defined(__DECC)
# ifdef HAVE_GETCWD
# if !defined(VMS) && !defined(__DECC)
char *getcwd ();
# endif
#else
# endif
# else
char *getwd ();
# define getcwd(buf, len) getwd (buf)
#endif
# define getcwd(buf, len) getwd (buf)
# endif
#endif /* Not GNU C library or POSIX. */
#if !HAVE_STRCASECMP
# if HAVE_STRICMP
@@ -556,20 +628,17 @@ int strncasecmp (const char *s1, const char *s2, int n);
# endif
#endif
#ifdef POSIX
# define OUTPUT_SYNC
#endif
#define OUTPUT_SYNC_NONE 0
#define OUTPUT_SYNC_LINE 1
#define OUTPUT_SYNC_TARGET 2
#define OUTPUT_SYNC_RECURSE 3
extern const gmk_floc *reading_file;
extern const gmk_floc **expanding_var;
/* Non-GNU systems may not declare this in unistd.h. */
extern char **environ;
extern const floc *reading_file;
extern const floc **expanding_var;
extern unsigned short stopchar_map[];
extern int just_print_flag, silent_flag, ignore_errors_flag, keep_going_flag;
@@ -580,6 +649,8 @@ extern int warn_undefined_variables_flag, trace_flag, posix_pedantic;
extern int not_parallel, second_expansion, clock_skew_detected;
extern int rebuilding_makefiles, one_shell, output_sync, verify_flag;
extern const char *default_shell;
/* can we run commands via 'sh -c xxx' or must we use batch files? */
extern int batch_mode_shell;
@@ -589,15 +660,59 @@ extern int batch_mode_shell;
extern char cmd_prefix;
extern unsigned int job_slots;
extern int job_fds[2];
extern int job_rfd;
#ifndef NO_FLOAT
extern double max_load_average;
#else
extern int max_load_average;
#endif
#ifdef WINDOWS32
extern char *program;
#else
extern const char *program;
#endif
#ifdef VMS
const char *vms_command (const char *argv0);
const char *vms_progname (const char *argv0);
void vms_exit (int);
# define _exit(foo) vms_exit(foo)
# define exit(foo) vms_exit(foo)
extern char *program_name;
void
set_program_name (const char *arv0);
int
need_vms_symbol (void);
int
create_foreign_command (const char *command, const char *image);
int
vms_export_dcl_symbol (const char *name, const char *value);
int
vms_putenv_symbol (const char *string);
void
vms_restore_symbol (const char *string);
#endif
void remote_setup (void);
void remote_cleanup (void);
int start_remote_job_p (int);
int start_remote_job (char **, char **, int, int *, int *, int *);
int remote_status (int *, int *, int *, int);
void block_remote_children (void);
void unblock_remote_children (void);
int remote_kill (int id, int sig);
void print_variable_data_base (void);
void print_vpath_data_base (void);
extern char *starting_directory;
extern unsigned int makelevel;
extern char *version_string, *remote_description, *make_host;
@@ -614,15 +729,10 @@ extern int handling_fatal_signal;
#define MAX(_a,_b) ((_a)>(_b)?(_a):(_b))
#endif
#ifdef VMS
# define MAKE_SUCCESS 1
# define MAKE_TROUBLE 2
# define MAKE_FAILURE 3
#else
# define MAKE_SUCCESS 0
# define MAKE_TROUBLE 1
# define MAKE_FAILURE 2
#endif
#define MAKE_SUCCESS 0
#define MAKE_TROUBLE 1
#define MAKE_FAILURE 2
/* Set up heap debugging library dmalloc. */

43
misc.c
View File

@@ -1,5 +1,5 @@
/* Miscellaneous generic support functions for GNU Make.
Copyright (C) 1988-2013 Free Software Foundation, Inc.
Copyright (C) 1988-2016 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
@@ -15,6 +15,7 @@ You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
#include "makeint.h"
#include "filedef.h"
#include "dep.h"
#include "debug.h"
@@ -90,12 +91,13 @@ collapse_continuations (char *line)
{
/* Backslash/newline handling:
In traditional GNU make all trailing whitespace, consecutive
backslash/newlines, and any leading whitespace on the next line
is reduced to a single space.
backslash/newlines, and any leading non-newline whitespace on the
next line is reduced to a single space.
In POSIX, each backslash/newline and is replaced by a space. */
in = next_token (in);
while (ISBLANK (*in))
++in;
if (! posix_pedantic)
while (out > line && isblank ((unsigned char)out[-1]))
while (out > line && ISBLANK (out[-1]))
--out;
*out++ = ' ';
}
@@ -218,7 +220,7 @@ xmalloc (unsigned int size)
/* Make sure we don't allocate 0, for pre-ISO implementations. */
void *result = malloc (size ? size : 1);
if (result == 0)
fatal (NILF, _("virtual memory exhausted"));
OUT_OF_MEM();
return result;
}
@@ -229,7 +231,7 @@ xcalloc (unsigned int size)
/* Make sure we don't allocate 0, for pre-ISO implementations. */
void *result = calloc (size ? size : 1, 1);
if (result == 0)
fatal (NILF, _("virtual memory exhausted"));
OUT_OF_MEM();
return result;
}
@@ -244,7 +246,7 @@ xrealloc (void *ptr, unsigned int size)
size = 1;
result = ptr ? realloc (ptr, size) : malloc (size);
if (result == 0)
fatal (NILF, _("virtual memory exhausted"));
OUT_OF_MEM();
return result;
}
@@ -261,7 +263,7 @@ xstrdup (const char *ptr)
#endif
if (result == 0)
fatal (NILF, _("virtual memory exhausted"));
OUT_OF_MEM();
#ifdef HAVE_STRDUP
return result;
@@ -280,7 +282,7 @@ xstrndup (const char *str, unsigned int length)
#ifdef HAVE_STRNDUP
result = strndup (str, length);
if (result == 0)
fatal (NILF, _("virtual memory exhausted"));
OUT_OF_MEM();
#else
result = xmalloc (length + 1);
if (length > 0)
@@ -313,8 +315,7 @@ lindex (const char *s, const char *limit, int c)
char *
end_of_token (const char *s)
{
while (! STOP_SET (*s, MAP_BLANK|MAP_NUL))
++s;
END_OF_TOKEN (s);
return (char *)s;
}
@@ -323,8 +324,7 @@ end_of_token (const char *s)
char *
next_token (const char *s)
{
while (isblank ((unsigned char)*s))
++s;
NEXT_TOKEN (s);
return (char *)s;
}
@@ -376,19 +376,6 @@ copy_dep_chain (const struct dep *d)
return firstnew;
}
/* Free a chain of 'struct dep'. */
void
free_dep_chain (struct dep *d)
{
while (d != 0)
{
struct dep *df = d;
d = d->next;
free_dep (df);
}
}
/* Free a chain of struct nameseq.
For struct dep chains use free_dep_chain. */
@@ -399,7 +386,7 @@ free_ns_chain (struct nameseq *ns)
{
struct nameseq *t = ns;
ns = ns->next;
free (t);
free_ns (t);
}
}

84
os.h Normal file
View File

@@ -0,0 +1,84 @@
/* Declarations for operating system interfaces for GNU Make.
Copyright (C) 2016 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 <http://www.gnu.org/licenses/>. */
/* This section provides OS-specific functions to support the jobserver. */
#ifdef MAKE_JOBSERVER
/* 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 a child instance to connect to the jobserver. */
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. */
void jobserver_clear (void);
/* Recover all the jobserver tokens and return the number we got. */
unsigned int jobserver_acquire_all (void);
/* Release a jobserver token. If it fails and is_fatal is 1, fatal. */
void jobserver_release (int is_fatal);
/* Notify the jobserver that a child exited. */
void jobserver_signal (void);
/* Get ready to start a non-recursive child. */
void jobserver_pre_child (int);
/* Complete starting a non-recursive child. */
void jobserver_post_child (int);
/* Set up to acquire a new token. */
void jobserver_pre_acquire (void);
/* Wait until we can acquire a jobserver token.
TIMEOUT is 1 if we have other jobs waiting for the load to go down;
in this case we won't wait forever, so we can check the load.
Returns 1 if we got a token, or 0 if we stopped waiting due to a child
exiting or a timeout. */
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)
#endif
/* Create a "bad" file descriptor for stdin when parallel jobs are run. */
#if !defined(VMD) && !defined(WINDOWS32) && !defined(_AMIGA) && !defined(__MSDOS__)
int get_bad_stdin (void);
#else
# define get_bad_stdin() (-1)
#endif

228
output.c
View File

@@ -1,5 +1,5 @@
/* Output to stdout / stderr for GNU make
Copyright (C) 2013 Free Software Foundation, Inc.
Copyright (C) 2013-2016 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
@@ -22,7 +22,10 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#include <assert.h>
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
@@ -30,32 +33,23 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
# include <sys/file.h>
#endif
#ifdef WINDOWS32
# include <windows.h>
# include <io.h>
# include "sub_proc.h"
#endif /* WINDOWS32 */
struct output *output_context = NULL;
static unsigned int stdio_traced = 0;
unsigned int stdio_traced = 0;
#define OUTPUT_NONE (-1)
#define OUTPUT_ISSET(_out) ((_out)->out >= 0 || (_out)->err >= 0)
/* I really want to move to gnulib. However, this is a big undertaking
especially for non-UNIX platforms: how to get bootstrapping to work, etc.
I don't want to take the time to do it right now. Use a hack to get a
useful version of vsnprintf() for Windows. */
#ifdef _MSC_VER
#define va_copy(_d, _s) ((_d) = (_s))
#define snprintf msc_vsnprintf
static int
msc_vsnprintf (char *str, size_t size, const char *format, va_list ap)
{
int len = -1;
if (size > 0)
len = _vsnprintf_s (str, size, _TRUNCATE, format, ap);
if (len == -1)
len = _vscprintf (format, ap);
return len;
}
#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. */
@@ -78,10 +72,8 @@ _outputs (struct output *out, int is_err, const char *msg)
while (1)
{
EINTRLOOP (r, write (fd, msg, len));
if (r == len)
if (r == len || r <= 0)
break;
if (r <= 0)
return;
len -= r;
msg += r;
}
@@ -92,7 +84,7 @@ _outputs (struct output *out, int is_err, const char *msg)
left (according to ENTERING) the current directory. */
static int
log_working_directory (struct output *out, int entering)
log_working_directory (int entering)
{
static char *buf = NULL;
static unsigned int len = 0;
@@ -101,7 +93,7 @@ log_working_directory (struct output *out, int entering)
char *p;
/* Get enough space for the longest possible output. */
need = strlen (program) + INTEGER_LENGTH + 2 + 1;
need = strlen (program) + INTSTR_LENGTH + 2 + 1;
if (starting_directory)
need += strlen (starting_directory);
@@ -154,7 +146,7 @@ log_working_directory (struct output *out, int entering)
else
sprintf (p, fmt, program, makelevel, starting_directory);
_outputs (out, 0, buf);
_outputs (NULL, 0, buf);
return 1;
}
@@ -173,18 +165,16 @@ set_append_mode (int fd)
}
#ifdef OUTPUT_SYNC
#ifndef NO_OUTPUT_SYNC
/* Semaphore for use in -j mode with output_sync. */
static sync_handle_t sync_handle = -1;
#define STREAM_OK(_s) ((fcntl (fileno (_s), F_GETFD) != -1) || (errno != EBADF))
#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 ()
sync_init (void)
{
int combined_output = 0;
@@ -250,7 +240,11 @@ pump_from_tmp (int from, FILE *to)
if (len <= 0)
break;
if (fwrite (buffer, len, 1, to) < 1)
perror ("fwrite()");
{
perror ("fwrite()");
break;
}
fflush (to);
}
#ifdef WINDOWS32
@@ -289,7 +283,7 @@ release_semaphore (void *sem)
/* Returns a file descriptor to a temporary file. The file is automatically
closed/deleted on exit. Don't use a FILE* stream. */
int
output_tmpfd ()
output_tmpfd (void)
{
int fd = -1;
FILE *tfile = tmpfile ();
@@ -350,7 +344,7 @@ setup_tmpfile (struct output *out)
/* If we failed to create a temp file, disable output sync going forward. */
error:
output_close (out);
output_sync = 0;
output_sync = OUTPUT_SYNC_NONE;
}
/* Synchronize the output of jobs in -j mode to keep the results of
@@ -369,22 +363,21 @@ output_dump (struct output *out)
int traced = 0;
/* Try to acquire the semaphore. If it fails, dump the output
unsynchronized; still better than silently discarding it. */
unsynchronized; still better than silently discarding it.
We want to keep this lock for as little time as possible. */
void *sem = acquire_semaphore ();
/* Log the working directory for this dump. */
if (print_directory_flag && output_sync != OUTPUT_SYNC_RECURSE)
traced = log_working_directory (output_context, 1);
traced = log_working_directory (1);
/* We've entered the "critical section" during which a lock is held. We
want to keep it as short as possible. */
if (outfd_not_empty)
pump_from_tmp (out->out, stdout);
if (errfd_not_empty && out->err != out->out)
pump_from_tmp (out->err, stderr);
if (traced)
log_working_directory (output_context, 0);
log_working_directory (0);
/* Exit the critical section. */
if (sem)
@@ -405,7 +398,7 @@ output_dump (struct output *out)
}
}
}
#endif /* OUTPUT_SYNC */
#endif /* NO_OUTPUT_SYNC */
/* Provide support for temporary files. */
@@ -448,7 +441,7 @@ output_tmpfile (char **name, const char *template)
# ifdef HAVE_FDOPEN
/* Can't use mkstemp(), but guard against a race condition. */
fd = open (*name, O_CREAT|O_EXCL|O_WRONLY, 0600);
EINTRLOOP (fd, open (*name, O_CREAT|O_EXCL|O_WRONLY, 0600));
if (fd == -1)
return 0;
return fdopen (fd, "w");
@@ -499,10 +492,10 @@ close_stdout (void)
if (prev_fail || fclose_fail)
{
if (fclose_fail)
error (NILF, _("write error: %s"), strerror (errno));
perror_with_name (_("write error: stdout"), "");
else
error (NILF, _("write error"));
exit (EXIT_FAILURE);
O (error, NILF, _("write error: stdout"));
exit (MAKE_TROUBLE);
}
}
@@ -547,11 +540,11 @@ output_close (struct output *out)
if (! out)
{
if (stdio_traced)
log_working_directory (NULL, 0);
log_working_directory (0);
return;
}
#ifdef OUTPUT_SYNC
#ifndef NO_OUTPUT_SYNC
output_dump (out);
#endif
@@ -565,18 +558,20 @@ output_close (struct output *out)
/* We're about to generate output: be sure it's set up. */
void
output_start ()
output_start (void)
{
#ifdef OUTPUT_SYNC
if (output_context && output_context->syncout && ! OUTPUT_ISSET(output_context))
setup_tmpfile (output_context);
#ifndef NO_OUTPUT_SYNC
/* If we're syncing output make sure the temporary file is set up. */
if (output_context && output_context->syncout)
if (! OUTPUT_ISSET(output_context))
setup_tmpfile (output_context);
#endif
if (! output_context || output_sync == OUTPUT_SYNC_RECURSE)
{
if (! stdio_traced && print_directory_flag)
stdio_traced = log_working_directory (NULL, 1);
}
/* 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)
stdio_traced = log_working_directory (1);
}
void
@@ -591,141 +586,120 @@ outputs (int is_err, const char *msg)
}
/* Return formatted string buffers.
If we move to gnulib we can use vasnprintf() etc. to make this simpler.
Note these functions use a static buffer, so each call overwrites the
results of the previous call. */
static struct fmtstring
{
char *buffer;
unsigned int size;
unsigned int len;
} fmtbuf = { NULL, 0, 0 };
size_t size;
} fmtbuf = { NULL, 0 };
/* Concatenate a formatted string onto the format buffer. */
static const char *
vfmtconcat (const char *fmt, va_list args)
static char *
get_buffer (size_t need)
{
va_list vcopy;
int tot;
int unused = fmtbuf.size - fmtbuf.len;
va_copy (vcopy, args);
tot = vsnprintf (&fmtbuf.buffer[fmtbuf.len], unused, fmt, args);
assert (tot >= 0);
if (tot >= unused)
/* Make sure we have room. NEED includes space for \0. */
if (need > fmtbuf.size)
{
fmtbuf.size += tot * 2;
fmtbuf.size += need * 2;
fmtbuf.buffer = xrealloc (fmtbuf.buffer, fmtbuf.size);
unused = fmtbuf.size - fmtbuf.len;
tot = vsnprintf (&fmtbuf.buffer[fmtbuf.len], unused, fmt, vcopy);
}
va_end (vcopy);
fmtbuf.len += tot;
fmtbuf.buffer[need-1] = '\0';
return fmtbuf.buffer;
}
static const char *
fmtconcat (const char *fmt, ...)
{
const char *p;
va_list args;
va_start (args, fmt);
p = vfmtconcat (fmt, args);
va_end (args);
return p;
}
/* Print a message on stdout. */
void
message (int prefix, const char *fmt, ...)
message (int prefix, size_t len, const char *fmt, ...)
{
va_list args;
char *p;
assert (fmt != NULL);
fmtbuf.len = 0;
len += strlen (fmt) + strlen (program) + INTSTR_LENGTH + 4 + 1 + 1;
p = get_buffer (len);
if (prefix)
{
if (makelevel == 0)
fmtconcat ("%s: ", program);
sprintf (p, "%s: ", program);
else
fmtconcat ("%s[%u]: ", program, makelevel);
sprintf (p, "%s[%u]: ", program, makelevel);
p += strlen (p);
}
va_start (args, fmt);
vfmtconcat (fmt, args);
vsprintf (p, fmt, args);
va_end (args);
fmtconcat ("\n");
strcat (p, "\n");
assert (fmtbuf.buffer[len-1] == '\0');
outputs (0, fmtbuf.buffer);
}
/* Print an error message. */
void
error (const gmk_floc *flocp, const char *fmt, ...)
error (const floc *flocp, size_t len, const char *fmt, ...)
{
va_list args;
char *p;
assert (fmt != NULL);
fmtbuf.len = 0;
len += (strlen (fmt) + strlen (program)
+ (flocp && flocp->filenm ? strlen (flocp->filenm) : 0)
+ INTSTR_LENGTH + 4 + 1 + 1);
p = get_buffer (len);
if (flocp && flocp->filenm)
fmtconcat ("%s:%lu: ", flocp->filenm, flocp->lineno);
sprintf (p, "%s:%lu: ", flocp->filenm, flocp->lineno + flocp->offset);
else if (makelevel == 0)
fmtconcat ("%s: ", program);
sprintf (p, "%s: ", program);
else
fmtconcat ("%s[%u]: ", program, makelevel);
sprintf (p, "%s[%u]: ", program, makelevel);
p += strlen (p);
va_start (args, fmt);
vfmtconcat (fmt, args);
vsprintf (p, fmt, args);
va_end (args);
fmtconcat ("\n");
strcat (p, "\n");
assert (fmtbuf.buffer[len-1] == '\0');
outputs (1, fmtbuf.buffer);
}
/* Print an error message and exit. */
void
fatal (const gmk_floc *flocp, const char *fmt, ...)
fatal (const floc *flocp, size_t len, const char *fmt, ...)
{
va_list args;
const char *stop = _(". Stop.\n");
char *p;
assert (fmt != NULL);
fmtbuf.len = 0;
len += (strlen (fmt) + strlen (program)
+ (flocp && flocp->filenm ? strlen (flocp->filenm) : 0)
+ INTSTR_LENGTH + 8 + strlen (stop) + 1);
p = get_buffer (len);
if (flocp && flocp->filenm)
fmtconcat ("%s:%lu: *** ", flocp->filenm, flocp->lineno);
sprintf (p, "%s:%lu: *** ", flocp->filenm, flocp->lineno + flocp->offset);
else if (makelevel == 0)
fmtconcat ("%s: *** ", program);
sprintf (p, "%s: *** ", program);
else
fmtconcat ("%s[%u]: *** ", program, makelevel);
sprintf (p, "%s[%u]: *** ", program, makelevel);
p += strlen (p);
va_start (args, fmt);
vfmtconcat (fmt, args);
vsprintf (p, fmt, args);
va_end (args);
fmtconcat (_(". Stop.\n"));
strcat (p, stop);
assert (fmtbuf.buffer[len-1] == '\0');
outputs (1, fmtbuf.buffer);
die (2);
die (MAKE_FAILURE);
}
/* Print an error message from errno. */
@@ -733,7 +707,8 @@ fatal (const gmk_floc *flocp, const char *fmt, ...)
void
perror_with_name (const char *str, const char *name)
{
error (NILF, _("%s%s: %s"), str, name, strerror (errno));
const char *err = strerror (errno);
OSSS (error, NILF, _("%s%s: %s"), str, name, err);
}
/* Print an error message from errno and exit. */
@@ -741,7 +716,8 @@ perror_with_name (const char *str, const char *name)
void
pfatal_with_name (const char *name)
{
fatal (NILF, _("%s: %s"), name, strerror (errno));
const char *err = strerror (errno);
OSS (fatal, NILF, _("%s: %s"), name, err);
/* NOTREACHED */
}

View File

@@ -1,5 +1,5 @@
/* Output to stdout / stderr for GNU make
Copyright (C) 2013 Free Software Foundation, Inc.
Copyright (C) 2013-2016 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
@@ -22,10 +22,14 @@ struct output
};
extern struct output *output_context;
extern unsigned int stdio_traced;
#define OUTPUT_SET(_new) do{ if ((_new)->syncout) output_context = (_new); }while(0)
#define OUTPUT_SET(_new) do{ output_context = (_new)->syncout ? (_new) : NULL; }while(0)
#define OUTPUT_UNSET() do{ output_context = NULL; }while(0)
#define OUTPUT_TRACED() do{ stdio_traced = 1; }while(0)
#define OUTPUT_IS_TRACED() (!!stdio_traced)
FILE *output_tmpfile (char **, const char *);
/* Initialize and close a child output structure: if NULL do this program's
@@ -40,7 +44,7 @@ void output_start (void);
/* Show a message on stdout or stderr. Will start the output if needed. */
void outputs (int is_err, const char *msg);
#ifdef OUTPUT_SYNC
#ifndef NO_OUTPUT_SYNC
int output_tmpfd (void);
/* Dump any child output content to stdout, and reset it. */
void output_dump (struct output *out);

View File

@@ -1,93 +0,0 @@
2013-01-06 Paul Smith <psmith@gnu.org>
* POTFILES.in: Add new load.c file.
2012-01-12 Paul Smith <psmith@gnu.org>
* POTFILES.in: Add new guile.c file.
2011-09-26 Paul Smith <psmith@gnu.org>
* LINGUAS: Added new translation file for Czech (cs).
2009-09-16 Paul Smith <psmith@gnu.org>
* LINGUAS: Added new translation for Italian (it).
2008-05-17 Paul Smith <psmith@gnu.org>
* LINGUAS: Added new translation for Lithuanian (lt).
2007-08-15 Paul Smith <psmith@gnu.org>
* LINGUAS: The Kinyarwanda (rw) translation has disappeared from
the translation site, so remove it.
2006-01-28 Paul D. Smith <psmith@gnu.org>
* LINGUAS: Added new translation for Vietnamese (vi).
2005-07-14 Paul D. Smith <psmith@gnu.org>
* LINGUAS: Added new translation for Indonesian (id).
2005-05-09 Paul D. Smith <psmith@gnu.org>
* POTFILES.in: Add new file vmsjobs.c.
2005-04-06 Paul D. Smith <psmith@gnu.org>
* LINGUAS: Added a new translation for Kinywarwanda (rw).
2005-02-09 Paul D. Smith <psmith@gnu.org>
* LINGUAS: Added a new translation for Irish (ga).
2005-02-01 Paul D. Smith <psmith@gnu.org>
* LINGUAS: Added a new translation for Finnish (fi).
2003-10-18 Paul D. Smith <psmith@gnu.org>
* LINGUAS: Added a new translation for Belarusian (be).
2002-12-19 Paul D. Smith <psmith@gnu.org>
* LINGUAS: Added a new translation for Ukrainian (uk).
2002-10-05 Paul D. Smith <psmith@gnu.org>
* POTFILES.in: Add variable.h as it has a translatable string.
2002-08-08 Paul D. Smith <psmith@gnu.org>
* LINGUAS: Add a new translation for Chinese (simplified) (zh_CN).
2002-08-02 Paul D. Smith <psmith@gnu.org>
* LINGUAS: Add a new translation for Swedish (sv).
2002-04-21 Paul D. Smith <psmith@gnu.org>
* LINGUAS, hr.po: Added new translation: Croatian.
* da.po, de.po, es.po, fr.po, gl.po, he.po, ja.po, ko.po, nl.po,
pl.po, pt_BR.po, ru.po, tr.po: Moved from i18n to here.
* .cvsignore: Moved from i18n to here.
* POTFILES.in, LINGUAS, Makevars: Created.
Copyright (C) 2002-2013 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 <http://www.gnu.org/licenses/>.

View File

@@ -1,5 +1,5 @@
# This is a -*-Makefile-*-
# Copyright (C) 2002-2013 Free Software Foundation, Inc.
# Copyright (C) 2002-2016 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

View File

@@ -1,5 +1,5 @@
# List of source files containing translatable strings.
# Copyright (C) 2000-2013 Free Software Foundation, Inc.
# Copyright (C) 2000-2016 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
@@ -32,6 +32,7 @@ load.c
main.c
misc.c
output.c
posixos.c
read.c
remake.c
remote-cstms.c
@@ -43,3 +44,4 @@ variable.h
vmsfunctions.c
vmsjobs.c
vpath.c
w32/w32os.c

431
posixos.c Normal file
View File

@@ -0,0 +1,431 @@
/* POSIX-based operating system interface for GNU Make.
Copyright (C) 2016 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 <http://www.gnu.org/licenses/>. */
#include "makeint.h"
#include <stdio.h>
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#endif
#if defined(HAVE_PSELECT) && defined(HAVE_SYS_SELECT_H)
# include <sys/select.h>
#endif
#include "debug.h"
#include "job.h"
#include "os.h"
#ifdef MAKE_JOBSERVER
/* This section provides OS-specific functions to support the jobserver. */
/* These track the state of the jobserver pipe. Passed to child instances. */
static int job_fds[2] = { -1, -1 };
/* Used to signal read() that a SIGCHLD happened. Always CLOEXEC.
If we use pselect() this will never be created and always -1.
*/
static int job_rfd = -1;
/* Token written to the pipe (could be any character...) */
static char token = '+';
static int
make_job_rfd (void)
{
#ifdef HAVE_PSELECT
/* Pretend we succeeded. */
return 0;
#else
EINTRLOOP (job_rfd, dup (job_fds[0]));
if (job_rfd >= 0)
CLOSE_ON_EXEC (job_rfd);
return job_rfd;
#endif
}
unsigned int
jobserver_setup (int slots)
{
int r;
EINTRLOOP (r, pipe (job_fds));
if (r < 0)
pfatal_with_name (_("creating jobs pipe"));
if (make_job_rfd () < 0)
pfatal_with_name (_("duping jobs pipe"));
while (slots--)
{
EINTRLOOP (r, write (job_fds[1], &token, 1));
if (r != 1)
pfatal_with_name (_("init jobserver pipe"));
}
return 1;
}
unsigned int
jobserver_parse_auth (const char *auth)
{
/* Given the command-line parameter, parse it. */
if (sscanf (auth, "%d,%d", &job_fds[0], &job_fds[1]) != 2)
OS (fatal, NILF,
_("internal error: invalid --jobserver-auth string '%s'"), auth);
DB (DB_JOBS,
(_("Jobserver client (fds %d,%d)\n"), job_fds[0], job_fds[1]));
#ifdef HAVE_FCNTL_H
# define FD_OK(_f) (fcntl ((_f), F_GETFD) != -1)
#else
# define FD_OK(_f) 1
#endif
/* Make sure our pipeline is valid, and (possibly) create a duplicate pipe,
that will be closed in the SIGCHLD handler. If this fails with EBADF,
the parent has closed the pipe on us because it didn't think we were a
submake. If so, warn and default to -j1. */
if (!FD_OK (job_fds[0]) || !FD_OK (job_fds[1]) || make_job_rfd () < 0)
{
if (errno != EBADF)
pfatal_with_name (_("jobserver pipeline"));
job_fds[0] = job_fds[1] = -1;
return 0;
}
return 1;
}
char *
jobserver_get_auth (void)
{
char *auth = xmalloc ((INTSTR_LENGTH * 2) + 2);
sprintf (auth, "%d,%d", job_fds[0], job_fds[1]);
return auth;
}
unsigned int
jobserver_enabled (void)
{
return job_fds[0] >= 0;
}
void
jobserver_clear (void)
{
if (job_fds[0] >= 0)
close (job_fds[0]);
if (job_fds[1] >= 0)
close (job_fds[1]);
if (job_rfd >= 0)
close (job_rfd);
job_fds[0] = job_fds[1] = job_rfd = -1;
}
void
jobserver_release (int is_fatal)
{
int r;
EINTRLOOP (r, write (job_fds[1], &token, 1));
if (r != 1)
{
if (is_fatal)
pfatal_with_name (_("write jobserver"));
perror_with_name ("write", "");
}
}
unsigned int
jobserver_acquire_all (void)
{
unsigned int tokens = 0;
/* Close the write side, so the read() won't hang. */
close (job_fds[1]);
job_fds[1] = -1;
while (1)
{
char intake;
int r;
EINTRLOOP (r, read (job_fds[0], &intake, 1));
if (r != 1)
return tokens;
++tokens;
}
}
/* Prepare the jobserver to start a child process. */
void
jobserver_pre_child (int recursive)
{
/* If it's not a recursive make, avoid polutting the jobserver pipes. */
if (!recursive && job_fds[0] >= 0)
{
CLOSE_ON_EXEC (job_fds[0]);
CLOSE_ON_EXEC (job_fds[1]);
}
}
void
jobserver_post_child (int recursive)
{
#if defined(F_GETFD) && defined(F_SETFD)
if (!recursive && job_fds[0] >= 0)
{
unsigned int i;
for (i = 0; i < 2; ++i)
{
int flags;
EINTRLOOP (flags, fcntl (job_fds[i], F_GETFD));
if (flags >= 0)
{
int r;
EINTRLOOP (r, fcntl (job_fds[i], F_SETFD, flags & ~FD_CLOEXEC));
}
}
}
#endif
}
void
jobserver_signal (void)
{
if (job_rfd >= 0)
{
close (job_rfd);
job_rfd = -1;
}
}
void
jobserver_pre_acquire (void)
{
/* Make sure we have a dup'd FD. */
if (job_rfd < 0 && job_fds[0] >= 0 && make_job_rfd () < 0)
pfatal_with_name (_("duping jobs pipe"));
}
#ifdef HAVE_PSELECT
/* Use pselect() to atomically wait for both a signal and a file descriptor.
It also provides a timeout facility so we don't need to use SIGALRM.
This method relies on the fact that SIGCHLD will be blocked everywhere,
and only unblocked (atomically) within the pselect() call, so we can
never miss a SIGCHLD.
*/
unsigned int
jobserver_acquire (int timeout)
{
sigset_t empty;
fd_set readfds;
struct timespec spec;
struct timespec *specp = NULL;
int r;
char intake;
sigemptyset (&empty);
FD_ZERO (&readfds);
FD_SET (job_fds[0], &readfds);
if (timeout)
{
/* Alarm after one second (is this too granular?) */
spec.tv_sec = 1;
spec.tv_nsec = 0;
specp = &spec;
}
r = pselect (job_fds[0]+1, &readfds, NULL, NULL, specp, &empty);
if (r == -1)
{
/* Better be SIGCHLD. */
if (errno != EINTR)
pfatal_with_name (_("pselect jobs pipe"));
return 0;
}
if (r == 0)
/* Timeout. */
return 0;
/* The read FD is ready: read it! */
EINTRLOOP (r, read (job_fds[0], &intake, 1));
if (r < 0)
pfatal_with_name (_("read jobs pipe"));
/* What does it mean if read() returns 0? It shouldn't happen because only
the master make can reap all the tokens and close the write side...?? */
return r > 0;
}
#else
/* This method uses a "traditional" UNIX model for waiting on both a signal
and a file descriptor. However, it's complex and since we have a SIGCHLD
handler installed we need to check ALL system calls for EINTR: painful!
Read a token. As long as there's no token available we'll block. We
enable interruptible system calls before the read(2) so that if we get a
SIGCHLD while we're waiting, we'll return with EINTR and we can process the
death(s) and return tokens to the free pool.
Once we return from the read, we immediately reinstate restartable system
calls. This allows us to not worry about checking for EINTR on all the
other system calls in the program.
There is one other twist: there is a span between the time reap_children()
does its last check for dead children and the time the read(2) call is
entered, below, where if a child dies we won't notice. This is extremely
serious as it could cause us to deadlock, given the right set of events.
To avoid this, we do the following: before we reap_children(), we dup(2)
the read FD on the jobserver pipe. The read(2) call below uses that new
FD. In the signal handler, we close that FD. That way, if a child dies
during the section mentioned above, the read(2) will be invoked with an
invalid FD and will return immediately with EBADF. */
static RETSIGTYPE
job_noop (int sig UNUSED)
{
}
/* Set the child handler action flags to FLAGS. */
static void
set_child_handler_action_flags (int set_handler, int set_alarm)
{
struct sigaction sa;
#ifdef __EMX__
/* The child handler must be turned off here. */
signal (SIGCHLD, SIG_DFL);
#endif
memset (&sa, '\0', sizeof sa);
sa.sa_handler = child_handler;
sa.sa_flags = set_handler ? 0 : SA_RESTART;
#if defined SIGCHLD
if (sigaction (SIGCHLD, &sa, NULL) < 0)
pfatal_with_name ("sigaction: SIGCHLD");
#endif
#if defined SIGCLD && SIGCLD != SIGCHLD
if (sigaction (SIGCLD, &sa, NULL) < 0)
pfatal_with_name ("sigaction: SIGCLD");
#endif
#if defined SIGALRM
if (set_alarm)
{
/* If we're about to enter the read(), set an alarm to wake up in a
second so we can check if the load has dropped and we can start more
work. On the way out, turn off the alarm and set SIG_DFL. */
if (set_handler)
{
sa.sa_handler = job_noop;
sa.sa_flags = 0;
if (sigaction (SIGALRM, &sa, NULL) < 0)
pfatal_with_name ("sigaction: SIGALRM");
alarm (1);
}
else
{
alarm (0);
sa.sa_handler = SIG_DFL;
sa.sa_flags = 0;
if (sigaction (SIGALRM, &sa, NULL) < 0)
pfatal_with_name ("sigaction: SIGALRM");
}
}
#endif
}
unsigned int
jobserver_acquire (int timeout)
{
char intake;
int got_token;
int saved_errno;
/* Set interruptible system calls, and read() for a job token. */
set_child_handler_action_flags (1, timeout);
EINTRLOOP (got_token, read (job_rfd, &intake, 1));
saved_errno = errno;
set_child_handler_action_flags (0, timeout);
if (got_token == 1)
return 1;
/* If the error _wasn't_ expected (EINTR or EBADF), fatal. Otherwise,
go back and reap_children(), and try again. */
errno = saved_errno;
if (errno != EINTR && errno != EBADF)
pfatal_with_name (_("read jobs pipe"));
if (errno == EBADF)
DB (DB_JOBS, ("Read returned EBADF.\n"));
return 0;
}
#endif
#endif /* MAKE_JOBSERVER */
/* Create a "bad" file descriptor for stdin when parallel jobs are run. */
int
get_bad_stdin (void)
{
static int bad_stdin = -1;
/* Set up a bad standard input that reads from a broken pipe. */
if (bad_stdin == -1)
{
/* Make a file descriptor that is the read end of a broken pipe.
This will be used for some children's standard inputs. */
int pd[2];
if (pipe (pd) == 0)
{
/* Close the write side. */
(void) close (pd[1]);
/* Save the read side. */
bad_stdin = pd[0];
/* Set the descriptor to close on exec, so it does not litter any
child's descriptor table. When it is dup2'd onto descriptor 0,
that descriptor will not close on exec. */
CLOSE_ON_EXEC (bad_stdin);
}
}
return bad_stdin;
}

59
prepare_vms.com Normal file
View File

@@ -0,0 +1,59 @@
$!
$! prepare_vms.com - Build config.h-vms from master on VMS.
$!
$! 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")
$ 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")
$ if config_template .eqs. ""
$ then
$ write sys$output "Could not find config.h-vms*template!"
$ 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
$!
$!
$! Pull the package and version from configure.ac
$!
$ open/read ac_file sys$disk:[]configure.ac
$ac_read_loop:
$ read ac_file/end=ac_read_loop_end line_in
$ key = f$extract(0, 7, line_in)
$ if key .nes. "AC_INIT" then goto ac_read_loop
$ package = f$element (1,"[",line_in)
$ package = f$element (0,"]",package)
$ version = f$element (2,"[",line_in)
$ version = f$element (0,"]",version)
$ac_read_loop_end:
$ close ac_file
$!
$ if (package .eqs. "") .or. (version .eqs. "")
$ then
$ write sys$output "Unable to determine package and/or version!"
$ exit 44
$ endif
$!
$!
$ outfile = "sys$disk:[]config.h-vms"
$!
$! 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" ;-
write sys$output "exit") |-
edit/edt 'config_template'/out='outfile'/command=sys$pipe >nla0:
$!
$ write sys$output package, ", version: ", version, " prepared for VMS"

353
read.c
View File

@@ -1,5 +1,5 @@
/* Reading and parsing of makefiles for GNU Make.
Copyright (C) 1988-2013 Free Software Foundation, Inc.
Copyright (C) 1988-2016 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
@@ -18,10 +18,8 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#include <assert.h>
#include <glob.h>
#include "dep.h"
#include "filedef.h"
#include "dep.h"
#include "job.h"
#include "commands.h"
#include "variable.h"
@@ -54,7 +52,7 @@ struct ebuffer
char *bufstart; /* Start of the entire buffer. */
unsigned int size; /* Malloc'd size of buffer. */
FILE *fp; /* File, or NULL if this is an internal buffer. */
gmk_floc floc; /* Info on the file in fp (if any). */
floc floc; /* Info on the file in fp (if any). */
};
/* Track the modifiers we can have on variable assignments */
@@ -128,13 +126,13 @@ static unsigned int max_incl_len;
/* The filename and pointer to line number of the
makefile currently being read in. */
const gmk_floc *reading_file = 0;
const floc *reading_file = 0;
/* The chain of files read by read_all_makefiles. */
static struct dep *read_files = 0;
static struct goaldep *read_files = 0;
static int eval_makefile (const char *filename, int flags);
static struct goaldep *eval_makefile (const char *filename, int flags);
static void eval (struct ebuffer *buffer, int flags);
static long readline (struct ebuffer *ebuf);
@@ -142,16 +140,16 @@ static void do_undefine (char *name, enum variable_origin origin,
struct ebuffer *ebuf);
static struct variable *do_define (char *name, enum variable_origin origin,
struct ebuffer *ebuf);
static int conditional_line (char *line, int len, const gmk_floc *flocp);
static int conditional_line (char *line, int len, const floc *flocp);
static void record_files (struct nameseq *filenames, const char *pattern,
const char *pattern_percent, char *depstr,
unsigned int cmds_started, char *commands,
unsigned int commands_idx, int two_colon,
char prefix, const gmk_floc *flocp);
char prefix, const floc *flocp);
static void record_target_var (struct nameseq *filenames, char *defn,
enum variable_origin origin,
struct vmodifiers *vmod,
const gmk_floc *flocp);
const floc *flocp);
static enum make_word_type get_next_mword (char *buffer, char *delim,
char **startp, unsigned int *length);
static void remove_comments (char *line);
@@ -167,7 +165,7 @@ static char *unescape_char (char *string, int c);
/* Read in all the makefiles and return a chain of targets to rebuild. */
struct dep *
struct goaldep *
read_all_makefiles (const char **makefiles)
{
unsigned int num_makefiles = 0;
@@ -217,17 +215,11 @@ read_all_makefiles (const char **makefiles)
if (makefiles != 0)
while (*makefiles != 0)
{
struct dep *tail = read_files;
struct dep *d;
struct goaldep *d = eval_makefile (*makefiles, 0);
if (! eval_makefile (*makefiles, 0))
if (errno)
perror_with_name ("", *makefiles);
/* Find the first element eval_makefile() added to read_files. */
d = read_files;
while (d->next != tail)
d = d->next;
/* Reuse the storage allocated for the read_file. */
*makefiles = dep_name (d);
++num_makefiles;
@@ -238,42 +230,47 @@ read_all_makefiles (const char **makefiles)
if (num_makefiles == 0)
{
static char *default_makefiles[] =
static const char *default_makefiles[] =
#ifdef VMS
/* all lower case since readdir() (the vms version) 'lowercasifies' */
{ "makefile.vms", "gnumakefile.", "makefile.", 0 };
/* TODO: Above is not always true, this needs more work */
{ "makefile.vms", "gnumakefile", "makefile", 0 };
#else
#ifdef _AMIGA
{ "GNUmakefile", "Makefile", "SMakefile", 0 };
#else /* !Amiga && !VMS */
#ifdef WINDOWS32
{ "GNUmakefile", "makefile", "Makefile", "makefile.mak", 0 };
#else /* !Amiga && !VMS && !WINDOWS32 */
{ "GNUmakefile", "makefile", "Makefile", 0 };
#endif /* !Amiga && !VMS && !WINDOWS32 */
#endif /* AMIGA */
#endif /* VMS */
register char **p = default_makefiles;
const char **p = default_makefiles;
while (*p != 0 && !file_exists_p (*p))
++p;
if (*p != 0)
{
if (! eval_makefile (*p, 0))
eval_makefile (*p, 0);
if (errno)
perror_with_name ("", *p);
}
else
{
/* No default makefile was found. Add the default makefiles to the
'read_files' chain so they will be updated if possible. */
struct dep *tail = read_files;
struct goaldep *tail = read_files;
/* Add them to the tail, after any MAKEFILES variable makefiles. */
while (tail != 0 && tail->next != 0)
tail = tail->next;
for (p = default_makefiles; *p != 0; ++p)
{
struct dep *d = alloc_dep ();
struct goaldep *d = alloc_goaldep ();
d->file = enter_file (strcache_add (*p));
d->dontcare = 1;
/* Tell update_goal_chain to bail out as soon as this file is
made, and main not to die if we can't make this file. */
d->changed = RM_DONTCARE;
d->flags = RM_DONTCARE;
if (tail == 0)
read_files = d;
else
@@ -307,26 +304,25 @@ static void
restore_conditionals (struct conditionals *saved)
{
/* Free any space allocated by conditional_line. */
if (conditionals->ignoring)
free (conditionals->ignoring);
if (conditionals->seen_else)
free (conditionals->seen_else);
free (conditionals->ignoring);
free (conditionals->seen_else);
/* Restore state. */
conditionals = saved;
}
static int
static struct goaldep *
eval_makefile (const char *filename, int flags)
{
struct dep *deps;
struct goaldep *deps;
struct ebuffer ebuf;
const gmk_floc *curfile;
const floc *curfile;
char *expanded = 0;
int makefile_errno;
ebuf.floc.filenm = filename; /* Use the original file name. */
ebuf.floc.lineno = 1;
ebuf.floc.offset = 0;
if (ISDB (DB_VERBOSE))
{
@@ -368,7 +364,10 @@ eval_makefile (const char *filename, int flags)
case ENFILE:
#endif
case ENOMEM:
fatal (reading_file, "%s", strerror (makefile_errno));
{
const char *err = strerror (makefile_errno);
OS (fatal, reading_file, "%s", err);
}
}
/* If the makefile wasn't found and it's either a makefile from
@@ -395,29 +394,26 @@ eval_makefile (const char *filename, int flags)
filename = strcache_add (filename);
/* Add FILENAME to the chain of read makefiles. */
deps = alloc_dep ();
deps = alloc_goaldep ();
deps->next = read_files;
read_files = deps;
deps->file = lookup_file (filename);
if (deps->file == 0)
deps->file = enter_file (filename);
filename = deps->file->name;
deps->changed = flags;
if (flags & RM_DONTCARE)
deps->dontcare = 1;
deps->flags = flags;
if (expanded)
free (expanded);
free (expanded);
/* If the makefile can't be found at all, give up entirely. */
if (ebuf.fp == 0)
{
/* If we did some searching, errno has the error from the last
attempt, rather from FILENAME itself. Restore it in case the
attempt, rather from FILENAME itself. Store it in case the
caller wants to use it in a message. */
errno = makefile_errno;
return 0;
return deps;
}
/* Set close-on-exec to avoid leaking the makefile to children, such as
@@ -447,16 +443,17 @@ eval_makefile (const char *filename, int flags)
free (ebuf.bufstart);
alloca (0);
return 1;
errno = 0;
return deps;
}
void
eval_buffer (char *buffer, const gmk_floc *floc)
eval_buffer (char *buffer, const floc *flocp)
{
struct ebuffer ebuf;
struct conditionals *saved;
struct conditionals new;
const gmk_floc *curfile;
const floc *curfile;
/* Evaluate the buffer */
@@ -464,14 +461,15 @@ eval_buffer (char *buffer, const gmk_floc *floc)
ebuf.buffer = ebuf.bufnext = ebuf.bufstart = buffer;
ebuf.fp = NULL;
if (floc)
ebuf.floc = *floc;
if (flocp)
ebuf.floc = *flocp;
else if (reading_file)
ebuf.floc = *reading_file;
else
{
ebuf.floc.filenm = NULL;
ebuf.floc.lineno = 1;
ebuf.floc.offset = 0;
}
curfile = reading_file;
@@ -506,7 +504,7 @@ parse_var_assignment (const char *line, struct vmodifiers *vmod)
memset (vmod, '\0', sizeof (*vmod));
/* Find the start of the next token. If there isn't one we're done. */
line = next_token (line);
NEXT_TOKEN (line);
if (*line == '\0')
return (char *)line;
@@ -585,8 +583,8 @@ eval (struct ebuffer *ebuf, int set_default)
char prefix = cmd_prefix;
const char *pattern = 0;
const char *pattern_percent;
gmk_floc *fstart;
gmk_floc fi;
floc *fstart;
floc fi;
#define record_waiting_files() \
do \
@@ -594,6 +592,7 @@ eval (struct ebuffer *ebuf, int set_default)
if (filenames != 0) \
{ \
fi.lineno = tgts_started; \
fi.offset = 0; \
record_files (filenames, pattern, pattern_percent, depstr, \
cmds_started, commands, commands_idx, two_colon, \
prefix, &fi); \
@@ -704,8 +703,7 @@ eval (struct ebuffer *ebuf, int set_default)
if (collapsed_length < linelen+1)
{
collapsed_length = linelen+1;
if (collapsed)
free (collapsed);
free (collapsed);
/* Don't need xrealloc: we don't need to preserve the content. */
collapsed = xmalloc (collapsed_length);
}
@@ -716,8 +714,7 @@ eval (struct ebuffer *ebuf, int set_default)
/* Get rid if starting space (including formfeed, vtab, etc.) */
p = collapsed;
while (isspace ((unsigned char)*p))
++p;
NEXT_TOKEN (p);
/* See if this is a variable assignment. We need to do this early, to
allow variables with names like 'ifdef', 'export', 'private', etc. */
@@ -727,9 +724,6 @@ eval (struct ebuffer *ebuf, int set_default)
struct variable *v;
enum variable_origin origin = vmod.override_v ? o_override : o_file;
/* Variable assignment ends the previous rule. */
record_waiting_files ();
/* If we're ignoring then we're done now. */
if (ignoring)
{
@@ -738,6 +732,9 @@ eval (struct ebuffer *ebuf, int set_default)
continue;
}
/* Variable assignment ends the previous rule. */
record_waiting_files ();
if (vmod.undefine_v)
{
do_undefine (p, origin, ebuf);
@@ -765,7 +762,7 @@ eval (struct ebuffer *ebuf, int set_default)
p2 = end_of_token (p);
wlen = p2 - p;
p2 = next_token (p2);
NEXT_TOKEN (p2);
/* If we're in an ignored define, skip this line (but maybe get out). */
if (in_ignored_define)
@@ -783,7 +780,7 @@ eval (struct ebuffer *ebuf, int set_default)
if (i != -2)
{
if (i == -1)
fatal (fstart, _("invalid syntax in conditional"));
O (fatal, fstart, _("invalid syntax in conditional"));
ignoring = i;
continue;
@@ -853,8 +850,7 @@ eval (struct ebuffer *ebuf, int set_default)
/* No pattern means remove all previous selective VPATH's. */
vpat = 0;
construct_vpath_list (vpat, p);
if (vpat != 0)
free (vpat);
free (vpat);
continue;
}
@@ -901,18 +897,20 @@ eval (struct ebuffer *ebuf, int set_default)
while (files != 0)
{
struct nameseq *next = files->next;
const char *name = files->name;
int r;
int flags = (RM_INCLUDED | RM_NO_TILDE
| (noerror ? RM_DONTCARE : 0)
| (set_default ? 0 : RM_NO_DEFAULT_GOAL));
struct goaldep *d = eval_makefile (files->name, flags);
if (errno)
{
d->error = (unsigned short)errno;
d->floc = *fstart;
}
free_ns (files);
files = next;
r = eval_makefile (name,
(RM_INCLUDED | RM_NO_TILDE
| (noerror ? RM_DONTCARE : 0)
| (set_default ? 0 : RM_NO_DEFAULT_GOAL)));
if (!r && !noerror)
error (fstart, "%s: %s", name, strerror (errno));
}
/* Restore conditional state. */
@@ -947,20 +945,28 @@ eval (struct ebuffer *ebuf, int set_default)
PARSEFS_NOAR);
free (p);
/* Load each file and add it to the list "to be rebuilt". */
/* Load each file. */
while (files != 0)
{
struct nameseq *next = files->next;
const char *name = files->name;
struct dep *deps;
struct goaldep *deps;
int r;
/* Load the file. 0 means failure. */
r = load_file (&ebuf->floc, &name, noerror);
if (! r && ! noerror)
OS (fatal, &ebuf->floc, _("%s: failed to load"), name);
free_ns (files);
files = next;
if (! load_file (&ebuf->floc, &name, noerror) && ! noerror)
fatal (&ebuf->floc, _("%s: failed to load"), name);
/* Return of -1 means a special load: don't rebuild it. */
if (r == -1)
continue;
deps = alloc_dep ();
/* It succeeded, so add it to the list "to be rebuilt". */
deps = alloc_goaldep ();
deps->next = read_files;
read_files = deps;
deps->file = lookup_file (name);
@@ -976,7 +982,7 @@ eval (struct ebuffer *ebuf, int set_default)
was no preceding target, and the line might have been usable as a
variable definition. But now we know it is definitely lossage. */
if (line[0] == cmd_prefix)
fatal (fstart, _("recipe commences before first target"));
O (fatal, fstart, _("recipe commences before first target"));
/* This line describes some target files. This is complicated by
the existence of target-specific variables, because we can't
@@ -1025,7 +1031,7 @@ eval (struct ebuffer *ebuf, int set_default)
{
case w_eol:
if (cmdleft != 0)
fatal (fstart, _("missing rule before recipe"));
O (fatal, fstart, _("missing rule before recipe"));
/* This line contained something but turned out to be nothing
but whitespace (a comment?). */
continue;
@@ -1065,7 +1071,7 @@ eval (struct ebuffer *ebuf, int set_default)
here, but merely copy, since now you're beyond a ";"
and into a command script. However, the old parser
expanded the whole line, so we continue that for
backwards-compatiblity. Also, it wouldn't be
backwards-compatibility. Also, it wouldn't be
entirely consistent, since we do an unconditional
expand below once we know we don't have a
target-specific variable. */
@@ -1109,13 +1115,15 @@ eval (struct ebuffer *ebuf, int set_default)
it. If so, we can't parse this line so punt. */
if (wtype == w_eol)
{
if (*p2 != '\0')
/* There's no need to be ivory-tower about this: check for
one of the most common bugs found in makefiles... */
fatal (fstart, _("missing separator%s"),
(cmd_prefix == '\t' && !strneq (line, " ", 8))
? "" : _(" (did you mean TAB instead of 8 spaces?)"));
continue;
if (*p2 == '\0')
continue;
/* There's no need to be ivory-tower about this: check for
one of the most common bugs found in makefiles... */
if (cmd_prefix == '\t' && strneq (line, " ", 8))
O (fatal, fstart, _("missing separator (did you mean TAB instead of 8 spaces?)"));
else
O (fatal, fstart, _("missing separator"));
}
/* Make the colon the end-of-string so we know where to stop
@@ -1226,8 +1234,7 @@ eval (struct ebuffer *ebuf, int set_default)
The rule is that it's only a target, if there are TWO :'s
OR a space around the :.
*/
if (p && !(isspace ((unsigned char)p[1]) || !p[1]
|| isspace ((unsigned char)p[-1])))
if (p && !(ISSPACE (p[1]) || !p[1] || ISSPACE (p[-1])))
p = 0;
#endif
#ifdef HAVE_DOS_PATHS
@@ -1252,13 +1259,13 @@ eval (struct ebuffer *ebuf, int set_default)
PARSEFS_NOGLOB);
++p2;
if (target == 0)
fatal (fstart, _("missing target pattern"));
O (fatal, fstart, _("missing target pattern"));
else if (target->next != 0)
fatal (fstart, _("multiple target patterns"));
O (fatal, fstart, _("multiple target patterns"));
pattern_percent = find_percent_cached (&target->name);
pattern = target->name;
if (pattern_percent == 0)
fatal (fstart, _("target pattern contains no '%%'"));
O (fatal, fstart, _("target pattern contains no '%%'"));
free_ns (target);
}
else
@@ -1380,13 +1387,12 @@ eval (struct ebuffer *ebuf, int set_default)
#undef word1eq
if (conditionals->if_cmds)
fatal (fstart, _("missing 'endif'"));
O (fatal, fstart, _("missing 'endif'"));
/* At eof, record the last rule. */
record_waiting_files ();
if (collapsed)
free (collapsed);
free (collapsed);
free (commands);
}
@@ -1419,9 +1425,9 @@ do_undefine (char *name, enum variable_origin origin, struct ebuffer *ebuf)
var = allocated_variable_expand (name);
name = next_token (var);
if (*name == '\0')
fatal (&ebuf->floc, _("empty variable name"));
O (fatal, &ebuf->floc, _("empty variable name"));
p = name + strlen (name) - 1;
while (p > name && isblank ((unsigned char)*p))
while (p > name && ISBLANK (*p))
--p;
p[1] = '\0';
@@ -1438,7 +1444,7 @@ do_define (char *name, enum variable_origin origin, struct ebuffer *ebuf)
{
struct variable *v;
struct variable var;
gmk_floc defstart;
floc defstart;
int nlevels = 1;
unsigned int length = 100;
char *definition = xmalloc (length);
@@ -1454,7 +1460,7 @@ do_define (char *name, enum variable_origin origin, struct ebuffer *ebuf)
else
{
if (var.value[0] != '\0')
error (&defstart, _("extraneous text after 'define' directive"));
O (error, &defstart, _("extraneous text after 'define' directive"));
/* Chop the string before the assignment token to get the name. */
var.name[var.length] = '\0';
@@ -1464,9 +1470,9 @@ do_define (char *name, enum variable_origin origin, struct ebuffer *ebuf)
n = allocated_variable_expand (name);
name = next_token (n);
if (name[0] == '\0')
fatal (&defstart, _("empty variable name"));
O (fatal, &defstart, _("empty variable name"));
p = name + strlen (name) - 1;
while (p > name && isblank ((unsigned char)*p))
while (p > name && ISBLANK (*p))
--p;
p[1] = '\0';
@@ -1479,7 +1485,7 @@ do_define (char *name, enum variable_origin origin, struct ebuffer *ebuf)
/* If there is nothing left to be eval'd, there's no 'endef'!! */
if (nlines < 0)
fatal (&defstart, _("missing 'endef', unterminated 'define'"));
O (fatal, &defstart, _("missing 'endef', unterminated 'define'"));
ebuf->floc.lineno += nlines;
line = ebuf->buffer;
@@ -1494,20 +1500,20 @@ do_define (char *name, enum variable_origin origin, struct ebuffer *ebuf)
len = strlen (p);
/* If this is another 'define', increment the level count. */
if ((len == 6 || (len > 6 && isblank ((unsigned char)p[6])))
if ((len == 6 || (len > 6 && ISBLANK (p[6])))
&& strneq (p, "define", 6))
++nlevels;
/* If this is an 'endef', decrement the count. If it's now 0,
we've found the last one. */
else if ((len == 5 || (len > 5 && isblank ((unsigned char)p[5])))
else if ((len == 5 || (len > 5 && ISBLANK (p[5])))
&& strneq (p, "endef", 5))
{
p += 5;
remove_comments (p);
if (*(next_token (p)) != '\0')
error (&ebuf->floc,
_("extraneous text after 'endef' directive"));
O (error, &ebuf->floc,
_("extraneous text after 'endef' directive"));
if (--nlevels == 0)
break;
@@ -1554,9 +1560,9 @@ do_define (char *name, enum variable_origin origin, struct ebuffer *ebuf)
1 if following text should be ignored. */
static int
conditional_line (char *line, int len, const gmk_floc *flocp)
conditional_line (char *line, int len, const floc *flocp)
{
char *cmdname;
const char *cmdname;
enum { c_ifdef, c_ifndef, c_ifeq, c_ifneq, c_else, c_endif } cmdtype;
unsigned int i;
unsigned int o;
@@ -1576,18 +1582,20 @@ conditional_line (char *line, int len, const gmk_floc *flocp)
return -2;
/* Found one: skip past it and any whitespace after it. */
line = next_token (line + len);
line += len;
NEXT_TOKEN (line);
#define EXTRANEOUS() error (flocp, _("extraneous text after '%s' directive"), cmdname)
#define EXTRATEXT() OS (error, flocp, _("extraneous text after '%s' directive"), cmdname)
#define EXTRACMD() OS (fatal, flocp, _("extraneous '%s'"), cmdname)
/* An 'endif' cannot contain extra text, and reduces the if-depth by 1 */
if (cmdtype == c_endif)
{
if (*line != '\0')
EXTRANEOUS ();
EXTRATEXT ();
if (!conditionals->if_cmds)
fatal (flocp, _("extraneous '%s'"), cmdname);
EXTRACMD ();
--conditionals->if_cmds;
@@ -1601,12 +1609,12 @@ conditional_line (char *line, int len, const gmk_floc *flocp)
const char *p;
if (!conditionals->if_cmds)
fatal (flocp, _("extraneous '%s'"), cmdname);
EXTRACMD ();
o = conditionals->if_cmds - 1;
if (conditionals->seen_else[o])
fatal (flocp, _("only one 'else' per conditional"));
O (fatal, flocp, _("only one 'else' per conditional"));
/* Change the state of ignorance. */
switch (conditionals->ignoring[o])
@@ -1639,7 +1647,7 @@ conditional_line (char *line, int len, const gmk_floc *flocp)
/* If it's 'else' or 'endif' or an illegal conditional, fail. */
if (word1eq ("else") || word1eq ("endif")
|| conditional_line (line, len, flocp) < 0)
EXTRANEOUS ();
EXTRATEXT ();
else
{
/* conditional_line() created a new level of conditional.
@@ -1696,7 +1704,7 @@ conditional_line (char *line, int len, const gmk_floc *flocp)
/* Make sure there's only one variable name to test. */
p = end_of_token (var);
i = p - var;
p = next_token (p);
NEXT_TOKEN (p);
if (*p != '\0')
return -1;
@@ -1742,7 +1750,7 @@ conditional_line (char *line, int len, const gmk_floc *flocp)
{
/* Strip blanks after the first string. */
char *p = line++;
while (isblank ((unsigned char)p[-1]))
while (ISBLANK (p[-1]))
--p;
*p = '\0';
}
@@ -1758,7 +1766,7 @@ conditional_line (char *line, int len, const gmk_floc *flocp)
if (termin != ',')
/* Find the start of the second string. */
line = next_token (line);
NEXT_TOKEN (line);
termin = termin == ',' ? ')' : *line;
if (termin != ')' && termin != '"' && termin != '\'')
@@ -1793,10 +1801,10 @@ conditional_line (char *line, int len, const gmk_floc *flocp)
if (*line == '\0')
return -1;
*line = '\0';
line = next_token (++line);
*(line++) = '\0';
NEXT_TOKEN (line);
if (*line != '\0')
EXTRANEOUS ();
EXTRATEXT ();
s2 = variable_expand (s2);
conditionals->ignoring[o] = (streq (s1, s2) == (cmdtype == c_ifneq));
@@ -1823,7 +1831,7 @@ conditional_line (char *line, int len, const gmk_floc *flocp)
static void
record_target_var (struct nameseq *filenames, char *defn,
enum variable_origin origin, struct vmodifiers *vmod,
const gmk_floc *flocp)
const floc *flocp)
{
struct nameseq *nextf;
struct variable_set_list *global;
@@ -1881,7 +1889,7 @@ record_target_var (struct nameseq *filenames, char *defn,
current_variable_set_list = f->variables;
v = try_variable_definition (flocp, defn, origin, 1);
if (!v)
fatal (flocp, _("Malformed target-specific variable definition"));
O (fatal, flocp, _("Malformed target-specific variable definition"));
current_variable_set_list = global;
}
@@ -1901,8 +1909,7 @@ record_target_var (struct nameseq *filenames, char *defn,
if (gv && v != gv
&& (gv->origin == o_env_override || gv->origin == o_command))
{
if (v->value != 0)
free (v->value);
free (v->value);
v->value = xstrdup (gv->value);
v->origin = gv->origin;
v->recursive = gv->recursive;
@@ -1928,7 +1935,7 @@ record_files (struct nameseq *filenames, const char *pattern,
const char *pattern_percent, char *depstr,
unsigned int cmds_started, char *commands,
unsigned int commands_idx, int two_colon,
char prefix, const gmk_floc *flocp)
char prefix, const floc *flocp)
{
struct commands *cmds;
struct dep *deps;
@@ -1940,7 +1947,7 @@ record_files (struct nameseq *filenames, const char *pattern,
at this time, since they won't get snapped and we'll get core dumps.
See Savannah bug # 12124. */
if (snapped_deps)
fatal (flocp, _("prerequisites cannot be defined in recipes"));
O (fatal, flocp, _("prerequisites cannot be defined in recipes"));
/* Determine if this is a pattern rule or not. */
name = filenames->name;
@@ -1952,6 +1959,7 @@ record_files (struct nameseq *filenames, const char *pattern,
cmds = xmalloc (sizeof (struct commands));
cmds->fileinfo.filenm = flocp->filenm;
cmds->fileinfo.lineno = cmds_started;
cmds->fileinfo.offset = 0;
cmds->commands = xstrndup (commands, commands_idx);
cmds->command_lines = 0;
cmds->recipe_prefix = prefix;
@@ -1998,7 +2006,7 @@ record_files (struct nameseq *filenames, const char *pattern,
unsigned int c;
if (pattern != 0)
fatal (flocp, _("mixed implicit and static pattern rules"));
O (fatal, flocp, _("mixed implicit and static pattern rules"));
/* Count the targets to create an array of target names.
We already have the first one. */
@@ -2021,7 +2029,7 @@ record_files (struct nameseq *filenames, const char *pattern,
implicit_percent = find_percent_cached (&name);
if (implicit_percent == 0)
fatal (flocp, _("mixed implicit and normal rules"));
O (fatal, flocp, _("mixed implicit and normal rules"));
targets[c] = name;
target_pats[c] = implicit_percent;
@@ -2073,7 +2081,8 @@ record_files (struct nameseq *filenames, const char *pattern,
'targets: target%pattern: prereq%pattern; recipe',
make sure the pattern matches this target name. */
if (pattern && !pattern_matches (pattern, pattern_percent, name))
error (flocp, _("target '%s' doesn't match the target pattern"), name);
OS (error, flocp,
_("target '%s' doesn't match the target pattern"), name);
else if (deps)
/* If there are multiple targets, copy the chain DEPS for all but the
last one. It is not safe for the same deps to go in more than one
@@ -2087,25 +2096,26 @@ record_files (struct nameseq *filenames, const char *pattern,
if any. */
f = enter_file (strcache_add (name));
if (f->double_colon)
fatal (flocp,
_("target file '%s' has both : and :: entries"), f->name);
OS (fatal, flocp,
_("target file '%s' has both : and :: entries"), f->name);
/* If CMDS == F->CMDS, this target was listed in this rule
more than once. Just give a warning since this is harmless. */
if (cmds != 0 && cmds == f->cmds)
error (flocp,
_("target '%s' given more than once in the same rule"),
f->name);
OS (error, flocp,
_("target '%s' given more than once in the same rule"),
f->name);
/* Check for two single-colon entries both with commands.
Check is_target so that we don't lose on files such as .c.o
whose commands were preinitialized. */
else if (cmds != 0 && f->cmds != 0 && f->is_target)
{
error (&cmds->fileinfo,
size_t l = strlen (f->name);
error (&cmds->fileinfo, l,
_("warning: overriding recipe for target '%s'"),
f->name);
error (&f->cmds->fileinfo,
error (&f->cmds->fileinfo, l,
_("warning: ignoring old recipe for target '%s'"),
f->name);
}
@@ -2132,8 +2142,8 @@ record_files (struct nameseq *filenames, const char *pattern,
/* Check for both : and :: rules. Check is_target so we don't lose
on default suffix rules or makefiles. */
if (f != 0 && f->is_target && !f->double_colon)
fatal (flocp,
_("target file '%s' has both : and :: entries"), f->name);
OS (fatal, flocp,
_("target file '%s' has both : and :: entries"), f->name);
f = enter_file (strcache_add (name));
/* If there was an existing entry and it was a double-colon entry,
@@ -2209,7 +2219,8 @@ record_files (struct nameseq *filenames, const char *pattern,
/* Reduce escaped percents. If there are any unescaped it's an error */
name = filenames->name;
if (find_percent_cached (&name))
fatal (flocp, _("mixed implicit and normal rules"));
O (error, flocp,
_("*** mixed implicit and normal rules: deprecated syntax"));
}
}
@@ -2244,6 +2255,10 @@ find_char_unquote (char *string, int map)
{
char openparen = p[1];
/* Check if '$' is the last character in the string. */
if (openparen == '\0')
break;
p += 2;
/* Skip the contents of a non-quoted, multi-char variable ref. */
@@ -2323,16 +2338,21 @@ unescape_char (char *string, int c)
if (*e != c || l%2 == 0)
{
/* It's not; just take it all without unescaping. */
memcpy (p, s, l);
memmove (p, s, l);
p += l;
// If we hit the end of the string, we're done
if (*e == '\0')
break;
}
else if (l > 1)
{
/* It is, and there's >1 backslash. Take half of them. */
l /= 2;
memcpy (p, s, l);
memmove (p, s, l);
p += l;
}
s = e;
}
@@ -2440,7 +2460,7 @@ find_percent_cached (const char **string)
Since we aren't really reading from a file, don't bother with linenumbers.
*/
static unsigned long
static long
readstring (struct ebuffer *ebuf)
{
char *eol;
@@ -2518,8 +2538,8 @@ readline (struct ebuffer *ebuf)
lossage strikes again! (xmkmf puts NULs in its makefiles.)
There is nothing really to be done; we synthesize a newline so
the following line doesn't appear to be part of this line. */
error (&ebuf->floc,
_("warning: NUL character seen; rest of line ignored"));
O (error, &ebuf->floc,
_("warning: NUL character seen; rest of line ignored"));
p[0] = '\n';
len = 1;
}
@@ -2614,7 +2634,7 @@ get_next_mword (char *buffer, char *delim, char **startp, unsigned int *length)
char c;
/* Skip any leading whitespace. */
while (isblank ((unsigned char)*p))
while (ISBLANK (*p))
++p;
beg = p;
@@ -2712,6 +2732,8 @@ get_next_mword (char *buffer, char *delim, char **startp, unsigned int *length)
c = *(p++);
if (c == '$')
break;
if (c == '\0')
goto done_word;
/* This is a variable reference, so note that it's expandable.
Then read it to the matching close paren. */
@@ -2834,8 +2856,7 @@ construct_include_path (const char **arg_dirs)
dirs[idx++] = strcache_add_len (dir, len);
}
if (expanded)
free (expanded);
free (expanded);
}
/* Now add the standard default dirs at the end. */
@@ -2897,7 +2918,6 @@ tilde_expand (const char *name)
#ifndef VMS
if (name[1] == '/' || name[1] == '\0')
{
extern char *getenv ();
char *home_dir;
int is_variable;
@@ -2920,7 +2940,6 @@ tilde_expand (const char *name)
# if !defined(_AMIGA) && !defined(WINDOWS32)
if (home_dir == 0 || home_dir[0] == '\0')
{
extern char *getlogin ();
char *logname = getlogin ();
home_dir = 0;
if (logname != 0)
@@ -2989,8 +3008,6 @@ void *
parse_file_seq (char **stringp, unsigned int size, int stopmap,
const char *prefix, int flags)
{
extern void dir_setup_glob (glob_t *glob);
/* tmp points to tmpbuf after the prefix, if any.
tp is the end of the buffer. */
static char *tmpbuf = NULL;
@@ -3048,7 +3065,7 @@ parse_file_seq (char **stringp, unsigned int size, int stopmap,
int i;
/* Skip whitespace; at the end of the string or STOPCHAR we're done. */
p = next_token (p);
NEXT_TOKEN (p);
if (STOP_SET (*p, stopmap))
break;
@@ -3063,8 +3080,7 @@ parse_file_seq (char **stringp, unsigned int size, int stopmap,
#endif
#ifdef _AMIGA
if (p && STOP_SET (*p, stopmap & MAP_COLON)
&& !(isspace ((unsigned char)p[1]) || !p[1]
|| isspace ((unsigned char)p[-1])))
&& !(ISSPACE (p[1]) || !p[1] || ISSPACE (p[-1])))
p = find_char_unquote (p+1, stopmap|MAP_VMSCOMMA|MAP_BLANK);
#endif
#ifdef HAVE_DOS_PATHS
@@ -3073,7 +3089,7 @@ parse_file_seq (char **stringp, unsigned int size, int stopmap,
Note that tokens separated by spaces should be treated as separate
tokens since make doesn't allow path names with spaces */
if (stopmap | MAP_COLON)
while (p != 0 && !isspace ((unsigned char)*p) &&
while (p != 0 && !ISSPACE (*p) &&
(p[1] == '\\' || p[1] == '/') && isalpha ((unsigned char)p[-1]))
p = find_char_unquote (p + 1, stopmap|MAP_VMSCOMMA|MAP_BLANK);
#endif
@@ -3083,12 +3099,15 @@ parse_file_seq (char **stringp, unsigned int size, int stopmap,
/* Strip leading "this directory" references. */
if (NONE_SET (flags, PARSEFS_NOSTRIP))
#ifdef VMS
/* Skip leading '[]'s. */
while (p - s > 2 && s[0] == '[' && s[1] == ']')
#else
/* Skip leading '[]'s. should only be one set or bug somwhere else */
if (p - s > 2 && s[0] == '[' && s[1] == ']')
s += 2;
/* Skip leading '<>'s. should only be one set or bug somwhere else */
if (p - s > 2 && s[0] == '<' && s[1] == '>')
s += 2;
#endif
/* Skip leading './'s. */
while (p - s > 2 && s[0] == '.' && s[1] == '/')
#endif
{
/* Skip "./" and all following slashes. */
s += 2;
@@ -3102,9 +3121,7 @@ parse_file_seq (char **stringp, unsigned int size, int stopmap,
if (s == p)
{
/* The name was stripped to empty ("./"). */
#if defined(VMS)
continue;
#elif defined(_AMIGA)
#if defined(_AMIGA)
/* PDS-- This cannot be right!! */
tp[0] = '\0';
nlen = 0;
@@ -3167,7 +3184,7 @@ parse_file_seq (char **stringp, unsigned int size, int stopmap,
do
{
const char *o = e;
e = next_token (e);
NEXT_TOKEN (e);
/* Find the end of this word. We don't want to unquote and
we don't care about quoting since we're looking for the
last char in the word. */
@@ -3261,7 +3278,7 @@ parse_file_seq (char **stringp, unsigned int size, int stopmap,
switch (glob (name, GLOB_NOSORT|GLOB_ALTDIRFUNC, NULL, &gl))
{
case GLOB_NOSPACE:
fatal (NILF, _("virtual memory exhausted"));
OUT_OF_MEM();
case 0:
/* Success. */
@@ -3327,12 +3344,10 @@ parse_file_seq (char **stringp, unsigned int size, int stopmap,
globfree (&gl);
#ifndef NO_ARCHIVES
if (arname)
free (arname);
free (arname);
#endif
if (tildep)
free (tildep);
free (tildep);
}
*stringp = p;

View File

@@ -1,391 +0,0 @@
This is the VMS version of GNU Make, updated by Hartmut Becker
Changes are based on GNU make 3.82.
This version was built and tested on OpenVMS V7.3 (VAX), V7.3-2 (Alpha) and
V8.3-1H1 (I64).
Build instructions
Make a 1st version
$ @makefile.com ! ignore any compiler and/or linker warning
$ rena make.exe 1st-make.exe
Use the 1st version to generate a 2nd version
$ mc sys$disk:[]1st-make clean
$ mc sys$disk:[]1st-make
Verify your 2nd version
$ rena make.exe 2nd-make.exe
$ mc sys$disk:[]2nd-make clean
$ mc sys$disk:[]2nd-make
Changes (3.81.90)
Michael Gehre (at VISTEC-SEMI dot COM) supplied a fix for a problem with
timestamps of object modules in OLBs. The timestamps were not correctly
adjusted to GMT based time, if the local VMS time was using a daylight saving
algorithm and if daylight saving was switched off.
John Eisenbraun (at HP dot COM) supplied fixes and and an enhancement to append
output redirection in action lines.
Rework of ctrl+c and ctrl+y handling.
Fix a problem with cached strings, which showed on case-insensitive file
systems.
Build fixes for const-ified code in VMS specific sources.
Build notes:
- Try to avoid HP C V7.2-001, which has an incompatible change
how __STDC__ is defined. This results at least in compile time warnings.
- On V8.3-1H1, if you press Ctrl+C you may see a traceback, starting with
%SYSTEM-F-CONTROLC, operation completed under CTRL/C
%TRACE-F-TRACEBACK, symbolic stack dump follows
image module routine line rel PC abs PC
DECC$SHR C$SIGNAL gsignal 27991 0000000000001180
FFFFFFFF84AB2DA0
DECC$SHR C$SIGNAL raise 28048 0000000000001280
FFFFFFFF84AB2EA0
DECC$SHR C$SIGPENDING decc$$deliver_signals
12475 0000000000000890
FFFFFFFF84C13690
...
This looks like an incompatibility to the Alpha and VAX behavior, so it looks
like a problem in I64 VMS version(s).
- There is no clean build on VAX. In the environment I tested, I had to use GNU
make's alloca which produced a couple of compile time warnings. It seems too
much effort to work on a clean build on VAX.
A note on appending the redirected output. With this change, a simple mechanism
is implemented to make ">>" work in action lines. In VMS there is no simple
feature like ">>" to have DCL command or program output redirected and appended
to a file. GNU make for VMS already implements the redirection of output. If
such a redirection is detected, an ">" on the action line, GNU make creates a
DCL command procedure to execute the action and to redirect its output. Based
on that, now ">>" is also recognized and a similar but different command
procedure is created to implement the append. The main idea here is to create a
temporary file which collects the output and which is appended to the wanted
output file. Then the temporary file is deleted. This is all done in the
command procedure to keep changes in make small and simple. This obviously has
some limitations but it seems good enough compared with the current ">"
implementation. (And in my opinion, redirection is not really what GNU make has
to do.) With this approach, it may happen that the temporary file is not yet
appended and is left in SYS$SCRATCH. The temporary file names look like
"CMDxxxxx.". Any time the created 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 as well. Its name is
CMDxxxxx.COM.
Change in the Ctrl+Y handling
Ctrl+Y was: The CtrlY handler called $forcex for the current child.
Ctrl+Y changed: The CtrlY handler uses $delprc to delete all children. This way
also actions with DCL commands will be stopped. As before Ctrl+Y then sends
SIGQUIT to itself, which is handled in common code.
Change in deleteing temporary command files
Temporary command files were deleted in the main line, after returning from the
vms child termination handler. If Ctrl+C was pressed, the handler is called but
did not return to main line.
Now, temporary command files are deleted in the vms child termination
handler. That deletes the them even if a Ctrl+C was pressed.
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.
Changes (3.80)
. In default.c define variable ARCH as IA64 for VMS on Itanium systems.
. In makefile.vms avoid name collision for glob and globfree.
In newer version of the VMS CRTL there are glob and globfree implemented.
Compiling and linking may result in
%ILINK-W-MULDEFLNKG, symbol DECC$GLOBFREE has subsequent linkage definition
in module DECC$SHR file SYS$COMMON:[SYSLIB]DECC$SHR.EXE;1
%ILINK-W-MULDEF, symbol DECC$GLOBFREE multiply defined
in module DECC$SHR file SYS$COMMON:[SYSLIB]DECC$SHR.EXE;1
linker messages (and similar for DECC$GLOB). The messages just say, that
globfree is a known CRTL whose name was mapped by the compiler to
DECC$GLOBFREE. This is done in glob.c as well, so this name is defined
twice. One possible solution is to use the VMS versions of glob and
globfree. However, then the build environment needs to figure out if
there is a new CRTL supporting these or not. This adds complexity. Even
more, these functions return VMS file specifications, which is not
expected by the other make sources. There is a switch at run time (a VMS
logical DECC$GLOB_UNIX_STYLE), which can be set to get Unix style
names. This may conflict with other software. The recommended solution
for this is to set this switch just prior to calling main: in an
initialization routine. This adds more complexity and more VMS specific
code. It is easier to tell the compiler NOT to map the routine names
with a simple change in makefile.vms.
Some notes on case sensitive names in rules and on the disk. In the VMS
template for CONFIG.H case sensitive rules can be enabled with defining
WANT_CASE_SENSITIVE_TARGETS. For recent version of VMS there is a case
sensitive file system: ODS5. To make use of that, additionally un-defining
the HAVE_CASE_INSENSITIVE_FS is required. As these are C macros, different
versions of make need to be built to have any case sensitivity for VMS
working. Unfortunately, for ODS5 disks that's not all.
- Usually DCL upcases command line tokens (except strings) and usually the
file system is case blind (similar to how Windows systems work)
$ set proc/parse=extended/case=sensitive
preserves lower and UPPER on the command line and (for this process and all
sub-processes) enables case sensitivity in the file system
- Usually the CRTL tries to reverse what DCL did with command line tokens, it
lowercases all tokens (except strings)
$ define DECC$ARGV_PARSE_STYLE enable
passes (the now preserved) lower and UPPER from the command line to main()
- Usually the CRTL upcases the arguments to open() and friends
$ define DECC$EFS_CASE_PRESERVE enable
preserves the names as is.
It is important to know that not all VMS tools are ready for case sensitivity.
With this setup some tools may not work as expected. The setup should not
blindly be applied for all users in default login procedures.
Example? The poor coding gives a compiler message, showing that there are
different files:
$ dir
Directory ODS5DISK[HB]
A.c;1 B.c;1 c.c;1 X.c;1
x.c;1
Total of 5 files.
$ ods5make x.obj
cc /obj=x.obj x.c
foo(){lowercase_x();}
......^
%CC-I-IMPLICITFUNC, In this statement, the identifier "lowercase_x" is implicitly declared as a function.
at line number 1 in file ODS5DISK[HB]x.c;1
$ mc SYS$SYSDEVICE:[HARTMUT.MAKE_3_80P]ods5make X.obj
cc /obj=X.obj X.c
foo() {UPPERCASE_X();}
.......^
%CC-I-IMPLICITFUNC, In this statement, the identifier "UPPERCASE_X" is implicitly declared as a function.
at line number 1 in file ODS5DISK[HB]X.c;1
$ dir
Directory ODS5DISK[HB]
A.c;1 B.c;1 c.c;1 X.c;1
x.c;1 X.obj;1 x.obj;1
Total of 7 files.
$
This is the VMS port of GNU Make done by Hartmut.Becker@compaq.com.
It is based on the specific version 3.77k and on 3.78.1. 3.77k was done
by Klaus Kämpf <kkaempf@rmi.de>, the code was based on the VMS port of
GNU Make 3.60 by Mike Moretti.
It was ported on OpenVMS/Alpha V7.1, DECC V5.7-006. It was re-build and
tested on OpenVMS/Alpha V7.2, OpenVMS/VAX 7.1 and 5.5-2. Different
versions of DECC were used. VAXC was tried: it fails; but it doesn't
seem worth to get it working. There are still some PTRMISMATCH warnings
during the compile. Although perl is working on VMS the test scripts
don't work. The function $shell is still missing.
There is a known bug in some of the VMS CRTLs. It is in the shipped
versions of VMS V7.2 and V7.2-1 and in the currently (October 1999)
available ECOs for VMS V7.1 and newer versions. It is fixed in versions
shipped with newer VMS versions and all ECO kits after October 1999. It
only shows up during the daylight saving time period (DST): stat()
returns a modification time 1 hour ahead. This results in GNU make
warning messages. For a just created source you will see:
$ gmake x.exe
gmake.exe;1: *** Warning: File 'x.c' has modification time in the future (940582863 > 940579269)
cc /obj=x.obj x.c
link x.obj /exe=x.exe
gmake.exe;1: *** Warning: Clock skew detected. Your build may be incomplete.
New in 3.78.1:
Fix a problem with automatically remaking makefiles. GNU make uses an
execve to restart itself after a successful remake of the makefile. On
UNIX systems execve replaces the running program with a new one and
resets all signal handling to the default. On VMS execve creates a child
process, signal and exit handlers of the parent are still active, and,
unfortunately, corrupt the exit code from the child. Fix in job.c:
ignore SIGCHLD.
Added some switches to reflect latest features of DECC. Modifications in
makefile.vms.
Set some definitions to reflect latest features of DECC. Modifications in
config.h-vms (which is copied to config.h).
Added extern strcmpi declaration to avoid 'implicitly declared' messages.
Modification in make.h.
Default rule for C++, conditionals for gcc (GCC_IS_NATIVE) or DEC/Digital/
Compaq c/c++ compilers. Modifications in default.c.
Usage of opendir() and friends, suppress file version. Modifications in dir.c.
Added VMS specific code to handle ctrl+c and ctrl+y to abort make.
Modifications in job.c.
Added support to have case sensitive targets and dependencies but to
still use case blind file names. This is especially useful for Java
makefiles on VMS:
.SUFFIXES :
.SUFFIXES : .class .java
.java.class :
javac "$<
HelloWorld.class : HelloWorld.java
A new macro WANT_CASE_SENSITIVE_TARGETS in config.h-vms was introduced.
It needs to be enabled to get this feature; default is disabled. The
macro HAVE_CASE_INSENSITIVE_FS must not be touched: it is still enabled.
Modifications in file.c and config.h-vms.
Bootstrap make to start building make is still makefile.com, but make
needs to be re-made with a make to make a correct version: ignore all
possible warnings, delete all objects, rename make.exe to a different
name and run it.
Made some minor modifications to the bootstrap build makefile.com.
This is the VMS port of GNU Make.
It is based on the VMS port of GNU Make 3.60 by Mike Moretti.
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
about other vms software and forthcoming updates to gnu make.
New for 3.77:
/bin/sh style I/O redirection is supported. You can now write lines like
mcr sys$disk:[]program.exe < input.txt > output.txt &> error.txt
Makefile variables are looked up in the current environment. You can set
symbols or logicals in DCL and evaluate them in the Makefile via
$(<name-of-symbol-or-logical>). Variables defined in the Makefile
override VMS symbols/logicals !
Functions for file names are working now. See the GNU Make manual for
$(dir ...) and $(wildcard ...). Unix-style and VMS-style names are
supported as arguments.
The default rules are set up for GNU C. Building an executable from a
single source file is as easy as 'make file.exe'.
The variable $(ARCH) is predefined as ALPHA or VAX resp. Makefiles for
different VMS systems can now be written by checking $(ARCH) as in
ifeq ($(ARCH),ALPHA)
$(ECHO) "On the Alpha"
else
$(ECHO) "On the VAX"
endif
Command lines of excessive length are correctly broken and written to a
batch file in sys$scratch for later execution. There's no limit to the
lengths of commands (and no need for .opt files :-) any more.
Empty commands are handled correctly and don't end in a new DCL process.
New for 3.76:
John W. Eaton has updated the VMS port to support libraries and VPATH.
To build Make, simply type @makefile. This should compile all the
necessary files and link Make. There is also a file called
makefile.vms. If you already have GNU Make built you can just use
Make with this makefile to rebuild.
Here are some notes about GNU Make for VMS:
The cd command is supported if it's called as $(CD). This invokes
the 'builtin_cd' command which changes the directory.
Calling 'set def' doesn't do the trick, since a sub-shell is
spawned for this command, the directory is changed *in this sub-shell*
and the sub-shell ends.
Libraries are not supported. They were in GNU Make 3.60 but somehow I
didn't care porting the code. If there is enough interest, I'll do it at
some later time.
The variable $^ separates files with commas instead of spaces (It's the
natural thing to do for VMS).
See defaults.c for VMS default suffixes and my definitions for default
rules and variables.
The shell function is not implemented yet.
Load average routines haven't been implemented for VMS yet.
The default include directory for including other makefiles is
SYS$SYSROOT:[SYSLIB] (I don't remember why I didn't just use
SYS$LIBRARY: instead; maybe it wouldn't work that way).
The default makefiles make looks for are: makefile.vms, gnumakefile,
makefile., and gnumakefile. .
The stat() function and handling of time stamps in VMS is broken, so I
replaced it with a hack in vmsfunctions.c. I will provide a full rewrite
somewhere in the future. Be warned, the time resolution inside make is
less than what vms provides. This might be a problem on the faster Alphas.
You can use a : in a filename only if you precede it with a backslash ('\').
E.g.- hobbes\:[bogas.files]
Make ignores success, informational, or warning errors (-S-, -I-, or
-W-). But it will stop on -E- and -F- errors. (unless you do something
to override this in your makefile, or whatever).
Remote stuff isn't implemented yet.
Multiple line DCL commands, such as "if" statements, must be put inside
command files. You can run a command file by using \@.
VMS changes made for 3.74.3
Lots of default settings are adapted for VMS. See default.c.
Long command lines are now converted to command files.
Comma (',') as a separator is now allowed. See makefile.vms for an example.
-------------------------------------------------------------------------------
Copyright (C) 1996-2013 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 <http://www.gnu.org/licenses/>.

257
remake.c
View File

@@ -1,5 +1,5 @@
/* Basic dependency engine for GNU Make.
Copyright (C) 1988-2013 Free Software Foundation, Inc.
Copyright (C) 1988-2016 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
@@ -37,8 +37,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#include <io.h>
#endif
extern int try_implicit_rule (struct file *file, unsigned int depth);
/* The test for circular dependencies is based on the 'updating' bit in
'struct file'. However, double colon targets have separate 'struct
@@ -55,13 +53,17 @@ extern int try_implicit_rule (struct file *file, unsigned int depth);
/* Incremented when a command is started (under -n, when one would be). */
unsigned int commands_started = 0;
/* Set to the goal dependency. Mostly needed for remaking makefiles. */
static struct goaldep *goal_list;
static struct dep *goal_dep;
/* Current value for pruning the scan of the goal chain (toggle 0/1). */
static unsigned int considered;
static int update_file (struct file *file, unsigned int depth);
static int update_file_1 (struct file *file, unsigned int depth);
static int check_dep (struct file *file, unsigned int depth,
FILE_TIMESTAMP this_mtime, int *must_make_ptr);
static enum update_status update_file (struct file *file, unsigned int depth);
static enum update_status update_file_1 (struct file *file, unsigned int depth);
static enum update_status check_dep (struct file *file, unsigned int depth,
FILE_TIMESTAMP this_mtime, int *must_make);
static enum update_status touch_file (struct file *file);
static void remake_file (struct file *file);
static FILE_TIMESTAMP name_mtime (const char *name);
@@ -77,32 +79,23 @@ static const char *library_search (const char *lib, FILE_TIMESTAMP *mtime_ptr);
one goal whose 'changed' member is nonzero is successfully made. */
enum update_status
update_goal_chain (struct dep *goals)
update_goal_chain (struct goaldep *goaldeps)
{
int t = touch_flag, q = question_flag, n = just_print_flag;
enum update_status status = us_none;
#define MTIME(file) (rebuilding_makefiles ? file_mtime_no_search (file) \
: file_mtime (file))
/* Duplicate the chain so we can remove things from it. */
goals = copy_dep_chain (goals);
struct dep *goals = copy_dep_chain ((struct dep *)goaldeps);
{
/* Clear the 'changed' flag of each goal in the chain.
We will use the flag below to notice when any commands
have actually been run for a target. When no commands
have been run, we give an "up to date" diagnostic. */
struct dep *g;
for (g = goals; g != 0; g = g->next)
g->changed = 0;
}
goal_list = rebuilding_makefiles ? goaldeps : NULL;
/* All files start with the considered bit 0, so the global value is 1. */
considered = 1;
#define MTIME(file) (rebuilding_makefiles ? file_mtime_no_search (file) \
: file_mtime (file))
/* Update all the goals until they are all finished. */
while (goals != 0)
@@ -125,14 +118,16 @@ update_goal_chain (struct dep *goals)
struct file *file;
int stop = 0, any_not_updated = 0;
goal_dep = g;
for (file = g->file->double_colon ? g->file->double_colon : g->file;
file != NULL;
file = file->prev)
{
unsigned int ocommands_started;
int fail;
enum update_status fail;
file->dontcare = g->dontcare;
file->dontcare = ANY_SET (g->flags, RM_DONTCARE);
check_renamed (file);
if (rebuilding_makefiles)
@@ -161,14 +156,12 @@ update_goal_chain (struct dep *goals)
if (commands_started > ocommands_started)
g->changed = 1;
/* If we updated a file and STATUS was not already 1, set it to
1 if updating failed, or to 0 if updating succeeded. Leave
STATUS as it is if no updating was done. */
stop = 0;
if ((fail || file->updated) && status < us_question)
{
if (file->update_status != us_success)
/* We updated this goal. Update STATUS and decide whether
to stop. */
if (file->update_status)
{
/* Updating failed, or -q triggered. The STATUS value
tells our caller which. */
@@ -228,10 +221,10 @@ update_goal_chain (struct dep *goals)
&& file->update_status == us_success && !g->changed
/* Never give a message under -s or -q. */
&& !silent_flag && !question_flag)
message (1, ((file->phony || file->cmds == 0)
? _("Nothing to be done for '%s'.")
: _("'%s' is up to date.")),
file->name);
OS (message, 1, ((file->phony || file->cmds == 0)
? _("Nothing to be done for '%s'.")
: _("'%s' is up to date.")),
file->name);
/* This goal is finished. Remove it from the chain. */
if (lastgoal == 0)
@@ -270,6 +263,30 @@ update_goal_chain (struct dep *goals)
return status;
}
/* If we're rebuilding an included makefile that failed, and we care
about errors, show an error message the first time. */
void
show_goal_error (void)
{
struct goaldep *goal;
if ((goal_dep->flags & (RM_INCLUDED|RM_DONTCARE)) != RM_INCLUDED)
return;
for (goal = goal_list; goal; goal = goal->next)
if (goal_dep->file == goal->file)
{
if (goal->error)
{
OSS (error, &goal->floc, "%s: %s",
goal->file->name, strerror ((int)goal->error));
goal->error = 0;
}
return;
}
}
/* If FILE is not up to date, execute the commands for it.
Return 0 if successful, non-0 if unsuccessful;
but with some flag settings, just call 'exit' if unsuccessful.
@@ -282,11 +299,11 @@ update_goal_chain (struct dep *goals)
If there are multiple double-colon entries for FILE,
each is considered in turn. */
static int
static enum update_status
update_file (struct file *file, unsigned int depth)
{
int status = 0;
register struct file *f;
enum update_status status = us_success;
struct file *f;
f = file->double_colon ? file->double_colon : file;
@@ -303,7 +320,7 @@ update_file (struct file *file, unsigned int depth)
&& !f->dontcare && f->no_diag))
{
DBF (DB_VERBOSE, _("Pruning file '%s'.\n"));
return f->command_state == cs_finished ? f->update_status : 0;
return f->command_state == cs_finished ? f->update_status : us_success;
}
}
@@ -311,26 +328,28 @@ update_file (struct file *file, unsigned int depth)
the chain is exhausted. */
for (; f != 0; f = f->prev)
{
enum update_status new;
f->considered = considered;
status |= update_file_1 (f, depth);
new = update_file_1 (f, depth);
check_renamed (f);
/* Clean up any alloca() used during the update. */
alloca (0);
/* If we got an error, don't bother with double_colon etc. */
if (status != 0 && !keep_going_flag)
return status;
if (new && !keep_going_flag)
return new;
if (f->command_state == cs_running
|| f->command_state == cs_deps_running)
{
/* Don't run the other :: rules for this
file until this rule is finished. */
status = 0;
break;
}
/* Don't run other :: rules for this target until
this rule is finished. */
return us_success;
if (new > status)
status = new;
}
/* Process the remaining rules in the double colon chain so they're marked
@@ -343,7 +362,11 @@ update_file (struct file *file, unsigned int depth)
f->considered = considered;
for (d = f->deps; d != 0; d = d->next)
status |= update_file (d->file, depth + 1);
{
enum update_status new = update_file (d->file, depth + 1);
if (new > status)
status = new;
}
}
return status;
@@ -373,24 +396,29 @@ complain (struct file *file)
if (d == 0)
{
const char *msg_noparent
= _("%sNo rule to make target '%s'%s");
const char *msg_parent
= _("%sNo rule to make target '%s', needed by '%s'%s");
show_goal_error ();
/* Didn't find any dependencies to complain about. */
if (!keep_going_flag)
if (file->parent)
{
if (file->parent == 0)
fatal (NILF, msg_noparent, "", file->name, "");
size_t l = strlen (file->name) + strlen (file->parent->name) + 4;
const char *m = _("%sNo rule to make target '%s', needed by '%s'%s");
fatal (NILF, msg_parent, "", file->name, file->parent->name, "");
if (!keep_going_flag)
fatal (NILF, l, m, "", file->name, file->parent->name, "");
error (NILF, l, m, "*** ", file->name, file->parent->name, ".");
}
if (file->parent == 0)
error (NILF, msg_noparent, "*** ", file->name, ".");
else
error (NILF, msg_parent, "*** ", file->name, file->parent->name, ".");
{
size_t l = strlen (file->name) + 4;
const char *m = _("%sNo rule to make target '%s'%s");
if (!keep_going_flag)
fatal (NILF, l, m, "", file->name, "");
error (NILF, l, m, "*** ", file->name, ".");
}
file->no_diag = 0;
}
@@ -399,12 +427,12 @@ complain (struct file *file)
/* Consider a single 'struct file' and update it as appropriate.
Return 0 on success, or non-0 on failure. */
static int
static enum update_status
update_file_1 (struct file *file, unsigned int depth)
{
enum update_status dep_status = us_success;
FILE_TIMESTAMP this_mtime;
int noexist, must_make, deps_changed;
int dep_status = 0;
struct file *ofile;
struct dep *d, *ad;
struct dep amake;
@@ -478,8 +506,9 @@ update_file_1 (struct file *file, unsigned int depth)
/* Avoid spurious rebuilds due to low resolution time stamps. */
int ns = FILE_TIMESTAMP_NS (this_mtime);
if (ns != 0)
error (NILF, _("*** Warning: .LOW_RESOLUTION_TIME file '%s' has a high resolution time stamp"),
file->name);
OS (error, NILF,
_("*** Warning: .LOW_RESOLUTION_TIME file '%s' has a high resolution time stamp"),
file->name);
this_mtime += FILE_TIMESTAMPS_PER_S - 1 - ns;
}
@@ -521,6 +550,7 @@ update_file_1 (struct file *file, unsigned int depth)
while (d)
{
enum update_status new;
FILE_TIMESTAMP mtime;
int maybe_make;
int dontcare = 0;
@@ -532,8 +562,8 @@ update_file_1 (struct file *file, unsigned int depth)
if (is_updating (d->file))
{
error (NILF, _("Circular %s <- %s dependency dropped."),
file->name, d->file->name);
OSS (error, NILF, _("Circular %s <- %s dependency dropped."),
file->name, d->file->name);
/* We cannot free D here because our the caller will still have
a reference to it when we were called recursively via
check_dep below. */
@@ -555,7 +585,9 @@ update_file_1 (struct file *file, unsigned int depth)
d->file->dontcare = file->dontcare;
}
dep_status |= check_dep (d->file, depth, this_mtime, &maybe_make);
new = check_dep (d->file, depth, this_mtime, &maybe_make);
if (new > dep_status)
dep_status = new;
/* Restore original dontcare flag. */
if (rebuilding_makefiles)
@@ -601,6 +633,7 @@ update_file_1 (struct file *file, unsigned int depth)
for (d = file->deps; d != 0; d = d->next)
if (d->file->intermediate)
{
enum update_status new;
int dontcare = 0;
FILE_TIMESTAMP mtime = file_mtime (d->file);
@@ -619,7 +652,9 @@ update_file_1 (struct file *file, unsigned int depth)
not prune it. */
d->file->considered = !considered;
dep_status |= update_file (d->file, depth);
new = update_file (d->file, depth);
if (new > dep_status)
dep_status = new;
/* Restore original dontcare flag. */
if (rebuilding_makefiles)
@@ -664,9 +699,10 @@ update_file_1 (struct file *file, unsigned int depth)
/* If any dependency failed, give up now. */
if (dep_status != 0)
if (dep_status)
{
file->update_status = us_failed;
/* I'm not sure if we can't just assign dep_status... */
file->update_status = dep_status == us_none ? us_failed : dep_status;
notice_finished_file (file);
--depth;
@@ -675,8 +711,8 @@ update_file_1 (struct file *file, unsigned int depth)
if (depth == 0 && keep_going_flag
&& !just_print_flag && !question_flag)
error (NILF,
_("Target '%s' not remade because of errors."), file->name);
OS (error, NILF,
_("Target '%s' not remade because of errors."), file->name);
return dep_status;
}
@@ -981,13 +1017,13 @@ notice_finished_file (struct file *file)
FILE depends on (including FILE itself). Return nonzero if any updating
failed. */
static int
static enum update_status
check_dep (struct file *file, unsigned int depth,
FILE_TIMESTAMP this_mtime, int *must_make_ptr)
{
struct file *ofile;
struct dep *d;
int dep_status = 0;
enum update_status dep_status = us_success;
++depth;
start_updating (file);
@@ -1060,12 +1096,13 @@ check_dep (struct file *file, unsigned int depth,
d = file->deps;
while (d != 0)
{
enum update_status new;
int maybe_make;
if (is_updating (d->file))
{
error (NILF, _("Circular %s <- %s dependency dropped."),
file->name, d->file->name);
OSS (error, NILF, _("Circular %s <- %s dependency dropped."),
file->name, d->file->name);
if (ld == 0)
{
file->deps = d->next;
@@ -1083,12 +1120,14 @@ check_dep (struct file *file, unsigned int depth,
d->file->parent = file;
maybe_make = *must_make_ptr;
dep_status |= check_dep (d->file, depth, this_mtime,
&maybe_make);
new = check_dep (d->file, depth, this_mtime, &maybe_make);
if (new > dep_status)
dep_status = new;
if (! d->ignore_mtime)
*must_make_ptr = maybe_make;
check_renamed (d->file);
if (dep_status != 0 && !keep_going_flag)
if (dep_status && !keep_going_flag)
break;
if (d->file->command_state == cs_running
@@ -1122,7 +1161,7 @@ static enum update_status
touch_file (struct file *file)
{
if (!silent_flag)
message (0, "touch %s", file->name);
OS (message, 0, "touch %s", file->name);
/* Print-only (-n) takes precedence over touch (-t). */
if (just_print_flag)
@@ -1134,8 +1173,9 @@ touch_file (struct file *file)
else
#endif
{
int fd = open (file->name, O_RDWR | O_CREAT, 0666);
int fd;
EINTRLOOP (fd, open (file->name, O_RDWR | O_CREAT, 0666));
if (fd < 0)
TOUCH_ERROR ("touch: open: ");
else
@@ -1148,18 +1188,24 @@ touch_file (struct file *file)
if (e < 0)
TOUCH_ERROR ("touch: fstat: ");
/* Rewrite character 0 same as it already is. */
if (read (fd, &buf, 1) < 0)
EINTRLOOP (e, read (fd, &buf, 1));
if (e < 0)
TOUCH_ERROR ("touch: read: ");
if (lseek (fd, 0L, 0) < 0L)
TOUCH_ERROR ("touch: lseek: ");
if (write (fd, &buf, 1) < 0)
{
off_t o;
EINTRLOOP (o, lseek (fd, 0L, 0));
if (o < 0L)
TOUCH_ERROR ("touch: lseek: ");
}
EINTRLOOP (e, write (fd, &buf, 1));
if (e < 0)
TOUCH_ERROR ("touch: write: ");
/* If file length was 0, we just
changed it, so change it back. */
/* If file length was 0, we just changed it, so change it back. */
if (statbuf.st_size == 0)
{
(void) close (fd);
fd = open (file->name, O_RDWR | O_TRUNC, 0666);
EINTRLOOP (fd, open (file->name, O_RDWR | O_TRUNC, 0666));
if (fd < 0)
TOUCH_ERROR ("touch: open: ");
}
@@ -1225,6 +1271,7 @@ FILE_TIMESTAMP
f_mtime (struct file *file, int search)
{
FILE_TIMESTAMP mtime;
int propagate_timestamp;
/* File's mtime is not known; must get it from the system. */
@@ -1301,6 +1348,8 @@ f_mtime (struct file *file, int search)
|| (file->name[0] == '-' && file->name[1] == 'l'
&& (name = library_search (file->name, &mtime)) != 0))
{
int name_len;
if (mtime != UNKNOWN_MTIME)
/* vpath_search and library_search store UNKNOWN_MTIME
if they didn't need to do a stat call for their work. */
@@ -1309,7 +1358,14 @@ f_mtime (struct file *file, int search)
/* If we found it in VPATH, see if it's in GPATH too; if so,
change the name right now; if not, defer until after the
dependencies are updated. */
if (gpath_search (name, strlen (name) - strlen (file->name) - 1))
#ifndef VMS
name_len = strlen (name) - strlen (file->name) - 1;
#else
name_len = strlen (name) - strlen (file->name);
if (name[name_len - 1] == '/')
name_len--;
#endif
if (gpath_search (name, name_len))
{
rename_file (file, name);
check_renamed (file);
@@ -1369,8 +1425,9 @@ f_mtime (struct file *file, int search)
if (adjusted_now < adjusted_mtime)
{
#ifdef NO_FLOAT
error (NILF, _("Warning: File '%s' has modification time in the future"),
file->name);
OS (error, NILF,
_("Warning: File '%s' has modification time in the future"),
file->name);
#else
double from_now =
(FILE_TIMESTAMP_S (mtime) - FILE_TIMESTAMP_S (now)
@@ -1382,18 +1439,22 @@ f_mtime (struct file *file, int search)
sprintf (from_now_string, "%lu", (unsigned long) from_now);
else
sprintf (from_now_string, "%.2g", from_now);
error (NILF, _("Warning: File '%s' has modification time %s s in the future"),
file->name, from_now_string);
OSS (error, NILF,
_("Warning: File '%s' has modification time %s s in the future"),
file->name, from_now_string);
#endif
clock_skew_detected = 1;
}
}
}
/* Store the mtime into all the entries for this file. */
/* Store the mtime into all the entries for this file for which it is safe
to do so: avoid propagating timestamps to double-colon rules that haven't
been examined so they're run or not based on the pre-update timestamp. */
if (file->double_colon)
file = file->double_colon;
propagate_timestamp = file->updated;
do
{
/* If this file is not implicit but it is intermediate then it was
@@ -1405,7 +1466,8 @@ f_mtime (struct file *file, int search)
&& !file->tried_implicit && file->intermediate)
file->intermediate = 0;
file->last_mtime = mtime;
if (file->updated == propagate_timestamp)
file->last_mtime = mtime;
file = file->prev;
}
while (file != 0);
@@ -1520,7 +1582,7 @@ name_mtime (const char *name)
static const char *
library_search (const char *lib, FILE_TIMESTAMP *mtime_ptr)
{
static char *dirs[] =
static const char *dirs[] =
{
#ifndef _AMIGA
"/lib",
@@ -1550,7 +1612,7 @@ library_search (const char *lib, FILE_TIMESTAMP *mtime_ptr)
/* Information about the earliest (in the vpath sequence) match. */
unsigned int best_vpath = 0, best_path = 0;
char **dp;
const char **dp;
libpatterns = xstrdup (variable_expand ("$(.LIBPATTERNS)"));
@@ -1580,7 +1642,8 @@ library_search (const char *lib, FILE_TIMESTAMP *mtime_ptr)
if (!p3)
{
/* Give a warning if there is no pattern. */
error (NILF, _(".LIBPATTERNS element '%s' is not a pattern"), p);
OS (error, NILF,
_(".LIBPATTERNS element '%s' is not a pattern"), p);
p[len] = c;
continue;
}

View File

@@ -3,7 +3,7 @@
Please do not send bug reports or questions about it to
the Make maintainers.
Copyright (C) 1988-2013 Free Software Foundation, Inc.
Copyright (C) 1988-2016 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
@@ -151,7 +151,7 @@ start_remote_job (char **argv, char **envp, int stdin_fd,
retsock = Rpc_UdpCreate (True, 0);
if (retsock < 0)
{
error (NILF, "exporting: Couldn't create return socket.");
O (error, NILF, "exporting: Couldn't create return socket.");
return 1;
}
@@ -192,35 +192,37 @@ start_remote_job (char **argv, char **envp, int stdin_fd,
host = gethostbyaddr ((char *)&permit.addr, sizeof(permit.addr), AF_INET);
if (status != RPC_SUCCESS)
{
(void) close (retsock);
(void) close (sock);
error (NILF, "exporting to %s: %s",
host ? host->h_name : inet_ntoa (permit.addr),
Rpc_ErrorMessage (status));
return 1;
}
else if (msg[0] != 'O' || msg[1] != 'k' || msg[2] != '\0')
{
(void) close (retsock);
(void) close (sock);
error (NILF, "exporting to %s: %s",
host ? host->h_name : inet_ntoa (permit.addr),
msg);
return 1;
}
else
{
error (NILF, "*** exported to %s (id %u)",
host ? host->h_name : inet_ntoa (permit.addr),
permit.id);
}
{
const char *hnm = host ? host->h_name : inet_ntoa (permit.addr);
size_t hlen = strlen (hnm);
fflush (stdout);
fflush (stderr);
if (status != RPC_SUCCESS)
{
const char *err = Rpc_ErrorMessage (status);
(void) close (retsock);
(void) close (sock);
error (NILF, hlen + strlen (err),
"exporting to %s: %s", hnm, err);
return 1;
}
else if (msg[0] != 'O' || msg[1] != 'k' || msg[2] != '\0')
{
(void) close (retsock);
(void) close (sock);
error (NILF, hlen + strlen (msg), "exporting to %s: %s", hnm, msg);
return 1;
}
else
{
error (NILF, hlen + INTSTR_LENGTH,
"*** exported to %s (id %u)", hnm, permit.id);
}
pid = fork ();
fflush (stdout);
fflush (stderr);
}
pid = vfork ();
if (pid < 0)
{
/* The fork failed! */

View File

@@ -1,5 +1,5 @@
/* Template for the remote job exportation interface to GNU Make.
Copyright (C) 1988-2013 Free Software Foundation, Inc.
Copyright (C) 1988-2016 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

16
rule.c
View File

@@ -1,5 +1,5 @@
/* Pattern and suffix rule internals for GNU Make.
Copyright (C) 1988-2013 Free Software Foundation, Inc.
Copyright (C) 1988-2016 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
@@ -18,8 +18,8 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#include <assert.h>
#include "dep.h"
#include "filedef.h"
#include "dep.h"
#include "job.h"
#include "commands.h"
#include "variable.h"
@@ -140,8 +140,7 @@ count_implicit_rule_limits (void)
rule = next;
}
if (name != 0)
free (name);
free (name);
}
/* Create a pattern rule from a suffix rule.
@@ -357,7 +356,7 @@ void
install_pattern_rule (struct pspec *p, int terminal)
{
struct rule *r;
char *ptr;
const char *ptr;
r = xmalloc (sizeof (struct rule));
@@ -373,7 +372,7 @@ install_pattern_rule (struct pspec *p, int terminal)
++r->suffixes[0];
ptr = p->dep;
r->deps = PARSE_SIMPLE_SEQ (&ptr, struct dep);
r->deps = PARSE_SIMPLE_SEQ ((char **)&ptr, struct dep);
if (new_pattern_rule (r, 0))
{
@@ -381,6 +380,7 @@ install_pattern_rule (struct pspec *p, int terminal)
r->cmds = xmalloc (sizeof (struct commands));
r->cmds->fileinfo.filenm = 0;
r->cmds->fileinfo.lineno = 0;
r->cmds->fileinfo.offset = 0;
/* These will all be string literals, but we malloc space for them
anyway because somebody might want to free them later. */
r->cmds->commands = xstrdup (p->commands);
@@ -528,7 +528,7 @@ print_rule_data_base (void)
/* This can happen if a fatal error was detected while reading the
makefiles and thus count_implicit_rule_limits wasn't called yet. */
if (num_pattern_rules != 0)
fatal (NILF, _("BUG: num_pattern_rules is wrong! %u != %u"),
num_pattern_rules, rules);
ONN (fatal, NILF, _("BUG: num_pattern_rules is wrong! %u != %u"),
num_pattern_rules, rules);
}
}

5
rule.h
View File

@@ -1,5 +1,5 @@
/* Definitions for using pattern rules in GNU Make.
Copyright (C) 1988-2013 Free Software Foundation, Inc.
Copyright (C) 1988-2016 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
@@ -33,7 +33,7 @@ struct rule
/* For calling install_pattern_rule. */
struct pspec
{
char *target, *dep, *commands;
const char *target, *dep, *commands;
};
@@ -55,3 +55,4 @@ void install_pattern_rule (struct pspec *p, int terminal);
void create_pattern_rule (const char **targets, const char **target_percents,
unsigned int num, int terminal, struct dep *deps,
struct commands *commands, int override);
void print_rule_data_base (void);

View File

@@ -1,5 +1,5 @@
/* Convert between signal names and numbers.
Copyright (C) 1990-2013 Free Software Foundation, Inc.
Copyright (C) 1990-2016 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

View File

@@ -1,5 +1,5 @@
/* Constant string caching for GNU Make.
Copyright (C) 2006-2013 Free Software Foundation, Inc.
Copyright (C) 2006-2016 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
@@ -42,8 +42,8 @@ struct strcache {
#define CACHE_BUFFER_ALLOC(_s) ((_s) - (2 * sizeof (size_t)))
#define CACHE_BUFFER_OFFSET (offsetof (struct strcache, buffer))
#define CACHE_BUFFER_SIZE(_s) (CACHE_BUFFER_ALLOC(_s) - CACHE_BUFFER_OFFSET)
#define BUFSIZE CACHE_BUFFER_SIZE (CACHE_BUFFER_BASE)
static sc_buflen_t bufsize = CACHE_BUFFER_SIZE (CACHE_BUFFER_BASE);
static struct strcache *strcache = NULL;
static struct strcache *fullcache = NULL;
@@ -57,65 +57,76 @@ static unsigned long total_size = 0;
that this doesn't seem to be much of an issue in practice.
*/
static struct strcache *
new_cache ()
new_cache (struct strcache **head, sc_buflen_t buflen)
{
struct strcache *new;
new = xmalloc (bufsize + CACHE_BUFFER_OFFSET);
struct strcache *new = xmalloc (buflen + CACHE_BUFFER_OFFSET);
new->end = 0;
new->count = 0;
new->bytesfree = bufsize;
new->bytesfree = buflen;
new->next = strcache;
strcache = new;
new->next = *head;
*head = new;
++total_buffers;
return new;
}
static const char *
copy_string (struct strcache *sp, const char *str, unsigned int len)
{
/* Add the string to this cache. */
char *res = &sp->buffer[sp->end];
memmove (res, str, len);
res[len++] = '\0';
sp->end += len;
sp->bytesfree -= len;
++sp->count;
return res;
}
static const char *
add_string (const char *str, unsigned int len)
{
char *res;
const char *res;
struct strcache *sp;
struct strcache **spp = &strcache;
/* We need space for the nul char. */
unsigned int sz = len + 1;
/* If the string we want is too large to fit into a single buffer, then
no existing cache is large enough. Change the maximum size. */
if (sz > bufsize)
bufsize = CACHE_BUFFER_SIZE ((((sz + 1) / CACHE_BUFFER_BASE) + 1)
* CACHE_BUFFER_BASE);
else
/* Find the first cache with enough free space. */
for (; *spp != NULL; spp = &(*spp)->next)
if ((*spp)->bytesfree > sz)
break;
/* If nothing is big enough, make a new cache. */
sp = *spp;
if (sp == NULL)
{
sp = new_cache ();
spp = &sp;
}
/* Add the string to this cache. */
res = &sp->buffer[sp->end];
memmove (res, str, len);
res[len] = '\0';
sp->end += sz;
sp->bytesfree -= sz;
++sp->count;
/* If the amount free in this cache is less than the average string size,
consider it full and move it to the full list. */
++total_strings;
total_size += sz;
if (sp->bytesfree < (total_size / total_strings) + 1)
/* If the string we want is too large to fit into a single buffer, then
no existing cache is large enough. Add it directly to the fullcache. */
if (sz > BUFSIZE)
{
*spp = (*spp)->next;
sp = new_cache (&fullcache, sz);
return copy_string (sp, str, len);
}
/* Find the first cache with enough free space. */
for (; *spp != NULL; spp = &(*spp)->next)
if ((*spp)->bytesfree > sz)
break;
sp = *spp;
/* If nothing is big enough, make a new cache at the front. */
if (sp == NULL)
{
sp = new_cache (&strcache, BUFSIZE);
spp = &strcache;
}
/* Add the string to this cache. */
res = copy_string (sp, str, len);
/* If the amount free in this cache is less than the average string size,
consider it full and move it to the full list. */
if (total_strings > 20 && sp->bytesfree < (total_size / total_strings) + 1)
{
*spp = sp->next;
sp->next = fullcache;
fullcache = sp;
}
@@ -123,6 +134,26 @@ add_string (const char *str, unsigned int len)
return res;
}
/* For strings too large for the strcache, we just save them in a list. */
struct hugestring {
struct hugestring *next; /* The next string. */
char buffer[1]; /* The string. */
};
static struct hugestring *hugestrings = NULL;
static const char *
add_hugestring (const char *str, unsigned int len)
{
struct hugestring *new = xmalloc (sizeof (struct hugestring) + len);
memcpy (new->buffer, str, len);
new->buffer[len] = '\0';
new->next = hugestrings;
hugestrings = new;
return new->buffer;
}
/* Hash table of strings in the cache. */
@@ -148,11 +179,19 @@ static struct hash_table strings;
static unsigned long total_adds = 0;
static const char *
add_hash (const char *str, int len)
add_hash (const char *str, unsigned int len)
{
char *const *slot;
const char *key;
/* If it's too large for the string cache, just copy it.
We don't bother trying to match these. */
if (len > USHRT_MAX - 1)
return add_hugestring (str, len);
/* Look up the string in the hash. If it's there, return it. */
char *const *slot = (char *const *) hash_find_slot (&strings, str);
const char *key = *slot;
slot = (char *const *) hash_find_slot (&strings, str);
key = *slot;
/* Count the total number of add operations we performed. */
++total_adds;
@@ -179,6 +218,13 @@ strcache_iscached (const char *str)
if (str >= sp->buffer && str < sp->buffer + sp->end)
return 1;
{
struct hugestring *hp;
for (hp = hugestrings; hp != 0; hp = hp->next)
if (str == hp->buffer)
return 1;
}
return 0;
}
@@ -207,14 +253,6 @@ strcache_add_len (const char *str, unsigned int len)
return add_hash (str, len);
}
int
strcache_setbufsize (unsigned int size)
{
if (size > bufsize)
bufsize = size;
return bufsize;
}
void
strcache_init (void)
{
@@ -229,7 +267,7 @@ strcache_print_stats (const char *prefix)
{
const struct strcache *sp;
unsigned long numbuffs = 0, fullbuffs = 0;
unsigned long totfree = 0, maxfree = 0, minfree = bufsize;
unsigned long totfree = 0, maxfree = 0, minfree = BUFSIZE;
if (! strcache)
{
@@ -268,12 +306,13 @@ strcache_print_stats (const char *prefix)
(total_size / total_strings));
printf (_("%s current buf: size = %hu B / used = %hu B / count = %hu / avg = %hu B\n"),
prefix, bufsize, strcache->end, strcache->count,
prefix, (sc_buflen_t)BUFSIZE, strcache->end, strcache->count,
(strcache->end / strcache->count));
if (numbuffs)
{
unsigned long sz = total_size - bufsize;
/* Show information about non-current buffers. */
unsigned long sz = total_size - strcache->end;
unsigned long cnt = total_strings - strcache->count;
sc_buflen_t avgfree = totfree / numbuffs;

View File

@@ -1,5 +1,5 @@
@echo off
rem Copyright (C) 1996-2013 Free Software Foundation, Inc.
rem Copyright (C) 1996-2016 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
@@ -20,4 +20,5 @@ set MAKE=%2
set MAKEFILE=%1
if x%2 == x set MAKE=nmake
%MAKE% /f %MAKEFILE%
if ERRORLEVEL 1 exit /B
cd ..\..

1
tests/.gitignore vendored
View File

@@ -1 +1,2 @@
config-flags.pm
work

View File

@@ -1,3 +1,82 @@
2013-10-09 Paul Smith <psmith@gnu.org>
* scripts/features/patspecific_vars: Typo fixes.
2013-10-05 Paul Smith <psmith@gnu.org>
* test_driver.pl (run_all_tests): Rewrite to be more clear.
* scripts/features/jobserver: Avoid using $ENV{HOME} as it doesn't
exist everywhere.
* scripts/features/default_names: End with 1;
* scripts/features/loadapi: Use new calling signatures. Verify
the NOEXPAND flag works. Test with all valid function name
characters.
2013-09-29 Paul Smith <psmith@gnu.org>
* scripts/variables/SHELL: Solaris /bin/sh can't handle options in
multiple words; skip that test.
* scripts/targets/ONESHELL: Ditto.
* scripts/variables/GNUMAKEFLAGS: Verify that GNUMAKEFLAGS is
cleared and options are not duplicated.
2013-09-23 Paul Smith <psmith@gnu.org>
* scripts/options/print-directory: Rename dash-w to
print-directory to avoid conflicts with dash-W on case-insensitive
filesystems.
2013-09-22 Paul Smith <psmith@gnu.org>
* scripts/features/se_implicit: Verify that order-only tokens
inside second expansion are parsed correctly.
Test for Savannah bug #31155.
* run_make_tests.pl (set_more_defaults): If we can't find
gnumake.h based on the make program we might be running from a
remote build directory. Parse the Makefile for the right path.
Fix some test issues on Solaris.
* scripts/features/archives: Determine what output ar gives when
adding and replacing objects and compare with that.
* scripts/features/escape: Solaris /bin/sh doesn't properly handle
backslashes inside single quotes, so don't rely on it.
* scripts/features/output-sync: false(1) gives different exit
codes on different systems; use "exit 1" instead.
* scripts/features/parallelism: Increase the timeout for slower systems.
2013-09-21 Paul Smith <psmith@gnu.org>
* scripts/features/archives: Some versions of ar (MacOSX) generate
different output when creating archives. Run it and verify the
real output.
* scripts/features/default_names: MacOSX is, like Windows,
case-preserving / case-insensitive. Redo the test to avoid
checking for "UNIX".
* test_driver.pl (attach_default_output): Don't dup stdout into
stderr. Reported by Denis Excoffier <bug-tar@Denis-Excoffier.org>
* scripts/features/se_explicit: Fix a test that behaves
differently with/without archive capability enabled.
* scripts/features/output-sync: Don't test output-sync if it's not
enabled. We also skip it if parallelism is not enabled, although
strictly speaking some of the output-sync tests are valid even
without parallelism.
* scripts/features/jobserver: Move some tests that require the
jobserver from features/parallelism to a separate suite. Only run
this if jobserver mode is enabled.
* scripts/features/output-sync: Test shell functions writing to
stderr in recipes: ensure it's captured via output-sync. Test
output generated while reading makefiles and make sure it's
captured via output-sync. Make sure that fatal errors dump the
output so it's not lost.
* scripts/options/dash-w: Add a test for -w flag.
2013-09-15 Paul Smith <psmith@gnu.org>
* scripts/misc/fopen-fail: Check for failure on infinite recursion.
@@ -1334,7 +1413,7 @@
ChangeLog file for the test suite created.
Copyright (C) 1992-2013 Free Software Foundation, Inc.
Copyright (C) 1992-2016 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

View File

@@ -162,7 +162,7 @@ Changes from 0.1 to 0.2 (5-4-92):
-------------------------------------------------------------------------------
Copyright (C) 1992-2013 Free Software Foundation, Inc.
Copyright (C) 1992-2016 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

View File

@@ -7,7 +7,7 @@ This entire test suite, including all test files, are copyright and
distributed under the following terms:
-----------------------------------------------------------------------------
Copyright (C) 1992-2013 Free Software Foundation, Inc.
Copyright (C) 1992-2016 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

19
tests/config-flags.pm.in Normal file
View File

@@ -0,0 +1,19 @@
# This is a -*-perl-*- script
#
# Set variables that were defined by configure, in case we need them
# during the tests.
%CONFIG_FLAGS = (
AM_LDFLAGS => '@AM_LDFLAGS@',
AR => '@AR@',
CC => '@CC@',
CFLAGS => '@CFLAGS@',
CPP => '@CPP@',
CPPFLAGS => '@CPPFLAGS@',
GUILE_CFLAGS => '@GUILE_CFLAGS@',
GUILE_LIBS => '@GUILE_LIBS@',
LDFLAGS => '@LDFLAGS@',
LIBS => '@LIBS@'
);
1;

53
tests/config_flags_pm.com Executable file
View File

@@ -0,0 +1,53 @@
$!
$! config_flags_pm.com - Build config-flags.pm on VMS.
$!
$! Just good enough to run the self tests for now.
$!
$! Copyright (C) 2014-2016 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 <http://www.gnu.org/licenses/>.
$!
$!
$ open/read cfpm_in config-flags.pm.in
$!
$ outfile = "sys$disk:[]config-flags.pm"
$!
$ cflags = "/include=([],[.glob]"
$!
$ create 'outfile'
$ open/append cfpm 'outfile'
$!
$cfpm_read_loop:
$ read cfpm_in/end=cfpm_read_loop_end line_in
$ line_in_len = f$length(line_in)
$ if f$locate("@", line_in) .lt. line_in_len
$ then
$ part1 = f$element(0, "@", line_in)
$ key = f$element(1, "@", line_in)
$ part2 = f$element(2, "@", line_in)
$ value = ""
$ if key .eqs. "CC" then value = "CC"
$ if key .eqs. "CPP" then value = "CPP"
$ if key .eqs. "CFLAGS" then value = cflags
$ if key .eqs. "GUILE_CFLAGS" then value = cflags
$ write cfpm part1, value, part2
$ goto cfpm_read_loop
$ endif
$ write cfpm line_in
$ goto cfpm_read_loop
$cfpm_read_loop_end:
$ close cfpm_in
$ close cfpm
$!

View File

@@ -3,7 +3,7 @@
# Simple script to make a "shadow" test directory, using symbolic links.
# Typically you'd put the shadow in /tmp or another local disk
#
# Copyright (C) 1992-2013 Free Software Foundation, Inc.
# Copyright (C) 1992-2016 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

272
tests/run_make_tests.com Executable file
View File

@@ -0,0 +1,272 @@
$! Test_make.com
$!
$! This is a wrapper for the GNU make perl test programs on VMS.
$!
$! Parameter "-help" for description on how to use described below.
$!
$! Copyright (C) 2014-2016 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 <http://www.gnu.org/licenses/>.
$!
$!
$! Allow more than 8 paramters with using commas as a delimiter.
$!
$ params = "''p1',''p2',''p3',''p4',''p5',''p6',''p7',''p8'"
$!
$ test_flags = ",verbose,detail,keep,usage,help,debug,"
$ test_flags_len = f$length(test_flags)
$ verbose_flag = ""
$ detail_flag = ""
$ keep_flag = ""
$ usage_flag = ""
$ help_flag = ""
$ debug_flag = ""
$!
$ ignored_options = "profile,make,srcdir,valgrind,memcheck,massif,"
$ ignored_option_len = f$length(ignored_options)
$!
$ testname = ""
$ make :== $bin:make.exe"
$!
$ i = 0
$param_loop:
$ param = f$element(i, ",", params)
$ i = i + 1
$ if param .eqs. "" then goto param_loop
$ if param .eqs. "," then goto param_loop_end
$ param_len = f$length(param)
$ if f$locate("/", param) .lt. param_len
$ then
$ if testname .nes. ""
$ then
$ write sys$output "Only the last test name specified will be run!"
$ endif
$ testname = param
$ goto param_loop
$ endif
$ lc_param = f$edit(param,"LOWERCASE") - "-"
$ if f$locate(",''lc_param',", ignored_options) .lt. ignored_option_len
$ then
$ write sys$output "parameter ''param' is ignored on VMS for now."
$ goto param_loop
$ endif
$ if f$locate(",''lc_param',", test_flags) .lt. test_flags_len
$ then
$ 'lc_param'_flag = "-" + lc_param
$ goto param_loop
$ endif
$ write sys$output "parameter ''param' is not known to VMS."
$ goto param_loop
$!
$param_loop_end:
$!
$no_gnv = 1
$no_perl = 1
$!
$! Find GNV 2.1.3 + manditory updates
$! If properly updated, the GNV$GNU logical name is present.
$! Updated GNV utilities have a gnv$ prefix on them.
$ gnv_root = f$trnlnm("GNV$GNU", "LNM$SYSTEM_TABLE")
$ if gnv_root .nes. ""
$ then
$ no_gnv = 0
$ ! Check for update ar utility.
$ new_ar = "gnv$gnu:[usr.bin]gnv$ar.exe"
$ if f$search(new_ar) .nes. ""
$ then
$ ! See if a new port of ar exists.
$ ar :== $'new_ar'
$ else
$ ! Fall back to legacy GNV AR wrapper.
$ old_ar = "gnv$gnu:[bin]ar.exe"
$ if f$search(old_ar) .nes. ""
$ then
$ ar :== $'old_ar'
$ else
$ no_gnv = 1
$ endif
$ endif
$ ! Check for updated bash
$ if no_gnv .eq. 0
$ then
$ new_bash = "gnv$gnu:[bin]gnv$bash.exe"
$ if f$search(new_bash) .nes. ""
$ then
$ bash :== $'new_bash'
$ sh :== $'new_bash'
$ else
$ no_gnv = 1
$ endif
$ endif
$ ! Check for updated coreutils
$ if no_gnv .eq. 0
$ then
$ new_cat = "gnv$gnu:[bin]gnv$cat.exe"
$ if f$search(new_cat) .nes. ""
$ then
$ cat :== $'new_cat'
$ cp :== $gnv$gnu:[bin]gnv$cp.exe
$ echo :== $gnv$gnu:[bin]gnv$echo.exe
$ false :== $gnv$gnu:[bin]gnv$false.exe
$ true :== $gnv$gnu:[bin]gnv$true.exe
$ touch :== $gnv$gnu:[bin]gnv$touch.exe
$ mkdir :== $gnv$gnu:[bin]gnv$mkdir.exe
$ rm :== $gnv$gnu:[bin]gnv$rm.exe
$ sleep :== $gnv$gnu:[bin]gnv$sleep.exe
$ else
$ no_gnv = 1
$ endif
$ endif
$ ! Check for updated diff utility.
$ if no_gnv .eq. 0
$ then
$ new_diff = "gnv$gnu:[usr.bin]gnv$diff.exe"
$ if f$search(new_diff) .nes. ""
$ then
$ ! See if a new port of diff exists.
$ diff :== $'new_diff'
$ else
$ ! Fall back to legacy GNV diff
$ old_diff = "gnv$gnu:[bin]diff.exe"
$ if f$search(old_diff) .nes. ""
$ then
$ diff :== $'old_diff'
$ else
$ no_gnv = 1
$ endif
$ endif
$ endif
$ endif
$!
$if no_gnv
$then
$ write sys$output "Could not find an up to date GNV installed!"
$ help_flag = 1
$endif
$!
$! Find perl 5.18.1 or later.
$!
$! look in perl_root:[000000]perl_setup.com
$ perl_root = f$trnlnm("perl_root")
$ ! This works with known perl installed from PCSI kits.
$ if perl_root .nes. ""
$ then
$ perl_ver = f$element(1, ".", perl_root)
$ if f$locate("-", perl_ver) .lt. f$length(perl_ver)
$ then
$ no_perl = 0
$ endif
$ endif
$ if no_perl
$ then
$! look for sys$common:[perl-*]perl_setup.com
$ perl_setup = f$search("sys$common:[perl-*]perl_setup.com")
$ if perl_setup .eqs. ""
$ then
$ if gnv_root .nes. ""
$ then
$ gnv_device = f$parse(gnv_root,,,"DEVICE")
$ perl_templ = "[vms$common.perl-*]perl_setup.com"
$ perl_search = f$parse(perl_templ, gnv_device)
$ perl_setup = f$search(perl_search)
$ endif
$ endif
$ if perl_setup .nes. ""
$ then
$ @'perl_setup'
$ no_perl = 0
$ endif
$ endif
$!
$ if no_perl
$ then
$ write sys$output "Could not find an up to date Perl installed!"
$ help_flag = "-help"
$ endif
$!
$!
$ if help_flag .nes. ""
$ then
$ type sys$input
$DECK
This is a test script wrapper for the run_make_tests.pl script.
This wrapper makes sure that the DCL symbols and logical names needed to
run the perl script are in place.
The test wrapper currently requires that the DCL symbols be global symbols.
Those symbols will be left behind after the procedure is run.
The PERL_ROOT will be set to a compatible perl if such a perl is found and
is not the default PERL_ROOT:. This setting will persist after the test.
This wrapper should be run with the default set to the base directory
of the make source.
The HELP parameter will bring up this text and then run the help script
for the Perl wrapper. Not all options for the perl script have been
implemented, such as valgrind or specifying the make path or source path.
Running the wrapper script requires:
Perl 5.18 or later.
PCSI kits available from http://sourceforge.net/projects/vmsperlkit/files/
GNV 2.1.3 or later. GNV 3.0.1 has not tested with this script.
Bash 4.2.47 or later.
Coreutils 8.21 or later.
http://sourceforge.net/projects/gnv/files/
Read before installing:
http://sourceforge.net/p/gnv/wiki/InstallingGNVPackages/
As updates for other GNV components get posted, those updates should
be used.
$EOD
$ endif
$!
$ if no_gnv .or. no_perl then exit 44
$!
$!
$ default = f$environment("DEFAULT")
$ default_dev = f$element(0, ":", default) + ":"
$ this = f$environment("PROCEDURE")
$ on error then goto all_error
$ set default 'default_dev''f$parse(this,,,"DIRECTORY")'
$!
$! Need to make sure that the config-flags.pm exists.
$ if f$search("config-flags.pm") .eqs. ""
$ then
$ @config_flags_pm.com
$ endif
$ define/user bin 'default_dev'[-],gnv$gnu:[bin]
$ define/user decc$filename_unix_noversion enable
$ define/user decc$filename_unix_report enable
$ define/user decc$readdir_dropdotnotype enable
$ flags = ""
$ if verbose_flag .nes. "" then flags = verbose_flag
$ if detail_flag .nes. "" then flags = flags + " " + detail_flag
$ if keep_flag .nes. "" then flags = flags + " " + keep_flag
$ if usage_flag .nes. "" then flags = flags + " " + usage_flag
$ if help_flag .nes. "" then flags = flags + " " + help_flag
$ if debug_flag .nes. "" then flags = flags + " " + debug_flag
$ flags = f$edit(flags, "TRIM, COMPRESS")
$ if testname .nes. ""
$ then
$ perl run_make_tests.pl "''testname'" 'flags'
$ else
$ perl run_make_tests.pl 'flags'
$ endif
$all_error:
$ set default 'default'
$!

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