mirror of
https://github.com/mirror/make.git
synced 2026-08-20 00:43:29 +08:00
Compare commits
244 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9ab8af7cd8 | ||
|
|
f522852f07 | ||
|
|
a3d8c086d5 | ||
|
|
4762480ae9 | ||
|
|
ef6c059e1e | ||
|
|
cf4ed2ebe8 | ||
|
|
5a4f9a67a3 | ||
|
|
2987163ac4 | ||
|
|
ec61980122 | ||
|
|
9bb994e831 | ||
|
|
e2ebea35f1 | ||
|
|
c73ed7dd1c | ||
|
|
ba8383efd8 | ||
|
|
6f7fb050b4 | ||
|
|
45200a42d3 | ||
|
|
4c9e10fd94 | ||
|
|
6e640321fd | ||
|
|
7241d136f4 | ||
|
|
c2be1df880 | ||
|
|
f1a9625001 | ||
|
|
047bd5a16f | ||
|
|
3fc99a48e1 | ||
|
|
87a5f98d24 | ||
|
|
53554e41e8 | ||
|
|
5bd7ad2b22 | ||
|
|
65115e7095 | ||
|
|
75dd0bd8bc | ||
|
|
8b54c5cff9 | ||
|
|
65c447289e | ||
|
|
86b20728fe | ||
|
|
b8a8af6550 | ||
|
|
360b76af84 | ||
|
|
c9e6ab9ac7 | ||
|
|
40277b8850 | ||
|
|
35047f824a | ||
|
|
e97159745d | ||
|
|
2b9dd215d5 | ||
|
|
fc2ddebdae | ||
|
|
b4682cb479 | ||
|
|
09202bc880 | ||
|
|
9ae02b7916 | ||
|
|
247b71e690 | ||
|
|
e33f3d72bf | ||
|
|
fd1dd7c398 | ||
|
|
14b2d7effb | ||
|
|
85c788572d | ||
|
|
8164c8ab3d | ||
|
|
fb7a7adc8a | ||
|
|
4f8be4bb28 | ||
|
|
e2b39edc22 | ||
|
|
8530d77c68 | ||
|
|
89e18c12eb | ||
|
|
bccd01354b | ||
|
|
5f9d341160 | ||
|
|
798ebd241b | ||
|
|
4db6d0c694 | ||
|
|
b754a35df7 | ||
|
|
168f12375d | ||
|
|
83443c706a | ||
|
|
4a5377aef7 | ||
|
|
48391c2817 | ||
|
|
42745a900f | ||
|
|
43181f1f82 | ||
|
|
c18b23f7b2 | ||
|
|
fe5585528f | ||
|
|
0205d3d08c | ||
|
|
9ef06be018 | ||
|
|
ac9a39dad7 | ||
|
|
c6ac580785 | ||
|
|
9efd477e98 | ||
|
|
5036dd120a | ||
|
|
7e849f3b81 | ||
|
|
a80a8b8a10 | ||
|
|
e4ac28e830 | ||
|
|
1fae20a2b7 | ||
|
|
292da6f686 | ||
|
|
3c487e7ed5 | ||
|
|
c0380823a2 | ||
|
|
1faae1d4ed | ||
|
|
18eb093f56 | ||
|
|
894ee7f6c8 | ||
|
|
e75662bc6a | ||
|
|
d1df4b21f3 | ||
|
|
a66bf2d736 | ||
|
|
31c2024b2e | ||
|
|
7df0fe77d8 | ||
|
|
9fc787c658 | ||
|
|
1afb0ad372 | ||
|
|
86a058029b | ||
|
|
0a3a0756b9 | ||
|
|
3712e8a819 | ||
|
|
9ed452b041 | ||
|
|
b11bef0bea | ||
|
|
bd716a1ec1 | ||
|
|
b484efca56 | ||
|
|
562344122f | ||
|
|
9a2451af0b | ||
|
|
7f9ce6e97b | ||
|
|
621e9edfe9 | ||
|
|
986632ec23 | ||
|
|
95ffcda425 | ||
|
|
dcca1b5b0e | ||
|
|
9cad73ad82 | ||
|
|
8e7a28a6a4 | ||
|
|
98de32a681 | ||
|
|
5369be5079 | ||
|
|
8de07f3e4a | ||
|
|
f970315766 | ||
|
|
579ee85941 | ||
|
|
7e51810bb5 | ||
|
|
bd30df4478 | ||
|
|
1f2fd22fec | ||
|
|
ab1210b1fe | ||
|
|
241787d8e4 | ||
|
|
faeeb27166 | ||
|
|
cab353d1dd | ||
|
|
8b01e6bebf | ||
|
|
55c00544cc | ||
|
|
8d577c2ff4 | ||
|
|
e44d6a12bb | ||
|
|
423c3955d9 | ||
|
|
ac67346d0f | ||
|
|
e364498113 | ||
|
|
85047eb904 | ||
|
|
0faa98a0bb | ||
|
|
8411528fdd | ||
|
|
d2a3e9ca9c | ||
|
|
e1863c05d8 | ||
|
|
b981bfd197 | ||
|
|
88713683fe | ||
|
|
a7cac0f0e3 | ||
|
|
165ccf3137 | ||
|
|
24620378ba | ||
|
|
9c8b68a905 | ||
|
|
432cb6575d | ||
|
|
a4937bc897 | ||
|
|
889303cdfe | ||
|
|
99385ee6f7 | ||
|
|
f5f5adb62c | ||
|
|
865d90bb1e | ||
|
|
30b25acc4e | ||
|
|
f8905059c3 | ||
|
|
12a3104c3d | ||
|
|
7b485daffb | ||
|
|
757849cd93 | ||
|
|
9d58570c77 | ||
|
|
d49ab08ae0 | ||
|
|
10a4b120bd | ||
|
|
309768aff1 | ||
|
|
9c28d5125d | ||
|
|
a7794f483b | ||
|
|
5d653b535a | ||
|
|
53b4a9e668 | ||
|
|
d4723d643d | ||
|
|
107ab16bf6 | ||
|
|
07f2666b91 | ||
|
|
f4b746b8c2 | ||
|
|
d7f25cfda5 | ||
|
|
b9a01a8b3b | ||
|
|
d654bff457 | ||
|
|
74ed682c54 | ||
|
|
e498e464dc | ||
|
|
d1d737d0fa | ||
|
|
87e5b64f41 | ||
|
|
70df3c35bf | ||
|
|
01a745025d | ||
|
|
4792e154b6 | ||
|
|
188b2a0f23 | ||
|
|
52191d9d61 | ||
|
|
dc9ae5e017 | ||
|
|
723e047428 | ||
|
|
b69b04dc8c | ||
|
|
b539908f73 | ||
|
|
2fb91e19a0 | ||
|
|
f96c114e22 | ||
|
|
98197303b1 | ||
|
|
f8786092ad | ||
|
|
1d4c15b4e1 | ||
|
|
b1c7f0df4e | ||
|
|
8e12202870 | ||
|
|
1f4ca0539b | ||
|
|
d0944ee2e8 | ||
|
|
38066b6f19 | ||
|
|
3bf3fde984 | ||
|
|
543521cd47 | ||
|
|
e8122ecb5d | ||
|
|
55a0c0e414 | ||
|
|
8a3436c65d | ||
|
|
fd30db1290 | ||
|
|
c3524b83b9 | ||
|
|
0296e40fc7 | ||
|
|
f69922b335 | ||
|
|
65931ce7a9 | ||
|
|
1a991ada47 | ||
|
|
7e77685bc3 | ||
|
|
300d1296fb | ||
|
|
822f8dae41 | ||
|
|
d2d44f76c4 | ||
|
|
6c3e88e60f | ||
|
|
9cd01958da | ||
|
|
4120f91846 | ||
|
|
30a5ee0d85 | ||
|
|
8a6205b43f | ||
|
|
bc120f27bd | ||
|
|
5c0fba7240 | ||
|
|
fa0f2c516a | ||
|
|
20ecc58126 | ||
|
|
1b90248893 | ||
|
|
a4d8444b59 | ||
|
|
0a81d50d66 | ||
|
|
3aa2aa7e82 | ||
|
|
29a94ceb76 | ||
|
|
ab78cbc71c | ||
|
|
c5bfa40044 | ||
|
|
deff9dacc9 | ||
|
|
40a49f244d | ||
|
|
87ac68fe79 | ||
|
|
72462ef1e1 | ||
|
|
f80222c15b | ||
|
|
4b81f5ca92 | ||
|
|
5601726151 | ||
|
|
9453a7451d | ||
|
|
5e7bf7c554 | ||
|
|
138d020e1b | ||
|
|
5b65c5b916 | ||
|
|
cc85b927cd | ||
|
|
bee4d93a59 | ||
|
|
353fcfdb30 | ||
|
|
d4043519f7 | ||
|
|
ef11217de7 | ||
|
|
e8f5d322cf | ||
|
|
dc922e3f4c | ||
|
|
c11024b3b3 | ||
|
|
2fc0f614be | ||
|
|
bf60bbd67a | ||
|
|
d2eaed1f0a | ||
|
|
8ab3564a71 | ||
|
|
ecf307bb0b | ||
|
|
a674abe702 | ||
|
|
80183457ad | ||
|
|
cece7ad61f | ||
|
|
943c06de47 | ||
|
|
171eb41908 | ||
|
|
9babfe49a5 |
16
.gitignore
vendored
16
.gitignore
vendored
@@ -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
|
||||
|
||||
2
AUTHORS
2
AUTHORS
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -1,3 +1,526 @@
|
||||
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.
|
||||
* NEWS: Ditto.
|
||||
|
||||
2013-09-15 Paul Smith <psmith@gnu.org>
|
||||
|
||||
* doc/make.texi (Error Messages): Add a bit more info to the
|
||||
section on static pattern errors, since they're common.
|
||||
Fixes Savannah bug #31326.
|
||||
|
||||
* read.c (eval_makefile): If the file open fails with an
|
||||
unrecoverable error, stop now rather than trying to make it.
|
||||
Fixes Savannah bug #27374.
|
||||
|
||||
* main.c (main): Perform the validation of the jobserver FDs
|
||||
early, before we read makefiles, to ensure that something hasn't
|
||||
opened and used those FDs for some other reason.
|
||||
Fixes Savannah bug #39934.
|
||||
|
||||
* main.c (main): Don't set MAKEFLAGS in the environment when we
|
||||
restart. We have the original command line flags so keep the
|
||||
original MAKEFLAGS settings as well.
|
||||
Fixes Savannah bug #39203.
|
||||
|
||||
2013-09-14 Paul Smith <psmith@gnu.org>
|
||||
|
||||
* main.c (decode_debug_flags): Add support for the "n" flag to
|
||||
disable all debugging.
|
||||
* make.1: Document the "n" (none) flag.
|
||||
* doc/make.texi (Options Summary): Ditto.
|
||||
* NEWS: Ditto.
|
||||
Fixes Savannah bug #35248.
|
||||
|
||||
* misc.c (close_stdout): Move to output.c.
|
||||
* main.c (main): Move atexit call to output_init().
|
||||
* makeint.h: Remove close_stdout() declaration.
|
||||
* output.c (output_init): Add close_stdout at exit only if it's open.
|
||||
Fixes Savannah bug #33134. Suggested by David Boyce <dsb@boyski.com>.
|
||||
|
||||
2013-09-14 Paul Smith <psmith@gnu.org>
|
||||
|
||||
* misc.c (set_append_mode, open_tmpfd, open_tmpfile): Move to output.c.
|
||||
* misc.h: Ditto.
|
||||
* output.h: Ditto.
|
||||
* main.c (main): Move stdio init into output.c:output_init().
|
||||
Change open_tmpfile() to output_tmpfile().
|
||||
* output.c: Rename open_*() to output_*(). set_append_mode() and
|
||||
open_tmpfd() are static.
|
||||
(_outputs, log_working_directory): Accept a struct output and
|
||||
print to that rather than the global context.
|
||||
(output_dump): In recurse mode print enter/leave once for the
|
||||
whole makefile.
|
||||
(output_init): Initialize this processes stdio as well as child's.
|
||||
|
||||
* vmsjobs.c: Reformat to be closer to convention.
|
||||
|
||||
2013-09-12 Paul Smith <psmith@gnu.org>
|
||||
|
||||
Rework output to handle synchronization and directory logging more
|
||||
reliably.
|
||||
|
||||
* output.c: New file. Implement lazy synchronization and
|
||||
directory logging so that we manage them "just in time", and the
|
||||
destination of the output is set via a global state variable.
|
||||
* output.h: New file.
|
||||
* function.c (func_shell_base): Ensure the output is set up before
|
||||
running a shell command, in case it writes to stderr.
|
||||
(func_error): Use outputs() to generate output.
|
||||
* job.h (struct child): Add struct output to track the child's output.
|
||||
* job.c: Use struct output in the child structure to track output.
|
||||
(child_out, sync_init, assign_child_tempfiles, pump_from_tmp)
|
||||
(acquire_semaphore, release_semaphore, sync_output): Move most of
|
||||
the output_sync handling to output.c.
|
||||
(child_error): Set output, then use simple message() and error()
|
||||
not _s versions.
|
||||
* main.c (log_working_directory): Moved to output.c
|
||||
(trace_option, decode_trace_flags) Remove. Remove support for
|
||||
different trace modes; we don't use it anymore.
|
||||
(die) Invoke output_close() before we exit.
|
||||
* misc.c (message_s, error_s): Removed; no longer needed.
|
||||
(message, error, fatal, perror_with_name, pfatal_with_name): Moved
|
||||
to output.c.
|
||||
* makeint.h: Remove message_s(), error_s(), and
|
||||
log_working_directory(). Remove the TRACE_* macros.
|
||||
* doc/make.texi: Enhance documentation for output sync, and remove
|
||||
MODE assignment for --trace.
|
||||
* make.1: Remove MODE assignment for --trace.
|
||||
* Makefile.am: Add new files.
|
||||
* NMakefile.template: Ditto.
|
||||
* SMakefile.template: Ditto.
|
||||
* build_w32.bat: Ditto.
|
||||
* dosbuild.bat: Ditto.
|
||||
* make.lnk: Ditto.
|
||||
* make_nsvc_net2003.vcproj: Ditto.
|
||||
* makefile.vms: Ditto.
|
||||
* po/POTFILES.in: Ditto.
|
||||
|
||||
2013-08-22 Petr Machata <pmachata@redhat.com>
|
||||
|
||||
* function.c (func_shell_base): Get rid of any avoidable limit on
|
||||
stack size for processes spawned via $(shell).
|
||||
|
||||
2013-07-22 Paul Smith <psmith@gnu.org>
|
||||
|
||||
* implicit.c (pattern_search): Use PARSE_SIMPLE_SEQ() even for
|
||||
non-second expansion prerequisites, to handle globbing in patterns.
|
||||
Fixes Savannah bug #39310.
|
||||
|
||||
* dep.h (PARSE_SIMPLE_SEQ): Macro for simple file sequence parsing.
|
||||
* default.c (set_default_suffixes): Use it.
|
||||
* file.c (split_prereqs): Ditto.
|
||||
* main.c (main): Ditto.
|
||||
* read.c (eval): Ditto.
|
||||
* rule.c (install_pattern_rule): Ditto.
|
||||
* file.c (split_prereqs): Use PARSEFS_NONE instead of 0.
|
||||
|
||||
2013-07-21 Paul Smith <psmith@gnu.org>
|
||||
|
||||
Cleanups detected by cppcheck. Fixes Savannah bug #39158.
|
||||
* arscan.c (ar_scan): Reduce the scope of local variables.
|
||||
* dir.c (vms_hash): Ditto.
|
||||
(find_directory): Ditto.
|
||||
(file_impossible_p): Ditto.
|
||||
* expand.c (variable_expand_string): Ditto.
|
||||
* function.c (func_sort): Ditto.
|
||||
(func_and): Ditto.
|
||||
* job.c (reap_children): Ditto.
|
||||
(exec_command): Ditto.
|
||||
* main.c (main): Ditto.
|
||||
* misc.c (collapse_continuations): Ditto.
|
||||
* read.c (eval): Ditto.
|
||||
(parse_file_seq): Ditto.
|
||||
* vpath.c (gpath_search): Ditto.
|
||||
(selective_vpath_search): Ditto.
|
||||
* job.c (is_bourne_compatible_shell): Simplify for non-Windows systems.
|
||||
* remake.c (f_mtime): Remove duplicate test.
|
||||
* signame.c (strsignal): Fix bogus conditional.
|
||||
|
||||
* job.c (assign_child_tempfiles): Assign OUTFD to -1 for safety.
|
||||
(start_job_command): Don't test output_sync and sync_cmd: redundant.
|
||||
Changes suggested by Frank Heckenbach <f.heckenbach@fh-soft.de>.
|
||||
|
||||
2013-07-14 Paul Smith <psmith@gnu.org>
|
||||
|
||||
* filedef.h (update_status): Convert UPDATE_STATUS from a char to
|
||||
an enumeration. Some systems declare "char" to be "unsigned"
|
||||
which broke the code (which expected to be able to use -1 as a
|
||||
flag). Using magic values was unpleasant, so rather than just
|
||||
force "signed char" I reworked it to use an enum.
|
||||
|
||||
* dep.h (update_goal_chain): Return an update_status value not int.
|
||||
* remake.c (touch_file): Ditto.
|
||||
(update_goal_chain): Track the update_status enum.
|
||||
|
||||
* file.c (enter_file): Use new enumeration values with update_status.
|
||||
(remove_intermediates): Ditto.
|
||||
(print_file): Ditto.
|
||||
* commands.c (execute_file_commands): Ditto.
|
||||
* job.c (reap_children): Ditto.
|
||||
(start_job_command): Ditto.
|
||||
(start_waiting_job): Ditto.
|
||||
* main.c (main): Ditto.
|
||||
* remake.c (update_file): Ditto.
|
||||
(complain): Ditto.
|
||||
(update_file_1): Ditto.
|
||||
(notice_finished_file): Ditto.
|
||||
(remake_file): Ditto.
|
||||
* vmsjobs.c (vmsHandleChildTerm): Ditto.
|
||||
|
||||
2013-07-09 Paul Smith <psmith@gnu.org>
|
||||
|
||||
* implicit.c (pattern_search): Keep a local copy of the number of
|
||||
deps in deplist: the global max might change due to recursion.
|
||||
Fixes a bug reported by Martin d'Anjou <martin.danjou14@gmail.com>.
|
||||
|
||||
2013-06-28 Paul Smith <psmith@gnu.org>
|
||||
|
||||
* misc.c (set_append_mode): Set the O_APPEND flag on a file descriptor.
|
||||
(open_tmpfd): Set append mode on the temporary file descriptor.
|
||||
* main.c (main): Set append mode on stdout and stderr.
|
||||
* makeint.h (set_append_mode): Declare it.
|
||||
|
||||
2013-06-22 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* build_w32.bat (LinkGCC): Prevent a comment from being displayed
|
||||
at build time.
|
||||
|
||||
* job.c (construct_command_argv_internal) [WINDOWS32]: Use
|
||||
case-insensitive comparison with internal commands of non-Unix
|
||||
shells.
|
||||
|
||||
* main.c (find_and_set_default_shell): Don't use file_exists_p or
|
||||
dir_file_exists_p, as those call readdir, which can fail if PATH
|
||||
includes directories with non-ASCII characters, and that would
|
||||
cause Make to fail at startup with confusing diagnostics. See
|
||||
https://sourceforge.net/mailarchive/message.php?msg_id=30846737
|
||||
for the details.
|
||||
|
||||
2013-06-22 Paul Smith <psmith@gnu.org>
|
||||
|
||||
Improve performance by using a character map to determine where we
|
||||
want to stop searching strings, rather than discrete comparisons.
|
||||
|
||||
* read.c (find_char_unquote): Pass a stop map instead of various
|
||||
flags and use that to check when to stop parsing the string.
|
||||
(eval): Use the new find_char_unquote() calling signature.
|
||||
(remove_comments): Ditto.
|
||||
(unescape_char): Ditto.
|
||||
(find_percent_cached): Ditto.
|
||||
(parse_file_seq): Use a stop-map flag.
|
||||
* main.c (stopchar_map): Character map definition.
|
||||
(initialize_stopchar_map): Initialize the map definition.
|
||||
(main): Invoke the map initialization function.
|
||||
* misc.c (end_of_token_w32): Remove unused function.
|
||||
* dir.c (dosify): Use STOP_SET to check for stop chars.
|
||||
* main.c (main): Ditto.
|
||||
* misc.c (end_of_token): Ditto.
|
||||
* function.c (subst_expand): Ditto.
|
||||
(func_notdir_suffix): Ditto.
|
||||
(func_basename_dir): Ditto.
|
||||
(abspath): Ditto.
|
||||
* job.c (is_bourne_compatible_shell): Ditto.
|
||||
* variable.c (parse_variable_definition): Ditto.
|
||||
* read.c (eval): Ditto.
|
||||
(conditional_line): Ditto.
|
||||
(find_percent_cached): Ditto.
|
||||
* dep.h (PARSE_FILE_SEQ): Update function declaration.
|
||||
* default.c (set_default_suffixes): Update PARSE_FILE_SEQ() call.
|
||||
* file.c (split_prereqs): Ditto.
|
||||
* function.c (string_glob): Ditto.
|
||||
* implicit.c (pattern_search): Ditto.
|
||||
* rule.c (install_pattern_rule): Ditto.
|
||||
* main.c (main): Ditto.
|
||||
|
||||
2013-06-21 Paul Smith <psmith@gnu.org>
|
||||
|
||||
* main.c (verify_flag): Global variable to determine whether to
|
||||
verify the database or not.
|
||||
(decode_debug_flags): If debug mode, enable verify_flag.
|
||||
(main): If MAKE_MAINTAINER_MODE, enable verify_flag, otherwise not.
|
||||
(die): Only verify the database if verify_flag is set.
|
||||
* file.c (enter_file): Don't check caching unless verify_flag.
|
||||
* makeint.h: Export verify_flag.
|
||||
|
||||
2013-05-27 Paul Smith <psmith@gnu.org>
|
||||
|
||||
* variable.c (define_automatic_variables): Create a new variable
|
||||
MAKE_HOST.
|
||||
|
||||
2013-05-27 Hartmut Becker <becker.ismaning@freenet.de>
|
||||
|
||||
* function.c (func_shell_base) [VMS]: Support VMS.
|
||||
* makefile.com [VMS]: Ditto.
|
||||
* makefile.vms [VMS]: Ditto.
|
||||
* makeint.h [VMS]: Ditto.
|
||||
* vmsjobs.c [VMS]: Ditto.
|
||||
* job.h: Define RECORD_SYNC_MUTEX() when OUTPUT_SYNC is not set.
|
||||
* load.c (unload_file): Fix signature if MAKE_LOAD is not set.
|
||||
|
||||
2013-05-26 Paul Smith <psmith@gnu.org>
|
||||
|
||||
* remake.c (f_mtime): Ensure that archive file names are in the
|
||||
string cache. Fixes Savannah bug #38442.
|
||||
|
||||
* read.c (readline): To be safe, move the entire buffer if we
|
||||
detect a CR. Fixes Savannah bug #38945.
|
||||
|
||||
* job.c (new_job): Compare OUT to the beginning of the OUT
|
||||
var/function, not IN. Fixes Savannah bug #39035.
|
||||
|
||||
2013-05-22 Paul Smith <psmith@gnu.org>
|
||||
|
||||
* main.c (switches[]): Order switches so simple flags all come first.
|
||||
(define_makeflags): Rework to make option passing more
|
||||
reliable and the code less tricksy. Ensure simple flags are kept
|
||||
in the initial batch of flags. Do not allow any flags with
|
||||
options in that batch. If there are only non-simple flags MAKEFLAGS
|
||||
begins with ' '.
|
||||
(print_data_base): Print the version. Fixes part of Savannah #35336.
|
||||
|
||||
* read.c (eval_buffer): Initialize lineno.
|
||||
|
||||
2013-05-18 Alexey Pavlov <alexpux@gmail.com> (tiny change)
|
||||
|
||||
* w32/Makefile.am (libw32_a_SOURCES): Add compat/posixfcn.c.
|
||||
|
||||
* configure.ac (OUTPUT_SYNC): Define for mingw32 target.
|
||||
|
||||
* job.c (construct_command_argv_internal) <sh_cmds_dos>
|
||||
[WINDOWS32]: Add "move". Fixes Savannah bug #30714.
|
||||
|
||||
* guile.c: Move inclusion of makeint.h before gnumake.h. This
|
||||
order must be observed when building Make, because gnumake.h must
|
||||
be included with GMK_BUILDING_MAKE defined, which makeint.h
|
||||
already does. Otherwise, the linker will look for, and fail to
|
||||
find, gmk_* functions in some external dynamic library.
|
||||
|
||||
2013-05-17 Benno Schulenberg <bensberg@justemail.net>
|
||||
|
||||
* main.c (decode_output_sync_flags): Fix output message.
|
||||
* read.c (EXTRANEOUS): Ditto.
|
||||
(record_files): Ditto.
|
||||
* remake.c (update_file_1): Ditto.
|
||||
|
||||
2013-05-17 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* main.c (prepare_mutex_handle_string): Define conditioned on
|
||||
OUTPUT_SYNC.
|
||||
|
||||
* build_w32.bat: Copy config.h.W32 to config.h regardless of
|
||||
whether or not we are building from SCM.
|
||||
|
||||
2013-05-17 Paul Smith <psmith@gnu.org>
|
||||
|
||||
* configure.ac: Update version to 3.99.90.
|
||||
@@ -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
|
||||
|
||||
48
Makefile.am
48
Makefile.am
@@ -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 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
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
457
NEWS
457
NEWS
@@ -1,6 +1,6 @@
|
||||
GNU make NEWS -*-indented-text-*-
|
||||
History of user-visible changes.
|
||||
17 May 2013
|
||||
10 June 2016
|
||||
|
||||
See the end of this file for copyrights and conditions.
|
||||
|
||||
@@ -9,7 +9,103 @@ 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.90
|
||||
Version 4.2.1 (10 Jun 2016)
|
||||
|
||||
A complete list of bugs fixed in this version is available here:
|
||||
h
|
||||
ttp://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=107&set=custom
|
||||
|
||||
This release is a bug-fix release.
|
||||
|
||||
|
||||
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 +119,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
|
||||
@@ -34,9 +138,10 @@ http://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=101&set
|
||||
the recipe to be invoked is printed even if it would otherwise be suppressed
|
||||
by .SILENT or a "@" prefix character. Also before each recipe is run the
|
||||
makefile name and linenumber where it was defined are shown as well as the
|
||||
prerequisites that caused the target to be considered out of date. If the
|
||||
"dir" option argument is given, it will display directory enter/leave
|
||||
logging around each block of synchronized output.
|
||||
prerequisites that caused the target to be considered out of date.
|
||||
|
||||
* New command line option argument: --debug now accepts a "n" (none) flag
|
||||
which disables all debugging settings that are currently enabled.
|
||||
|
||||
* New feature: The "job server" capability is now supported on Windows.
|
||||
Implementation contributed by Troy Runkel <Troy.Runkel@mathworks.com>
|
||||
@@ -46,6 +151,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
|
||||
@@ -57,11 +164,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
|
||||
@@ -72,10 +174,24 @@ 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.
|
||||
|
||||
* On failure, the makefile name and linenumber of the recipe that failed are
|
||||
shown.
|
||||
* 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'
|
||||
when running 'make --version'.
|
||||
|
||||
* 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 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.
|
||||
|
||||
* If a recipe fails, the makefile name and linenumber of the recipe are shown.
|
||||
|
||||
* A .RECIPEPREFIX setting is remembered per-recipe and variables expanded
|
||||
in that recipe also use that recipe prefix setting.
|
||||
@@ -93,7 +209,7 @@ http://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=101&set
|
||||
behavior when the recipe uses quoted string on shell command lines.
|
||||
|
||||
|
||||
Version 3.82
|
||||
Version 3.82 (28 Jul 2010)
|
||||
|
||||
A complete list of bugs fixed in this version is available here:
|
||||
|
||||
@@ -123,15 +239,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
|
||||
@@ -205,8 +312,59 @@ 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
|
||||
Version 3.81 (01 Apr 2006)
|
||||
|
||||
* GNU make is ported to OS/2.
|
||||
|
||||
@@ -219,8 +377,8 @@ Version 3.81
|
||||
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
|
||||
@@ -329,7 +487,7 @@ Version 3.81
|
||||
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
|
||||
@@ -347,7 +505,7 @@ A complete list of bugs fixed in this version is available here:
|
||||
http://savannah.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=103
|
||||
|
||||
|
||||
Version 3.80
|
||||
Version 3.80 (03 Oct 2002)
|
||||
|
||||
* A new feature exists: order-only prerequisites. These prerequisites
|
||||
affect the order in which targets are built, but they do not impact
|
||||
@@ -424,12 +582,48 @@ Version 3.80
|
||||
|
||||
* 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
|
||||
|
||||
|
||||
Version 3.79.1
|
||||
Version 3.79.1 (23 Jun 2000)
|
||||
|
||||
* .SECONDARY with no prerequisites now prevents any target from being
|
||||
removed because make thinks it's an intermediate file, not just those
|
||||
@@ -438,7 +632,7 @@ Version 3.79.1
|
||||
* New configure option --disable-nsec-timestamps, but this was
|
||||
superseded in later versions by the .LOW_RESOLUTION_TIME pseudo-target.
|
||||
|
||||
Version 3.79
|
||||
Version 3.79 (04 Apr 2000)
|
||||
|
||||
* GNU make optionally supports internationalization and locales via the
|
||||
GNU gettext (or local gettext if suitable) package. See the ABOUT-NLS
|
||||
@@ -479,9 +673,59 @@ Version 3.79
|
||||
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
|
||||
Version 3.78 (22 Sep 1999)
|
||||
|
||||
* Two new functions, $(error ...) and $(warning ...) are available. The
|
||||
former will cause make to fail and exit immediately upon expansion of
|
||||
@@ -537,7 +781,7 @@ Version 3.78
|
||||
by running "make check" in the distribution. Note that it requires
|
||||
Perl (either Perl 4 or Perl 5) to run.
|
||||
|
||||
Version 3.77
|
||||
Version 3.77 (28 Jul 1998)
|
||||
|
||||
* Implement BSD make's "?=" variable assignment operator. The variable
|
||||
is assigned the specified value only if that variable is not already
|
||||
@@ -582,12 +826,51 @@ Version 3.77
|
||||
|
||||
* 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
|
||||
Version 3.76.1 (19 Sep 1997)
|
||||
|
||||
* Small (but serious) bug fix. Quick rollout to get into the GNU source CD.
|
||||
|
||||
Version 3.76
|
||||
Version 3.76 (16 Sep 1997)
|
||||
|
||||
* GNU make now uses automake to control Makefile.in generation. This
|
||||
should make it more consistent with the GNU standards.
|
||||
@@ -630,9 +913,55 @@ Version 3.76
|
||||
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.
|
||||
|
||||
Version 3.75
|
||||
* 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,
|
||||
are now omitted if Make runs no commands and has no other messages to print.
|
||||
@@ -652,8 +981,16 @@ Version 3.75
|
||||
* 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
|
||||
Version 3.73 (05 Apr 1995)
|
||||
|
||||
* Converted to use Autoconf version 2, so `configure' has some new options.
|
||||
See INSTALL for details.
|
||||
@@ -661,7 +998,7 @@ Version 3.73
|
||||
* You can now send a SIGUSR1 signal to Make to toggle printing of debugging
|
||||
output enabled by -d, at any time during the run.
|
||||
|
||||
Version 3.72
|
||||
Version 3.72 (04 Nov 1994)
|
||||
|
||||
* DJ Delorie has ported Make to MS-DOS using the GO32 extender.
|
||||
He is maintaining the DOS port, not the GNU Make maintainer;
|
||||
@@ -695,7 +1032,7 @@ Version 3.72
|
||||
of `.SILENT', then the recipe to update that file will not be printed
|
||||
before it is run. (This change was made to conform to POSIX.2.)
|
||||
|
||||
Version 3.71
|
||||
Version 3.71 (21 May 1994)
|
||||
|
||||
* The automatic variables `$(@D)', `$(%D)', `$(*D)', `$(<D)', `$(?D)', and
|
||||
`$(^D)' now omit the trailing slash from the directory name. (This change
|
||||
@@ -717,7 +1054,7 @@ Version 3.71
|
||||
The exit status is 1 only when using -q and some target is not up to date.
|
||||
(This change was made to comply with POSIX.2.)
|
||||
|
||||
Version 3.70
|
||||
Version 3.70 (03 Jan 1994)
|
||||
|
||||
* It is no longer a fatal error to have a NUL character in a makefile.
|
||||
You should never put a NUL in a makefile because it can have strange
|
||||
@@ -728,7 +1065,7 @@ Version 3.70
|
||||
makefile name and line number where the `include' appeared, so Emacs's
|
||||
C-x ` command takes you there (in case it's a typo you need to fix).
|
||||
|
||||
Version 3.69
|
||||
Version 3.69 (07 Nov 1993)
|
||||
|
||||
* Implicit rule search for archive member references is now done in the
|
||||
opposite order from previous versions: the whole target name `LIB(MEM)'
|
||||
@@ -747,7 +1084,7 @@ Version 3.69
|
||||
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
|
||||
@@ -758,7 +1095,7 @@ Version 3.69
|
||||
* The recipe given for `.DEFAULT' is now used for phony targets with no
|
||||
recipe.
|
||||
|
||||
Version 3.68
|
||||
Version 3.68 (28 Jul 1993)
|
||||
|
||||
* You can list several archive member names inside parenthesis:
|
||||
`lib(mem1 mem2 mem3)' is equivalent to `lib(mem1) lib(mem2) lib(mem3)'.
|
||||
@@ -770,8 +1107,8 @@ Version 3.68
|
||||
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.
|
||||
@@ -784,16 +1121,16 @@ Version 3.68
|
||||
to set up variables for them. They used to run with the environment
|
||||
that `make' started with.
|
||||
|
||||
Version 3.66
|
||||
Version 3.66 (21 May 1993)
|
||||
|
||||
* `make --version' (or `make -v') now exits immediately after printing
|
||||
the version number.
|
||||
|
||||
Version 3.65
|
||||
Version 3.65 (09 May 1993)
|
||||
|
||||
* Make now supports long-named members in `ar' archive files.
|
||||
|
||||
Version 3.64
|
||||
Version 3.64 (21 Apr 1993)
|
||||
|
||||
* Make now supports the `+=' syntax for a variable definition which appends
|
||||
to the variable's previous value. See the section `Appending More Text
|
||||
@@ -807,7 +1144,7 @@ Version 3.64
|
||||
* The built-in implicit rules now support the alternative extension
|
||||
`.txinfo' for Texinfo files, just like `.texinfo' and `.texi'.
|
||||
|
||||
Version 3.63
|
||||
Version 3.63 (22 Jan 1993)
|
||||
|
||||
* Make now uses a standard GNU `configure' script. See the new file
|
||||
INSTALL for the new (and much simpler) installation procedure.
|
||||
@@ -841,15 +1178,15 @@ Version 3.63
|
||||
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.
|
||||
|
||||
@@ -869,9 +1206,9 @@ Version 3.63
|
||||
|
||||
* 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.
|
||||
@@ -1007,7 +1344,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.
|
||||
@@ -1187,7 +1524,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
|
||||
|
||||
@@ -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,8 +89,10 @@ OBJS = \
|
||||
$(OUTDIR)/hash.obj \
|
||||
$(OUTDIR)/implicit.obj \
|
||||
$(OUTDIR)/job.obj \
|
||||
$(OUTDIR)/load.obj \
|
||||
$(OUTDIR)/main.obj \
|
||||
$(OUTDIR)/misc.obj \
|
||||
$(OUTDIR)/output.obj \
|
||||
$(OUTDIR)/read.obj \
|
||||
$(OUTDIR)/remake.obj \
|
||||
$(OUTDIR)/remote-stub.obj \
|
||||
@@ -104,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)
|
||||
@@ -120,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 $?
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
515
README.VMS
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
105
README.git
105
README.git
@@ -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
|
||||
@@ -214,25 +237,33 @@ For both final releases and pre-releases, send an email with the URL of
|
||||
the package to the GNU translation robot to allow the translators to
|
||||
work on it:
|
||||
|
||||
<translation@iro.umontreal.ca>
|
||||
<coordinator@translationproject.org>
|
||||
|
||||
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -128,7 +128,8 @@ CTAGS = ctags -w
|
||||
objs = commands.o job.o dir.o file.o misc.o main.o read.o remake.o \
|
||||
rule.o implicit.o default.o variable.o expand.o function.o \
|
||||
vpath.o version.o ar.o arscan.o signame.o strcache.o hash.o \
|
||||
remote-$(REMOTE).o $(GLOB) $(GETOPT) $(ALLOCA) $(extras) $(guile)
|
||||
output.o remote-$(REMOTE).o $(GLOB) $(GETOPT) $(ALLOCA) \
|
||||
$(extras) $(guile)
|
||||
|
||||
srcs = $(srcdir)commands.c $(srcdir)job.c $(srcdir)dir.c \
|
||||
$(srcdir)file.c $(srcdir)getloadavg.c $(srcdir)misc.c \
|
||||
@@ -141,6 +142,7 @@ srcs = $(srcdir)commands.c $(srcdir)job.c $(srcdir)dir.c \
|
||||
$(srcdir)signame.c $(srcdir)signame.h $(GETOPT_SRC) \
|
||||
$(srcdir)commands.h $(srcdir)dep.h $(srcdir)file.h \
|
||||
$(srcdir)job.h $(srcdir)makeint.h $(srcdir)rule.h \
|
||||
$(srcdir)output.c $(srcdir)output.h \
|
||||
$(srcdir)variable.h $(ALLOCA_SRC) $(srcdir)config.h.in
|
||||
|
||||
|
||||
|
||||
26
TODO.private
26
TODO.private
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
4
amiga.c
4
amiga.c
@@ -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;
|
||||
|
||||
|
||||
2
amiga.h
2
amiga.h
@@ -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
73
ar.c
@@ -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;
|
||||
|
||||
|
||||
385
arscan.c
385
arscan.c
@@ -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. */
|
||||
@@ -328,12 +408,10 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
|
||||
{
|
||||
#ifdef AIAMAG
|
||||
FL_HDR fl_header;
|
||||
#ifdef AIAMAGBIG
|
||||
# ifdef AIAMAGBIG
|
||||
int big_archive = 0;
|
||||
FL_HDR_BIG fl_header_big;
|
||||
#endif
|
||||
#else
|
||||
int long_name = 0;
|
||||
# endif
|
||||
#endif
|
||||
char *namemap = 0;
|
||||
int desc = open (archive, O_RDONLY, 0);
|
||||
@@ -342,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);
|
||||
@@ -352,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);
|
||||
@@ -364,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);
|
||||
@@ -397,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);
|
||||
@@ -461,12 +544,15 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
|
||||
char namebuf[sizeof member_header.ar_name + 1];
|
||||
char *name;
|
||||
int is_namemap; /* Nonzero if this entry maps long names. */
|
||||
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;
|
||||
@@ -478,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))
|
||||
{
|
||||
@@ -488,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)
|
||||
{
|
||||
@@ -510,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))
|
||||
{
|
||||
@@ -520,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)
|
||||
{
|
||||
@@ -548,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;
|
||||
@@ -617,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);
|
||||
@@ -688,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);
|
||||
@@ -752,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
|
||||
@@ -763,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;
|
||||
@@ -783,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;
|
||||
|
||||
@@ -792,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
|
||||
@@ -821,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
|
||||
@@ -841,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 ();
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
489
build_w32.bat
Normal file → Executable file
489
build_w32.bat
Normal file → Executable 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,286 +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
|
||||
copy config.h.W32 config.h
|
||||
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
|
||||
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 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/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 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/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 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
|
||||
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 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
|
||||
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
|
||||
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:
|
||||
@@ -302,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
|
||||
|
||||
37
commands.c
37
commands.c
@@ -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,13 +449,13 @@ 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')
|
||||
{
|
||||
/* If there are no commands, assume everything worked. */
|
||||
set_command_state (file, cs_running);
|
||||
file->update_status = 0;
|
||||
file->update_status = us_success;
|
||||
notice_finished_file (file);
|
||||
return;
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
1
config/.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
ar-lib
|
||||
compile
|
||||
config.guess
|
||||
config.rpath
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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%"
|
||||
|
||||
94
configure.ac
94
configure.ac
@@ -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.90],[bug-make@gnu.org])
|
||||
AC_INIT([GNU make],[4.2.1],[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 &&
|
||||
@@ -498,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!
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
2
debug.h
2
debug.h
@@ -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
|
||||
|
||||
175
default.c
175
default.c
@@ -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,10 +680,9 @@ set_default_suffixes (void)
|
||||
else
|
||||
{
|
||||
struct dep *d;
|
||||
char *p = default_suffixes;
|
||||
suffix_file->deps = enter_prereqs (PARSE_FILE_SEQ (&p, struct dep, '\0',
|
||||
NULL, 0),
|
||||
NULL);
|
||||
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;
|
||||
|
||||
@@ -565,7 +698,7 @@ set_default_suffixes (void)
|
||||
void
|
||||
install_default_suffix_rules (void)
|
||||
{
|
||||
char **s;
|
||||
const char **s;
|
||||
|
||||
if (no_builtin_rules_flag)
|
||||
return;
|
||||
@@ -577,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;
|
||||
|
||||
114
dep.h
114
dep.h
@@ -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,50 +37,54 @@ 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)
|
||||
#define PARSEFS_NOGLOB (0x0004)
|
||||
#define PARSEFS_EXISTS (0x0008)
|
||||
#define PARSEFS_NOCACHE (0x0010)
|
||||
#define PARSEFS_NONE 0x0000
|
||||
#define PARSEFS_NOSTRIP 0x0001
|
||||
#define PARSEFS_NOAR 0x0002
|
||||
#define PARSEFS_NOGLOB 0x0004
|
||||
#define PARSEFS_EXISTS 0x0008
|
||||
#define PARSEFS_NOCACHE 0x0010
|
||||
|
||||
#define PARSE_FILE_SEQ(_s,_t,_c,_p,_f) \
|
||||
(_t *)parse_file_seq ((_s),sizeof (_t),(_c),(_p),(_f))
|
||||
#define PARSE_SIMPLE_SEQ(_s,_t) \
|
||||
(_t *)parse_file_seq ((_s),sizeof (_t),MAP_NUL,NULL,PARSEFS_NONE)
|
||||
|
||||
#ifdef VMS
|
||||
void *parse_file_seq ();
|
||||
#else
|
||||
void *parse_file_seq (char **stringp, unsigned int size,
|
||||
int stopchar, const char *prefix, int flags);
|
||||
int stopmap, const char *prefix, int flags);
|
||||
#endif
|
||||
|
||||
char *tilde_expand (const char *name);
|
||||
@@ -77,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);
|
||||
int 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);
|
||||
|
||||
294
dir.c
294
dir.c
@@ -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,8 @@ 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
|
||||
# include <dirent.h>
|
||||
@@ -84,21 +86,21 @@ dosify (const char *filename)
|
||||
df = dos_filename;
|
||||
|
||||
/* First, transform the name part. */
|
||||
for (i = 0; *filename != '\0' && i < 8 && *filename != '.'; ++i)
|
||||
for (i = 0; i < 8 && ! STOP_SET (*filename, MAP_DOT|MAP_NUL); ++i)
|
||||
*df++ = tolower ((unsigned char)*filename++);
|
||||
|
||||
/* Now skip to the next dot. */
|
||||
while (*filename != '\0' && *filename != '.')
|
||||
while (! STOP_SET (*filename, MAP_DOT|MAP_NUL))
|
||||
++filename;
|
||||
if (*filename != '\0')
|
||||
{
|
||||
*df++ = *filename++;
|
||||
for (i = 0; *filename != '\0' && i < 3 && *filename != '.'; ++i)
|
||||
for (i = 0; i < 3 && ! STOP_SET (*filename, MAP_DOT|MAP_NUL); ++i)
|
||||
*df++ = tolower ((unsigned char)*filename++);
|
||||
}
|
||||
|
||||
/* Look for more dots. */
|
||||
while (*filename != '\0' && *filename != '.')
|
||||
while (! STOP_SET (*filename, MAP_DOT|MAP_NUL))
|
||||
++filename;
|
||||
if (*filename == '.')
|
||||
return filename;
|
||||
@@ -140,15 +142,41 @@ 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)
|
||||
{
|
||||
int h = 0;
|
||||
int g;
|
||||
|
||||
while (*name)
|
||||
{
|
||||
unsigned char uc = *name;
|
||||
int g;
|
||||
#ifdef HAVE_CASE_INSENSITIVE_FS
|
||||
h = (h << 4) + (isupper (uc) ? tolower (uc) : uc);
|
||||
#else
|
||||
@@ -198,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. */
|
||||
@@ -216,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;
|
||||
@@ -244,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]
|
||||
@@ -267,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]
|
||||
@@ -306,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;
|
||||
@@ -373,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. */
|
||||
};
|
||||
|
||||
@@ -413,25 +445,9 @@ static struct directory *find_directory (const char *name);
|
||||
static struct directory *
|
||||
find_directory (const char *name)
|
||||
{
|
||||
const char *p;
|
||||
struct directory *dir;
|
||||
struct directory **dir_slot;
|
||||
struct directory dir_key;
|
||||
int r;
|
||||
#ifdef WINDOWS32
|
||||
char* w32_path;
|
||||
char fs_label[BUFSIZ];
|
||||
char fs_type[BUFSIZ];
|
||||
unsigned long fs_serno;
|
||||
unsigned long fs_flags;
|
||||
unsigned long fs_len;
|
||||
#endif
|
||||
#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);
|
||||
@@ -439,14 +455,19 @@ find_directory (const char *name)
|
||||
|
||||
if (HASH_VACANT (dir))
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
/* The directory was not found. Create a new entry for it. */
|
||||
const char *p = name + strlen (name);
|
||||
struct stat st;
|
||||
int r;
|
||||
|
||||
p = name + strlen (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
|
||||
@@ -454,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;
|
||||
|
||||
@@ -487,6 +506,9 @@ find_directory (const char *name)
|
||||
{
|
||||
/* Search the contents hash table; device and inode are the key. */
|
||||
|
||||
#ifdef WINDOWS32
|
||||
char *w32_path;
|
||||
#endif
|
||||
struct directory_contents *dc;
|
||||
struct directory_contents **dc_slot;
|
||||
struct directory_contents dc_key;
|
||||
@@ -496,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];
|
||||
@@ -510,7 +532,13 @@ find_directory (const char *name)
|
||||
if (HASH_VACANT (dc))
|
||||
{
|
||||
/* Nope; this really is a directory we haven't seen before. */
|
||||
|
||||
#ifdef WINDOWS32
|
||||
char fs_label[BUFSIZ];
|
||||
char fs_type[BUFSIZ];
|
||||
unsigned long fs_serno;
|
||||
unsigned long fs_flags;
|
||||
unsigned long fs_len;
|
||||
#endif
|
||||
dc = (struct directory_contents *)
|
||||
xmalloc (sizeof (struct directory_contents));
|
||||
|
||||
@@ -521,11 +549,8 @@ find_directory (const char *name)
|
||||
dc->ctime = st.st_ctime;
|
||||
dc->mtime = st.st_mtime;
|
||||
|
||||
/*
|
||||
* NTFS is the only WINDOWS32 filesystem that bumps mtime
|
||||
* on a directory when files are added/deleted from
|
||||
* a directory.
|
||||
*/
|
||||
/* NTFS is the only WINDOWS32 filesystem that bumps mtime on a
|
||||
directory when files are added/deleted from a directory. */
|
||||
w32_path[3] = '\0';
|
||||
if (GetVolumeInformation (w32_path, fs_label, sizeof (fs_label),
|
||||
&fs_serno, &fs_len, &fs_flags, fs_type,
|
||||
@@ -538,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];
|
||||
@@ -603,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;
|
||||
@@ -675,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)
|
||||
@@ -704,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
|
||||
@@ -735,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);
|
||||
}
|
||||
@@ -753,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. */
|
||||
{
|
||||
@@ -775,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)
|
||||
@@ -797,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'.
|
||||
@@ -812,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, '\\');
|
||||
@@ -831,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;
|
||||
@@ -860,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)
|
||||
@@ -879,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);
|
||||
@@ -893,17 +956,25 @@ int
|
||||
file_impossible_p (const char *filename)
|
||||
{
|
||||
const char *dirend;
|
||||
const char *p = 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. */
|
||||
{
|
||||
@@ -918,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;
|
||||
@@ -938,12 +1008,19 @@ file_impossible_p (const char *filename)
|
||||
dirend++;
|
||||
#endif
|
||||
cp = alloca (dirend - filename + 1);
|
||||
memcpy (cp, p, dirend - p);
|
||||
cp[dirend - p] = '\0';
|
||||
memcpy (cp, filename, dirend - filename);
|
||||
cp[dirend - filename] = '\0';
|
||||
dirname = cp;
|
||||
}
|
||||
dir = find_directory (dirname)->contents;
|
||||
p = filename = slash + 1;
|
||||
#ifdef VMS
|
||||
if (*slash == '/')
|
||||
filename = slash + 1;
|
||||
else
|
||||
filename = slash;
|
||||
#else
|
||||
filename = slash + 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (dir == 0 || dir->dirfiles.ht_vec == 0)
|
||||
@@ -951,13 +1028,14 @@ file_impossible_p (const char *filename)
|
||||
return 0;
|
||||
|
||||
#ifdef __MSDOS__
|
||||
filename = dosify (p);
|
||||
filename = dosify (filename);
|
||||
#endif
|
||||
#ifdef HAVE_CASE_INSENSITIVE_FS
|
||||
filename = downcase (p);
|
||||
filename = downcase (filename);
|
||||
#endif
|
||||
#ifdef VMS
|
||||
filename = vmsify (p, 1);
|
||||
if (want_vmsify)
|
||||
filename = vmsify (filename, 1);
|
||||
#endif
|
||||
|
||||
dirfile_key.name = filename;
|
||||
@@ -1004,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 %I64u): 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],
|
||||
@@ -1040,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 %I64u): "),
|
||||
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],
|
||||
@@ -1089,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
|
||||
@@ -1174,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.
|
||||
@@ -1188,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
|
||||
@@ -1226,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
2
doc/.gitignore
vendored
@@ -1,3 +1,5 @@
|
||||
manual/
|
||||
gendocs_template
|
||||
fdl.texi
|
||||
make-stds.texi
|
||||
stamp-vti
|
||||
|
||||
@@ -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
|
||||
|
||||
625
doc/make.texi
625
doc/make.texi
@@ -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
|
||||
@@ -4130,6 +4135,11 @@ Additionally, if there are multiple recursive @code{make} invocations
|
||||
running in parallel, they will communicate so that only one of them is
|
||||
generating output at a time.
|
||||
|
||||
If working directory printing is enabled (@pxref{-w Option, ,The
|
||||
@samp{--print-directory} Option}), the enter/leave messages are
|
||||
printed around each output grouping. If you prefer not to see these
|
||||
messages add the @samp{--no-print-directory} option to @code{MAKEFLAGS}.
|
||||
|
||||
There are four levels of granularity when synchronizing output,
|
||||
specified by giving an argument to the option (e.g., @samp{-Oline} or
|
||||
@samp{--output-sync=recurse}).
|
||||
@@ -4196,12 +4206,12 @@ completed.
|
||||
Some programs invoked by @code{make} may behave differently if they
|
||||
determine they're writing output to a terminal versus a file (often
|
||||
described as ``interactive'' vs. ``non-interactive'' modes). For
|
||||
example, many programs that can display colorized output often will
|
||||
not do so if they determine they are not displaying on a terminal. If
|
||||
your makefile invokes a program like this then using the output
|
||||
example, many programs that can display colorized output will not do
|
||||
so if they determine they are not writing to a terminal. If your
|
||||
makefile invokes a program like this then using the output
|
||||
synchronization options will cause the program to believe it's running
|
||||
in ``non-interactive'' mode even when it's ultimately writing to the
|
||||
terminal.
|
||||
in ``non-interactive'' mode even though the output will ultimately go
|
||||
to the terminal.
|
||||
|
||||
@node Parallel Input, , Parallel Output, Parallel
|
||||
@subsection Input During Parallel Execution
|
||||
@@ -4711,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
|
||||
@@ -4803,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
|
||||
@@ -4965,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
|
||||
@@ -5611,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,
|
||||
|
||||
@@ -5664,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.
|
||||
@@ -5689,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
|
||||
@@ -5797,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}
|
||||
@@ -6316,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
|
||||
@@ -6609,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
|
||||
@@ -7493,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
|
||||
@@ -7544,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
|
||||
@@ -7996,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
|
||||
@@ -8590,6 +8645,10 @@ By default, the above messages are not enabled while trying to remake
|
||||
the makefiles. This option enables messages while rebuilding makefiles,
|
||||
too. Note that the @samp{all} option does enable this option. This
|
||||
option also enables @samp{basic} messages.
|
||||
|
||||
@item n (@i{none})
|
||||
Disable all debugging currently enabled. If additional debugging
|
||||
flags are encountered after this they will still take effect.
|
||||
@end table
|
||||
|
||||
@item -e
|
||||
@@ -8708,22 +8767,6 @@ prerequisites, and do not remake anything on account of changes in
|
||||
are ignored. @xref{Avoiding Compilation, ,Avoiding Recompilation of
|
||||
Some Files}.@refill
|
||||
|
||||
@item -p
|
||||
@cindex @code{-p}
|
||||
@itemx --print-data-base
|
||||
@cindex @code{--print-data-base}
|
||||
@cindex data base of @code{make} rules
|
||||
@cindex predefined rules and variables, printing
|
||||
Print the data base (rules and variable values) that results from
|
||||
reading the makefiles; then execute as usual or as otherwise
|
||||
specified. This also prints the version information given by the
|
||||
@samp{-v} switch (see below). To print the data base without trying
|
||||
to remake any files, use @w{@samp{make -qp}}. To print the data base
|
||||
of predefined rules and variables, use @w{@samp{make -p -f /dev/null}}.
|
||||
The data base output contains file name and line number information for
|
||||
recipe and variable definitions, so it can be a useful debugging tool
|
||||
in complex environments.
|
||||
|
||||
@item -O[@var{type}]
|
||||
@cindex @code{-O}
|
||||
@itemx --output-sync[=@var{type}]
|
||||
@@ -8743,6 +8786,22 @@ from each line in the recipe is grouped together. With the type
|
||||
together. With the type @samp{none}, no output synchronization is
|
||||
performed. @xref{Parallel Output, ,Output During Parallel Execution}.
|
||||
|
||||
@item -p
|
||||
@cindex @code{-p}
|
||||
@itemx --print-data-base
|
||||
@cindex @code{--print-data-base}
|
||||
@cindex data base of @code{make} rules
|
||||
@cindex predefined rules and variables, printing
|
||||
Print the data base (rules and variable values) that results from
|
||||
reading the makefiles; then execute as usual or as otherwise
|
||||
specified. This also prints the version information given by the
|
||||
@samp{-v} switch (see below). To print the data base without trying
|
||||
to remake any files, use @w{@samp{make -qp}}. To print the data base
|
||||
of predefined rules and variables, use @w{@samp{make -p -f /dev/null}}.
|
||||
The data base output contains file name and line number information for
|
||||
recipe and variable definitions, so it can be a useful debugging tool
|
||||
in complex environments.
|
||||
|
||||
@item -q
|
||||
@cindex @code{-q}
|
||||
@itemx --question
|
||||
@@ -8814,17 +8873,13 @@ instead of running their recipes. This is used to pretend that the
|
||||
recipes were done, in order to fool future invocations of
|
||||
@code{make}. @xref{Instead of Execution, ,Instead of Executing Recipes}.
|
||||
|
||||
@item --trace[=@var{mode}]
|
||||
@item --trace
|
||||
@cindex @code{--trace}
|
||||
Show tracing information for @code{make} execution. With no mode or
|
||||
the type @samp{rule}, print the entire recipe to be executed, even for
|
||||
recipes that are normally silent (due to @code{.SILENT} or @samp{@@}).
|
||||
Also print the makefile name and line number where the recipe was
|
||||
defined, and information on why the target is being rebuilt. With the
|
||||
type @samp{dir}, directory enter/leave lines are shown around each
|
||||
synchronized output segment. These modes are cumulative and can be
|
||||
set with multiple instances of the @code{--trace} flag. With the type
|
||||
@samp{none}, all tracing is disabled.
|
||||
Show tracing information for @code{make} execution. Prints the entire
|
||||
recipe to be executed, even for recipes that are normally silent (due
|
||||
to @code{.SILENT} or @samp{@@}). Also prints the makefile name and
|
||||
line number where the recipe was defined, and information on why the
|
||||
target is being rebuilt.
|
||||
|
||||
@item -v
|
||||
@cindex @code{-v}
|
||||
@@ -8922,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.
|
||||
@@ -8974,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
|
||||
@@ -9004,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
|
||||
@@ -9012,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
|
||||
|
||||
@@ -10662,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
|
||||
|
||||
@@ -10905,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
|
||||
|
||||
@@ -10973,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:
|
||||
|
||||
@@ -11100,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
|
||||
@@ -11125,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
|
||||
@@ -11169,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
|
||||
@@ -11278,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
|
||||
@@ -11387,6 +11685,11 @@ The concept of doing several things at once (parallelism) exists in
|
||||
many incarnations of @code{make} and similar programs, though not in the
|
||||
System V or BSD implementations. @xref{Execution, ,Recipe Execution}.
|
||||
|
||||
@item
|
||||
A number of different build tools that support parallelism also
|
||||
support collecting output and displaying as a single block.
|
||||
@xref{Parallel Output, ,Output During Parallel Execution}.
|
||||
|
||||
@item
|
||||
Modified variable references using pattern substitution come from
|
||||
SunOS 4. @xref{Reference, ,Basics of Variable References}.
|
||||
@@ -11530,12 +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}.
|
||||
|
||||
@item
|
||||
The built-in variable @samp{MAKE_VERSION} gives the version number of
|
||||
@code{make}.
|
||||
@vindex MAKE_VERSION
|
||||
@xref{Catalogue of Rules, ,Catalogue of Built-In Rules}.
|
||||
|
||||
@item
|
||||
Load dynamic objects which can modify the behavior of @code{make}.
|
||||
@@ -11658,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.
|
||||
|
||||
@@ -11883,6 +12181,11 @@ Evaluate @var{text} then read the results as makefile commands.
|
||||
Expands to the empty string.@*
|
||||
@xref{Eval Function, ,The @code{eval} Function}.
|
||||
|
||||
@item $(file @var{op} @var{filename},@var{text})
|
||||
Expand the arguments, then open the file @var{filename} using mode
|
||||
@var{op} and write @var{text} to that file.@*
|
||||
@xref{File Function, ,The @code{file} Function}.
|
||||
|
||||
@item $(value @var{var})
|
||||
Evaluates to the contents of the variable @var{var}, with no expansion
|
||||
performed on it.@*
|
||||
@@ -11982,6 +12285,18 @@ The name with which @code{make} was invoked. Using this variable in
|
||||
recipes has special meaning. @xref{MAKE Variable, ,How the
|
||||
@code{MAKE} Variable Works}.
|
||||
|
||||
@item MAKE_VERSION
|
||||
|
||||
The built-in variable @samp{MAKE_VERSION} expands to the version
|
||||
number of the GNU @code{make} program.
|
||||
@vindex MAKE_VERSION
|
||||
|
||||
@item MAKE_HOST
|
||||
|
||||
The built-in variable @samp{MAKE_HOST} expands to a string
|
||||
representing the host that GNU @code{make} was built to run on.
|
||||
@vindex MAKE_HOST
|
||||
|
||||
@item MAKELEVEL
|
||||
|
||||
The number of levels of recursion (sub-@code{make}s).@*
|
||||
@@ -12007,6 +12322,7 @@ you'd like to set GNU @code{make}-specific flags in a POSIX-compliant
|
||||
makefile. This variable will be seen by GNU @code{make} and ignored
|
||||
by other @code{make} implementations. It's not needed if you only use
|
||||
GNU @code{make}; just use @code{MAKEFLAGS} directly.
|
||||
@xref{Options/Recursion, ,Communicating Options to a Sub-@code{make}}.
|
||||
|
||||
@item MAKECMDGOALS
|
||||
|
||||
@@ -12016,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
|
||||
@@ -12151,12 +12467,15 @@ of its arguments. @xref{Functions, ,Functions for Transforming Text}.
|
||||
@itemx multiple target patterns. Stop.
|
||||
@itemx target pattern contains no `%'. Stop.
|
||||
@itemx mixed implicit and static pattern rules. Stop.
|
||||
These are generated for malformed static pattern rules. The first means
|
||||
there's no pattern in the target section of the rule; the second means
|
||||
there are multiple patterns in the target section; the third means
|
||||
the target doesn't contain a pattern character (@code{%}); and the
|
||||
fourth means that all three parts of the static pattern rule contain
|
||||
pattern characters (@code{%})--only the first two parts should.
|
||||
These are generated for malformed static pattern rules. The first
|
||||
means there's no pattern in the target section of the rule; the second
|
||||
means there are multiple patterns in the target section; the third
|
||||
means the target doesn't contain a pattern character (@code{%}); and
|
||||
the fourth means that all three parts of the static pattern rule
|
||||
contain pattern characters (@code{%})--only the first two parts
|
||||
should. If you see these errors and you aren't trying to create a
|
||||
static pattern rule, check the value of any variables in your target
|
||||
and prerequisite lists to be sure they do not contain colons.
|
||||
@xref{Static Usage, ,Syntax of Static Pattern Rules}.
|
||||
|
||||
@item warning: -jN forced in submake: disabling jobserver mode.
|
||||
|
||||
@@ -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
|
||||
@@ -20,6 +20,7 @@ echo Building Make for MSDOS
|
||||
rem Echo ON so they will see what is going on.
|
||||
@echo on
|
||||
gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g commands.c -o commands.o
|
||||
gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g output.c -o output.o
|
||||
gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g job.c -o job.o
|
||||
gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g dir.c -o dir.o
|
||||
gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g file.c -o file.o
|
||||
@@ -51,7 +52,7 @@ ar rv libglob.a glob.o fnmatch.o
|
||||
@echo off
|
||||
cd ..
|
||||
echo commands.o > respf.$$$
|
||||
for %%f in (job dir file misc main read remake rule implicit default variable) do echo %%f.o >> respf.$$$
|
||||
for %%f in (job output dir file misc main read remake rule implicit default variable) do echo %%f.o >> respf.$$$
|
||||
for %%f in (expand function vpath hash strcache version ar arscan signame remote-stub getopt getopt1) do echo %%f.o >> respf.$$$
|
||||
echo glob/libglob.a >> respf.$$$
|
||||
rem gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g guile.c -o guile.o
|
||||
|
||||
43
expand.c
43
expand.c
@@ -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)
|
||||
{
|
||||
@@ -304,10 +306,8 @@ variable_expand_string (char *line, const char *string, long length)
|
||||
if (colon)
|
||||
{
|
||||
/* This looks like a substitution reference: $(FOO:A=B). */
|
||||
const char *subst_beg, *subst_end, *replace_beg, *replace_end;
|
||||
|
||||
subst_beg = colon + 1;
|
||||
subst_end = lindex (subst_beg, end, '=');
|
||||
const char *subst_beg = colon + 1;
|
||||
const char *subst_end = lindex (subst_beg, end, '=');
|
||||
if (subst_end == 0)
|
||||
/* There is no = in sight. Punt on the substitution
|
||||
reference and treat this as a variable name containing
|
||||
@@ -315,8 +315,8 @@ variable_expand_string (char *line, const char *string, long length)
|
||||
colon = 0;
|
||||
else
|
||||
{
|
||||
replace_beg = subst_end + 1;
|
||||
replace_end = end;
|
||||
const char *replace_beg = subst_end + 1;
|
||||
const char *replace_end = end;
|
||||
|
||||
/* Extract the variable name before the colon
|
||||
and look up that variable. */
|
||||
@@ -379,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:
|
||||
@@ -449,8 +445,7 @@ expand_argument (const char *str, const char *end)
|
||||
|
||||
r = allocated_variable_expand (tmp);
|
||||
|
||||
if (alloc)
|
||||
free (alloc);
|
||||
free (alloc);
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -463,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);
|
||||
|
||||
90
file.c
90
file.c
@@ -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)
|
||||
@@ -153,7 +160,7 @@ enter_file (const char *name)
|
||||
struct file file_key;
|
||||
|
||||
assert (*name != '\0');
|
||||
assert (strcache_iscached (name));
|
||||
assert (! verify_flag || strcache_iscached (name));
|
||||
|
||||
#if defined(VMS) && !defined(WANT_CASE_SENSITIVE_TARGETS)
|
||||
if (*name != '.')
|
||||
@@ -184,7 +191,7 @@ enter_file (const char *name)
|
||||
|
||||
new = xcalloc (sizeof (struct file));
|
||||
new->name = new->hname = name;
|
||||
new->update_status = -1;
|
||||
new->update_status = us_none;
|
||||
|
||||
if (HASH_VACANT (f))
|
||||
{
|
||||
@@ -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;
|
||||
}
|
||||
@@ -378,7 +389,7 @@ remove_intermediates (int sig)
|
||||
&& !f->secondary && !f->cmd_target)
|
||||
{
|
||||
int status;
|
||||
if (f->update_status == -1)
|
||||
if (f->update_status == us_none)
|
||||
/* If nothing would have created this file yet,
|
||||
don't print an "rm" command for it. */
|
||||
continue;
|
||||
@@ -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)
|
||||
@@ -430,7 +442,8 @@ remove_intermediates (int sig)
|
||||
struct dep *
|
||||
split_prereqs (char *p)
|
||||
{
|
||||
struct dep *new = PARSE_FILE_SEQ (&p, struct dep, '|', NULL, 0);
|
||||
struct dep *new = PARSE_FILE_SEQ (&p, struct dep, MAP_PIPE, NULL,
|
||||
PARSEFS_NONE);
|
||||
|
||||
if (*p)
|
||||
{
|
||||
@@ -439,7 +452,7 @@ split_prereqs (char *p)
|
||||
struct dep *ood;
|
||||
|
||||
++p;
|
||||
ood = PARSE_FILE_SEQ (&p, struct dep, '\0', NULL, 0);
|
||||
ood = PARSE_SIMPLE_SEQ (&p, struct dep);
|
||||
|
||||
if (! new)
|
||||
new = ood;
|
||||
@@ -802,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;
|
||||
@@ -1000,23 +1014,18 @@ print_file (const void *item)
|
||||
case cs_finished:
|
||||
switch (f->update_status)
|
||||
{
|
||||
case -1:
|
||||
case us_none:
|
||||
break;
|
||||
case 0:
|
||||
case us_success:
|
||||
puts (_("# Successfully updated."));
|
||||
break;
|
||||
case 1:
|
||||
case us_question:
|
||||
assert (question_flag);
|
||||
puts (_("# Needs to be updated (-q is set)."));
|
||||
break;
|
||||
case 2:
|
||||
case us_failed:
|
||||
puts (_("# Failed to be updated."));
|
||||
break;
|
||||
default:
|
||||
puts (_("# Invalid value in 'update_status' member!"));
|
||||
fflush (stdout);
|
||||
fflush (stderr);
|
||||
abort ();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -1050,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\n", _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
|
||||
|
||||
26
filedef.h
26
filedef.h
@@ -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
|
||||
@@ -58,12 +58,19 @@ struct file
|
||||
FILE_TIMESTAMP last_mtime; /* File's modtime, if already known. */
|
||||
FILE_TIMESTAMP mtime_before_update; /* File's modtime before any updating
|
||||
has been performed. */
|
||||
unsigned int considered; /* equal to 'considered' if file has been
|
||||
considered on current scan of goal chain */
|
||||
int command_flags; /* Flags OR'd in for cmds; see commands.h. */
|
||||
char update_status; /* Status of the last attempt to update,
|
||||
or -1 if none has been made. */
|
||||
enum update_status /* Status of the last attempt to update. */
|
||||
{
|
||||
us_success = 0, /* Successfully updated. Must be 0! */
|
||||
us_none, /* No attempt to update has been made. */
|
||||
us_question, /* Needs to be updated (-q is is set). */
|
||||
us_failed /* Update failed. */
|
||||
} update_status ENUM_BITFIELD (2);
|
||||
enum cmd_state /* State of the commands. */
|
||||
{ /* Note: It is important that cs_not_started be zero. */
|
||||
cs_not_started, /* Not yet started. */
|
||||
{
|
||||
cs_not_started = 0, /* Not yet started. Must be 0! */
|
||||
cs_deps_running, /* Dep commands running. */
|
||||
cs_running, /* Commands running. */
|
||||
cs_finished /* Commands finished. */
|
||||
@@ -91,14 +98,12 @@ struct file
|
||||
unsigned int ignore_vpath:1;/* Nonzero if we threw out VPATH name. */
|
||||
unsigned int pat_searched:1;/* Nonzero if we already searched for
|
||||
pattern-specific variables. */
|
||||
unsigned int considered:1; /* equal to 'considered' if file has been
|
||||
considered on current scan of goal chain */
|
||||
unsigned int no_diag:1; /* True if the file failed to update and no
|
||||
diagnostics has been issued (dontcare). */
|
||||
};
|
||||
|
||||
|
||||
extern struct file *suffix_file, *default_file;
|
||||
extern struct file *default_file;
|
||||
|
||||
|
||||
struct file *lookup_file (const char *name);
|
||||
@@ -112,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) \
|
||||
@@ -138,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;
|
||||
|
||||
589
function.c
589
function.c
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
2
getopt.c
2
getopt.c
@@ -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.
|
||||
|
||||
2
getopt.h
2
getopt.h
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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, '{');
|
||||
|
||||
@@ -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
|
||||
|
||||
30
gnumake.h
30
gnumake.h
@@ -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_ */
|
||||
|
||||
52
guile.c
52
guile.c
@@ -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
|
||||
@@ -14,15 +14,29 @@ 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"
|
||||
|
||||
#ifdef HAVE_GUILE
|
||||
|
||||
#include "gnumake.h"
|
||||
|
||||
#include "makeint.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
2
hash.c
@@ -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 */
|
||||
|
||||
107
implicit.c
107
implicit.c
@@ -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++);
|
||||
@@ -217,8 +216,8 @@ pattern_search (struct file *file, int archive,
|
||||
struct file *int_file = 0;
|
||||
|
||||
/* List of dependencies found recursively. */
|
||||
struct patdeps *deplist
|
||||
= xmalloc (max_pattern_deps * sizeof (struct patdeps));
|
||||
unsigned int max_deps = max_pattern_deps;
|
||||
struct patdeps *deplist = xmalloc (max_deps * sizeof (struct patdeps));
|
||||
struct patdeps *pat = deplist;
|
||||
|
||||
/* Names of possible dependencies are constructed in this buffer. */
|
||||
@@ -249,8 +248,6 @@ pattern_search (struct file *file, int archive,
|
||||
that is not just '%'. */
|
||||
int specific_rule_matched = 0;
|
||||
|
||||
struct dep dep_simple;
|
||||
|
||||
unsigned int ri; /* uninit checks OK */
|
||||
struct rule *rule;
|
||||
|
||||
@@ -268,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". */
|
||||
@@ -284,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;
|
||||
@@ -317,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
|
||||
@@ -341,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)
|
||||
@@ -352,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)
|
||||
@@ -439,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;
|
||||
@@ -532,11 +530,9 @@ pattern_search (struct file *file, int archive,
|
||||
/* If we don't need a second expansion, just replace the %. */
|
||||
if (! dep->need_2nd_expansion)
|
||||
{
|
||||
dep_simple = *dep;
|
||||
dep_simple.next = 0;
|
||||
p = strchr (nptr, '%');
|
||||
if (p == 0)
|
||||
dep_simple.name = nptr;
|
||||
strcpy (depname, nptr);
|
||||
else
|
||||
{
|
||||
char *o = depname;
|
||||
@@ -550,13 +546,19 @@ pattern_search (struct file *file, int archive,
|
||||
memcpy (o, stem_str, stemlen);
|
||||
o += stemlen;
|
||||
strcpy (o, p + 1);
|
||||
dep_simple.name = strcache_add (depname);
|
||||
}
|
||||
dl = &dep_simple;
|
||||
|
||||
/* Parse the expanded string. It might have wildcards. */
|
||||
p = depname;
|
||||
dl = PARSE_SIMPLE_SEQ (&p, struct dep);
|
||||
for (d = dl; d != NULL; d = d->next)
|
||||
{
|
||||
++deps_found;
|
||||
d->ignore_mtime = dep->ignore_mtime;
|
||||
}
|
||||
|
||||
/* We've used up this dep, so next time get a new one. */
|
||||
nptr = 0;
|
||||
++deps_found;
|
||||
}
|
||||
|
||||
/* We have to perform second expansion on this prereq. In an
|
||||
@@ -572,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)
|
||||
@@ -614,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)
|
||||
@@ -632,32 +638,47 @@ 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 ? '\0' : '|',
|
||||
add_dir ? dir : NULL, 0);
|
||||
|
||||
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
|
||||
2nd expansion), reset it and realloc the arrays. */
|
||||
|
||||
if (deps_found > max_pattern_deps)
|
||||
if (deps_found > max_deps)
|
||||
{
|
||||
unsigned int l = pat - deplist;
|
||||
/* This might have changed due to recursion. */
|
||||
max_pattern_deps = MAX(max_pattern_deps, deps_found);
|
||||
max_deps = max_pattern_deps;
|
||||
deplist = xrealloc (deplist,
|
||||
deps_found * sizeof (struct patdeps));
|
||||
max_deps * sizeof (struct patdeps));
|
||||
pat = deplist + l;
|
||||
max_pattern_deps = deps_found;
|
||||
}
|
||||
|
||||
/* Go through the nameseq and handle each as a prereq name. */
|
||||
@@ -757,8 +778,8 @@ pattern_search (struct file *file, int archive,
|
||||
pat->pattern = int_file->name;
|
||||
int_file->name = d->name;
|
||||
pat->file = int_file;
|
||||
(pat++)->name = d->name;
|
||||
int_file = 0;
|
||||
(pat++)->name = d->name;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -779,8 +800,7 @@ pattern_search (struct file *file, int archive,
|
||||
}
|
||||
|
||||
/* Free the ns chain. */
|
||||
if (dl != &dep_simple)
|
||||
free_dep_chain (dl);
|
||||
free_dep_chain (dl);
|
||||
|
||||
if (failed)
|
||||
break;
|
||||
@@ -843,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);
|
||||
|
||||
|
||||
54
job.h
54
job.h
@@ -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
|
||||
@@ -14,8 +14,7 @@ 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/>. */
|
||||
|
||||
#ifndef SEEN_JOB_H
|
||||
#define SEEN_JOB_H
|
||||
#include "output.h"
|
||||
|
||||
#ifdef HAVE_FCNTL_H
|
||||
# include <fcntl.h>
|
||||
@@ -25,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
|
||||
@@ -38,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
|
||||
@@ -70,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 */
|
||||
@@ -78,7 +80,7 @@ typedef int sync_handle_t; /* file descriptor */
|
||||
# define RECORD_SYNC_MUTEX(m) (void)(m)
|
||||
|
||||
# endif
|
||||
#endif /* OUTPUT_SYNC */
|
||||
#endif /* !NO_OUTPUT_SYNC */
|
||||
|
||||
/* Structure describing a running or dead child process. */
|
||||
|
||||
@@ -97,21 +99,24 @@ 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. */
|
||||
int outfd; /* File descriptor for saving stdout */
|
||||
int errfd; /* File descriptor for saving stderr */
|
||||
pid_t pid; /* Child process's ID number. */
|
||||
unsigned int remote:1; /* Nonzero if executing remotely. */
|
||||
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 dontcare:1; /* Saved dontcare flag. */
|
||||
unsigned int command_line; /* Index into command_lines. */
|
||||
struct output output; /* Output for this child. */
|
||||
pid_t pid; /* Child process's ID number. */
|
||||
unsigned int remote:1; /* Nonzero if executing remotely. */
|
||||
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);
|
||||
@@ -119,19 +124,22 @@ 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);
|
||||
void exec_command (char **argv) __attribute__ ((noreturn));
|
||||
#elif defined(__EMX__)
|
||||
int exec_command (char **argv, char **envp);
|
||||
#else
|
||||
void exec_command (char **argv, char **envp);
|
||||
void exec_command (char **argv, char **envp) __attribute__ ((noreturn));
|
||||
#endif
|
||||
|
||||
extern unsigned int job_slots_used;
|
||||
@@ -149,5 +157,3 @@ extern int fatal_signal_mask;
|
||||
#endif
|
||||
|
||||
extern unsigned int jobserver_tokens;
|
||||
|
||||
#endif /* SEEN_JOB_H */
|
||||
|
||||
72
load.c
72
load.c
@@ -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,19 +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;
|
||||
}
|
||||
|
||||
int
|
||||
unload_file (struct file *file)
|
||||
void
|
||||
unload_file (const char *name UNUSED)
|
||||
{
|
||||
fatal (flocp, "INTERNAL: Cannot unload when load is not supported!");
|
||||
return 0;
|
||||
O (fatal, NILF, "INTERNAL: Cannot unload when load is not supported!");
|
||||
}
|
||||
|
||||
#endif /* MAKE_LOAD */
|
||||
|
||||
36
loadapi.c
36
loadapi.c
@@ -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);
|
||||
}
|
||||
|
||||
167
maintMakefile
167
maintMakefile
@@ -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
|
||||
RSYNC = rsync -Lrtvz
|
||||
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,17 +163,18 @@ 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)
|
||||
po_sync = translationproject.org::tp/latest/$(PACKAGE)/
|
||||
|
||||
.PHONY: do-po-update po-update
|
||||
do-po-update:
|
||||
tmppo="/tmp/po-$(PACKAGE)-$(VERSION).$$$$" \
|
||||
&& rm -rf "$$tmppo" \
|
||||
&& mkdir "$$tmppo" \
|
||||
&& (cd "$$tmppo" \
|
||||
&& $(WGET) $(po_wget_flags) -A '*.po' $(po_repo)) \
|
||||
&& cp "$$tmppo"/*.po $(top_srcdir)/po && rm -rf "$$tmppo"
|
||||
&& $(RSYNC) $(po_sync) "$$tmppo" \
|
||||
&& cp "$$tmppo"/*.po $(top_srcdir)/po \
|
||||
&& rm -rf "$$tmppo"
|
||||
cd po && $(MAKE) update-po
|
||||
$(MAKE) po-check
|
||||
|
||||
@@ -184,10 +223,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 +284,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 +353,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 +390,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
|
||||
|
||||
30
make.1
30
make.1
@@ -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
|
||||
@@ -143,7 +143,9 @@ for showing implicit rules,
|
||||
.I j
|
||||
for details on invocation of commands, and
|
||||
.I m
|
||||
for debugging while remaking makefiles.
|
||||
for debugging while remaking makefiles. Use
|
||||
.I n
|
||||
to disable all previous debugging flags.
|
||||
.TP 0.5i
|
||||
\fB\-e\fR, \fB\-\-environment\-overrides\fR
|
||||
Give variables taken from the environment precedence
|
||||
@@ -289,25 +291,9 @@ This is used to pretend that the commands were done, in order to fool
|
||||
future invocations of
|
||||
.BR make .
|
||||
.TP 0.5i
|
||||
.B \-\-trace\fR[=\fImode\fR]
|
||||
Print information about the commands invoked by
|
||||
.BR make .
|
||||
If
|
||||
.I mode
|
||||
is not specified or is
|
||||
.B rule
|
||||
information about the disposition of each target is printed. If
|
||||
.I mode
|
||||
is
|
||||
.B dir
|
||||
then directory enter/leave trace statements are shown for each synchronized
|
||||
output segment (see
|
||||
.BR \-O ).
|
||||
If
|
||||
.I mode
|
||||
is
|
||||
.B none
|
||||
then no tracing is performed.
|
||||
.B \-\-trace
|
||||
Information about the disposition of each target is printed (why the target is
|
||||
being rebuilt and what commands are run to rebuild it).
|
||||
.TP 0.5i
|
||||
\fB\-v\fR, \fB\-\-version\fR
|
||||
Print the version of the
|
||||
@@ -377,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
|
||||
|
||||
2
make.lnk
2
make.lnk
@@ -1,4 +1,4 @@
|
||||
FROM LIB:cres.o "commands.o"+"job.o"+"dir.o"+"file.o"+"misc.o"+"main.o"+"read.o"+"remake.o"+"rule.o"+"implicit.o"+"default.o"+"variable.o"+"expand.o"+"function.o"+"vpath.o"+"version.o"+"ar.o"+"arscan.o"+"signame.o"+"remote-stub.o"+"getopt.o"+"getopt1.o"+"alloca.o"+"amiga.o"+"hash.o"+"strcache.o"
|
||||
FROM LIB:cres.o "commands.o"+"job.o"+"dir.o"+"file.o"+"misc.o"+"main.o"+"read.o"+"remake.o"+"rule.o"+"implicit.o"+"default.o"+"variable.o"+"expand.o"+"function.o"+"vpath.o"+"version.o"+"ar.o"+"arscan.o"+"signame.o"+"remote-stub.o"+"getopt.o"+"getopt1.o"+"alloca.o"+"amiga.o"+"hash.o"+"strcache.o"+"output.o"
|
||||
TO "make.new"
|
||||
LIB glob/glob.lib LIB:sc.lib LIB:amiga.lib
|
||||
QUIET
|
||||
|
||||
@@ -154,11 +154,11 @@
|
||||
<File
|
||||
RelativePath=".\getopt1.c">
|
||||
</File>
|
||||
<!--
|
||||
|
||||
<File
|
||||
RelativePath=".\guile.c">
|
||||
</File>
|
||||
-->
|
||||
|
||||
<File
|
||||
RelativePath=".\hash.c">
|
||||
</File>
|
||||
@@ -171,6 +171,12 @@
|
||||
<File
|
||||
RelativePath=".\job.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\load.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\output.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\main.c">
|
||||
</File>
|
||||
@@ -207,6 +213,9 @@
|
||||
<File
|
||||
RelativePath=".\w32\compat\dirent.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\w32\compat\posixfcn.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\w32\subproc\misc.c">
|
||||
<FileConfiguration
|
||||
@@ -225,6 +234,9 @@
|
||||
<File
|
||||
RelativePath=".\w32\pathstuff.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\w32\w32os.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\w32\subproc\sub_proc.c">
|
||||
</File>
|
||||
@@ -277,6 +289,9 @@
|
||||
<File
|
||||
RelativePath=".\job.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\output.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\makeint.h">
|
||||
</File>
|
||||
|
||||
43
makefile.com
43
makefile.com
@@ -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 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
|
||||
|
||||
113
makefile.vms
113
makefile.vms
@@ -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
|
||||
@@ -20,7 +20,7 @@
|
||||
# Klaus Kämpf (kkaempf@rmi.de)
|
||||
# Modified for version 3.78.1 by Hartmut.Becker@compaq.com.
|
||||
# Modified for version 3.80 by zinser@decus.de
|
||||
# Modified for version 3.81 by Hartmut Becker
|
||||
# Modified for versions 3.81, 3.99.90 by Hartmut Becker
|
||||
|
||||
CC = cc
|
||||
CP = copy
|
||||
@@ -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,19 +91,20 @@ mandir = []
|
||||
# Number to put on the man page filename.
|
||||
manext = 1
|
||||
|
||||
#guile = ,guile.obj
|
||||
guile = ,guile.obj
|
||||
|
||||
objs = commands.obj,job.obj,dir.obj,file.obj,misc.obj,hash.obj,\
|
||||
main.obj,read.obj,remake.obj,rule.obj,implicit.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 dir.c file.c misc.c guile.c hash.c \
|
||||
main.c read.c remake.c rule.c implicit.c \
|
||||
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) \
|
||||
commands.h dep.h filedef.h job.h make.h rule.h variable.h
|
||||
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
|
||||
|
||||
|
||||
.PHONY: all doc
|
||||
@@ -114,40 +118,63 @@ make.exe: $(objs)
|
||||
|
||||
.PHONY: clean realclean
|
||||
clean:
|
||||
$$ purge [...]
|
||||
-purge [...]
|
||||
-$(RM) make.exe;,*.obj;
|
||||
-$(RM) [.glob]*.obj;
|
||||
|
||||
# Automatically generated dependencies.
|
||||
commands.obj: commands.c make.h dep.h commands.h filedef.h variable.h job.h
|
||||
job.obj: job.c vmsjobs.c make.h commands.h job.h filedef.h variable.h
|
||||
dir.obj: dir.c make.h
|
||||
file.obj: file.c make.h commands.h dep.h filedef.h variable.h
|
||||
misc.obj: misc.c make.h dep.h
|
||||
hash.obj: hash.c make.h hash.h
|
||||
strcache.obj: strcache.c make.h hash.h
|
||||
main.obj: main.c make.h commands.h dep.h filedef.h variable.h job.h
|
||||
guile.obj: guile.c make.h debug.h dep.h gmk-default.h
|
||||
read.obj: read.c make.h commands.h dep.h filedef.h variable.h
|
||||
remake.obj: remake.c make.h commands.h job.h dep.h filedef.h
|
||||
rule.obj: rule.c make.h commands.h dep.h filedef.h variable.h rule.h
|
||||
implicit.obj: implicit.c make.h rule.h dep.h filedef.h
|
||||
default.obj: default.c make.h rule.h dep.h filedef.h commands.h variable.h
|
||||
variable.obj: variable.c make.h commands.h variable.h dep.h filedef.h
|
||||
expand.obj: expand.c make.h commands.h filedef.h variable.h
|
||||
function.obj: function.c make.h variable.h dep.h commands.h job.h
|
||||
vpath.obj: vpath.c make.h filedef.h variable.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
|
||||
arscan.obj: arscan.c
|
||||
ar.obj: ar.c make.h filedef.h
|
||||
signame.obj: signame.c
|
||||
remote-stub.obj: remote-stub.c
|
||||
[.glob]glob.obj: [.glob]glob.c
|
||||
[.glob]fnmatch.obj: [.glob]fnmatch.c
|
||||
getopt.obj: getopt.c
|
||||
getopt1.obj: getopt1.c
|
||||
vmsfunctions.obj: vmsfunctions.c make.h vmsdir.h
|
||||
vmsify.obj: vmsify.c make.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 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) $< $@
|
||||
|
||||
286
makeint.h
286
makeint.h
@@ -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
|
||||
@@ -197,12 +203,20 @@ unsigned int get_path_max (void);
|
||||
#endif
|
||||
|
||||
#ifdef VMS
|
||||
# include <fcntl.h>
|
||||
# include <types.h>
|
||||
# include <unixlib.h>
|
||||
# include <unixio.h>
|
||||
# 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__
|
||||
@@ -327,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>
|
||||
@@ -352,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. */
|
||||
@@ -363,7 +362,6 @@ char *strsignal (int signum);
|
||||
|
||||
void sync_Path_environment (void);
|
||||
int w32_kill (pid_t pid, int sig);
|
||||
char *end_of_token_w32 (const char *s, char stopchar);
|
||||
int find_and_set_default_shell (const char *token);
|
||||
|
||||
/* indicates whether or not we have Bourne shell */
|
||||
@@ -378,9 +376,72 @@ 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)
|
||||
#define NONE_SET(_v,_m) (! ANY_SET ((_v),(_m)))
|
||||
|
||||
#define MAP_NUL 0x0001
|
||||
#define MAP_BLANK 0x0002
|
||||
#define MAP_NEWLINE 0x0004
|
||||
#define MAP_COMMENT 0x0008
|
||||
#define MAP_SEMI 0x0010
|
||||
#define MAP_EQUALS 0x0020
|
||||
#define MAP_COLON 0x0040
|
||||
#define MAP_PERCENT 0x0080
|
||||
#define MAP_PIPE 0x0100
|
||||
#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 directory separators is OS-specific. */
|
||||
#define MAP_DIRSEP 0x8000
|
||||
|
||||
#ifdef VMS
|
||||
# define MAP_VMSCOMMA MAP_COMMA
|
||||
#else
|
||||
# define MAP_VMSCOMMA 0x0000
|
||||
#endif
|
||||
|
||||
#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
|
||||
#endif
|
||||
@@ -389,28 +450,61 @@ 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, ...);
|
||||
const char *message_s (unsigned int length, int prefix, const char *fmt, ...)
|
||||
void message (int prefix, size_t length, const char *fmt, ...)
|
||||
__attribute__ ((__format__ (__printf__, 3, 4)));
|
||||
const char *error_s (unsigned int length, const gmk_floc *flocp, const char *fmt, ...)
|
||||
__attribute__ ((__format__ (__printf__, 3, 4)));
|
||||
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 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 log_working_directory (int, int);
|
||||
void pfatal_with_name (const char *) __attribute__ ((noreturn));
|
||||
void perror_with_name (const char *, const char *);
|
||||
#define xstrlen(_s) ((_s)==NULL ? 0 : strlen (_s))
|
||||
void *xmalloc (unsigned int);
|
||||
void *xcalloc (unsigned int);
|
||||
void *xrealloc (void *, unsigned int);
|
||||
@@ -425,8 +519,6 @@ int alpha_compare (const void *, const void *);
|
||||
void print_spaces (unsigned int);
|
||||
char *find_percent (char *);
|
||||
const char *find_percent_cached (const char **);
|
||||
int open_tmpfd (void);
|
||||
FILE *open_tmpfile (char **, const char *);
|
||||
|
||||
#ifndef NO_ARCHIVES
|
||||
int ar_name (const char *);
|
||||
@@ -437,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);
|
||||
@@ -451,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);
|
||||
@@ -471,26 +566,23 @@ void user_access (void);
|
||||
void make_access (void);
|
||||
void child_access (void);
|
||||
|
||||
void close_stdout (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,
|
||||
@@ -503,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
|
||||
@@ -536,31 +628,28 @@ 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
|
||||
|
||||
#define TRACE_NONE 0x0
|
||||
#define TRACE_RULE 0x1
|
||||
#define TRACE_DIRECTORY 0x2
|
||||
|
||||
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;
|
||||
extern int print_data_base_flag, question_flag, touch_flag, always_make_flag;
|
||||
extern int env_overrides, no_builtin_rules_flag, no_builtin_variables_flag;
|
||||
extern int print_version_flag, print_directory_flag, check_symlink_flag;
|
||||
extern int warn_undefined_variables_flag, trace_flag, posix_pedantic;
|
||||
extern int not_parallel, second_expansion, clock_skew_detected;
|
||||
extern int rebuilding_makefiles, one_shell, output_sync;
|
||||
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;
|
||||
@@ -571,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;
|
||||
@@ -596,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. */
|
||||
|
||||
|
||||
391
misc.c
391
misc.c
@@ -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"
|
||||
|
||||
@@ -22,6 +23,11 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef HAVE_FCNTL_H
|
||||
# include <fcntl.h>
|
||||
#else
|
||||
# include <sys/file.h>
|
||||
#endif
|
||||
|
||||
/* Compare strings *S1 and *S2.
|
||||
Return negative if the first is less, positive if it is greater,
|
||||
@@ -45,9 +51,7 @@ alpha_compare (const void *v1, const void *v2)
|
||||
void
|
||||
collapse_continuations (char *line)
|
||||
{
|
||||
register char *in, *out, *p;
|
||||
register int backslash;
|
||||
register unsigned int bs_write;
|
||||
char *in, *out, *p;
|
||||
|
||||
in = strchr (line, '\n');
|
||||
if (in == 0)
|
||||
@@ -62,8 +66,8 @@ collapse_continuations (char *line)
|
||||
/* BS_WRITE gets the number of quoted backslashes at
|
||||
the end just before IN, and BACKSLASH gets nonzero
|
||||
if the next character is quoted. */
|
||||
backslash = 0;
|
||||
bs_write = 0;
|
||||
unsigned int backslash = 0;
|
||||
unsigned int bs_write = 0;
|
||||
for (p = in - 1; p >= line && *p == '\\'; --p)
|
||||
{
|
||||
if (backslash)
|
||||
@@ -87,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++ = ' ';
|
||||
}
|
||||
@@ -149,7 +154,7 @@ concat (unsigned int num, ...)
|
||||
while (num-- > 0)
|
||||
{
|
||||
const char *s = va_arg (args, const char *);
|
||||
unsigned int l = s ? strlen (s) : 0;
|
||||
unsigned int l = xstrlen (s);
|
||||
|
||||
if (l == 0)
|
||||
continue;
|
||||
@@ -180,163 +185,8 @@ concat (unsigned int num, ...)
|
||||
}
|
||||
|
||||
|
||||
/* Return a formatted string buffer.
|
||||
LENGTH must be the maximum length of all format arguments, stringified.
|
||||
If we had a standard-compliant vsnprintf() this would be a lot simpler.
|
||||
Maybe in the future we'll include gnulib's version. */
|
||||
|
||||
const char *
|
||||
message_s (unsigned int length, int prefix, const char *fmt, ...)
|
||||
{
|
||||
static char *buffer = NULL;
|
||||
static unsigned int bsize = 0;
|
||||
char *bp;
|
||||
va_list args;
|
||||
|
||||
/* Compute the maximum buffer size we'll need, and make sure we have it. */
|
||||
length += strlen (fmt) + strlen (program) + 4 + INTEGER_LENGTH + 2;
|
||||
if (length > bsize)
|
||||
{
|
||||
bsize = length * 2;
|
||||
buffer = xrealloc (buffer, bsize);
|
||||
}
|
||||
|
||||
bp = buffer;
|
||||
if (prefix)
|
||||
{
|
||||
if (makelevel == 0)
|
||||
sprintf (bp, "%s: ", program);
|
||||
else
|
||||
sprintf (bp, "%s[%u]: ", program, makelevel);
|
||||
bp += strlen (buffer);
|
||||
}
|
||||
|
||||
va_start (args, fmt);
|
||||
vsprintf (bp, fmt, args);
|
||||
va_end (args);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/* Return a formatted error message in a buffer.
|
||||
LENGTH must be the maximum length of all format arguments, stringified. */
|
||||
|
||||
const char *
|
||||
error_s (unsigned int length, const gmk_floc *flocp, const char *fmt, ...)
|
||||
{
|
||||
static char *buffer = NULL;
|
||||
static unsigned int bsize = 0;
|
||||
char *bp;
|
||||
va_list args;
|
||||
|
||||
/* Compute the maximum buffer size we'll need, and make sure we have it. */
|
||||
length += (strlen (fmt) + strlen (program) + 4 + INTEGER_LENGTH + 2
|
||||
+ (flocp && flocp->filenm ? strlen (flocp->filenm) : 0));
|
||||
if (length > bsize)
|
||||
{
|
||||
bsize = length * 2;
|
||||
buffer = xrealloc (buffer, bsize);
|
||||
}
|
||||
|
||||
bp = buffer;
|
||||
if (flocp && flocp->filenm)
|
||||
sprintf (bp, "%s:%lu: ", flocp->filenm, flocp->lineno);
|
||||
else if (makelevel == 0)
|
||||
sprintf (bp, "%s: ", program);
|
||||
else
|
||||
sprintf (bp, "%s[%u]: ", program, makelevel);
|
||||
bp += strlen (bp);
|
||||
|
||||
va_start (args, fmt);
|
||||
vsprintf (bp, fmt, args);
|
||||
va_end (args);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/* Print a message on stdout. We could use message_s() to format it but then
|
||||
we'd need a va_list version... */
|
||||
|
||||
void
|
||||
message (int prefix, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
log_working_directory (1, 0);
|
||||
|
||||
if (fmt != 0)
|
||||
{
|
||||
if (prefix)
|
||||
{
|
||||
if (makelevel == 0)
|
||||
printf ("%s: ", program);
|
||||
else
|
||||
printf ("%s[%u]: ", program, makelevel);
|
||||
}
|
||||
va_start (args, fmt);
|
||||
vfprintf (stdout, fmt, args);
|
||||
va_end (args);
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
fflush (stdout);
|
||||
}
|
||||
|
||||
/* Print an error message. */
|
||||
|
||||
void
|
||||
error (const gmk_floc *flocp, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
log_working_directory (1, 0);
|
||||
|
||||
if (flocp && flocp->filenm)
|
||||
fprintf (stderr, "%s:%lu: ", flocp->filenm, flocp->lineno);
|
||||
else if (makelevel == 0)
|
||||
fprintf (stderr, "%s: ", program);
|
||||
else
|
||||
fprintf (stderr, "%s[%u]: ", program, makelevel);
|
||||
|
||||
va_start (args, fmt);
|
||||
vfprintf (stderr, fmt, args);
|
||||
va_end (args);
|
||||
|
||||
putc ('\n', stderr);
|
||||
fflush (stderr);
|
||||
}
|
||||
|
||||
/* Print an error message and exit. */
|
||||
|
||||
void
|
||||
fatal (const gmk_floc *flocp, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
log_working_directory (1, 0);
|
||||
|
||||
if (flocp && flocp->filenm)
|
||||
fprintf (stderr, "%s:%lu: *** ", flocp->filenm, flocp->lineno);
|
||||
else if (makelevel == 0)
|
||||
fprintf (stderr, "%s: *** ", program);
|
||||
else
|
||||
fprintf (stderr, "%s[%u]: *** ", program, makelevel);
|
||||
|
||||
va_start (args, fmt);
|
||||
vfprintf (stderr, fmt, args);
|
||||
va_end (args);
|
||||
|
||||
fputs (_(". Stop.\n"), stderr);
|
||||
|
||||
log_working_directory (0, 1);
|
||||
|
||||
die (2);
|
||||
}
|
||||
|
||||
#ifndef HAVE_STRERROR
|
||||
|
||||
#undef strerror
|
||||
|
||||
char *
|
||||
strerror (int errnum)
|
||||
{
|
||||
@@ -353,24 +203,6 @@ strerror (int errnum)
|
||||
return buf;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Print an error message from errno. */
|
||||
|
||||
void
|
||||
perror_with_name (const char *str, const char *name)
|
||||
{
|
||||
error (NILF, _("%s%s: %s"), str, name, strerror (errno));
|
||||
}
|
||||
|
||||
/* Print an error message from errno and exit. */
|
||||
|
||||
void
|
||||
pfatal_with_name (const char *name)
|
||||
{
|
||||
fatal (NILF, _("%s: %s"), name, strerror (errno));
|
||||
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/* Like malloc but get fatal error if memory is exhausted. */
|
||||
/* Don't bother if we're using dmalloc; it provides these for us. */
|
||||
@@ -388,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;
|
||||
}
|
||||
|
||||
@@ -399,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;
|
||||
}
|
||||
|
||||
@@ -414,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;
|
||||
}
|
||||
|
||||
@@ -431,7 +263,7 @@ xstrdup (const char *ptr)
|
||||
#endif
|
||||
|
||||
if (result == 0)
|
||||
fatal (NILF, _("virtual memory exhausted"));
|
||||
OUT_OF_MEM();
|
||||
|
||||
#ifdef HAVE_STRDUP
|
||||
return result;
|
||||
@@ -450,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)
|
||||
@@ -483,48 +315,16 @@ lindex (const char *s, const char *limit, int c)
|
||||
char *
|
||||
end_of_token (const char *s)
|
||||
{
|
||||
while (*s != '\0' && !isblank ((unsigned char)*s))
|
||||
++s;
|
||||
END_OF_TOKEN (s);
|
||||
return (char *)s;
|
||||
}
|
||||
|
||||
#ifdef WINDOWS32
|
||||
/*
|
||||
* Same as end_of_token, but take into account a stop character
|
||||
*/
|
||||
char *
|
||||
end_of_token_w32 (const char *s, char stopchar)
|
||||
{
|
||||
const char *p = s;
|
||||
int backslash = 0;
|
||||
|
||||
while (*p != '\0' && *p != stopchar
|
||||
&& (backslash || !isblank ((unsigned char)*p)))
|
||||
{
|
||||
if (*p++ == '\\')
|
||||
{
|
||||
backslash = !backslash;
|
||||
while (*p == '\\')
|
||||
{
|
||||
backslash = !backslash;
|
||||
++p;
|
||||
}
|
||||
}
|
||||
else
|
||||
backslash = 0;
|
||||
}
|
||||
|
||||
return (char *)p;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Return the address of the first nonwhitespace or null in the string S. */
|
||||
|
||||
char *
|
||||
next_token (const char *s)
|
||||
{
|
||||
while (isblank ((unsigned char)*s))
|
||||
++s;
|
||||
NEXT_TOKEN (s);
|
||||
return (char *)s;
|
||||
}
|
||||
|
||||
@@ -576,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. */
|
||||
|
||||
@@ -599,13 +386,12 @@ free_ns_chain (struct nameseq *ns)
|
||||
{
|
||||
struct nameseq *t = ns;
|
||||
ns = ns->next;
|
||||
free (t);
|
||||
free_ns (t);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if !HAVE_STRCASECMP && !HAVE_STRICMP && !HAVE_STRCMPI
|
||||
|
||||
/* If we don't have strcasecmp() (from POSIX), or anything that can substitute
|
||||
for it, define our own version. */
|
||||
|
||||
@@ -631,7 +417,6 @@ strcasecmp (const char *s1, const char *s2)
|
||||
#endif
|
||||
|
||||
#if !HAVE_STRNCASECMP && !HAVE_STRNICMP && !HAVE_STRNCMPI
|
||||
|
||||
/* If we don't have strncasecmp() (from POSIX), or anything that can
|
||||
substitute for it, define our own version. */
|
||||
|
||||
@@ -906,7 +691,7 @@ child_access (void)
|
||||
|
||||
#endif /* GETLOADAVG_PRIVILEGED */
|
||||
}
|
||||
|
||||
|
||||
#ifdef NEED_GET_PATH_MAX
|
||||
unsigned int
|
||||
get_path_max (void)
|
||||
@@ -925,129 +710,3 @@ get_path_max (void)
|
||||
return value;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Provide support for temporary files. */
|
||||
|
||||
#ifndef HAVE_STDLIB_H
|
||||
# ifdef HAVE_MKSTEMP
|
||||
int mkstemp (char *template);
|
||||
# else
|
||||
char *mktemp (char *template);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* This is only used by output-sync, and it may not be portable. */
|
||||
#ifdef OUTPUT_SYNC
|
||||
|
||||
/* Returns a file descriptor to a temporary file. The file is automatically
|
||||
closed/deleted on exit. Don't use a FILE* stream. */
|
||||
int
|
||||
open_tmpfd ()
|
||||
{
|
||||
int fd = -1;
|
||||
FILE *tfile = tmpfile ();
|
||||
|
||||
if (! tfile)
|
||||
pfatal_with_name ("tmpfile");
|
||||
|
||||
/* Create a duplicate so we can close the stream. */
|
||||
fd = dup (fileno (tfile));
|
||||
if (fd < 0)
|
||||
pfatal_with_name ("dup");
|
||||
|
||||
fclose (tfile);
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
FILE *
|
||||
open_tmpfile (char **name, const char *template)
|
||||
{
|
||||
#ifdef HAVE_FDOPEN
|
||||
int fd;
|
||||
#endif
|
||||
|
||||
#if defined HAVE_MKSTEMP || defined HAVE_MKTEMP
|
||||
# define TEMPLATE_LEN strlen (template)
|
||||
#else
|
||||
# define TEMPLATE_LEN L_tmpnam
|
||||
#endif
|
||||
*name = xmalloc (TEMPLATE_LEN + 1);
|
||||
strcpy (*name, template);
|
||||
|
||||
#if defined HAVE_MKSTEMP && defined HAVE_FDOPEN
|
||||
/* It's safest to use mkstemp(), if we can. */
|
||||
fd = mkstemp (*name);
|
||||
if (fd == -1)
|
||||
return 0;
|
||||
return fdopen (fd, "w");
|
||||
#else
|
||||
# ifdef HAVE_MKTEMP
|
||||
(void) mktemp (*name);
|
||||
# else
|
||||
(void) tmpnam (*name);
|
||||
# endif
|
||||
|
||||
# ifdef HAVE_FDOPEN
|
||||
/* Can't use mkstemp(), but guard against a race condition. */
|
||||
fd = open (*name, O_CREAT|O_EXCL|O_WRONLY, 0600);
|
||||
if (fd == -1)
|
||||
return 0;
|
||||
return fdopen (fd, "w");
|
||||
# else
|
||||
/* Not secure, but what can we do? */
|
||||
return fopen (*name, "w");
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* This code is stolen from gnulib.
|
||||
If/when we abandon the requirement to work with K&R compilers, we can
|
||||
remove this (and perhaps other parts of GNU make!) and migrate to using
|
||||
gnulib directly.
|
||||
|
||||
This is called only through atexit(), which means die() has already been
|
||||
invoked. So, call exit() here directly. Apparently that works...?
|
||||
*/
|
||||
|
||||
/* Close standard output, exiting with status 'exit_failure' on failure.
|
||||
If a program writes *anything* to stdout, that program should close
|
||||
stdout and make sure that it succeeds before exiting. Otherwise,
|
||||
suppose that you go to the extreme of checking the return status
|
||||
of every function that does an explicit write to stdout. The last
|
||||
printf can succeed in writing to the internal stream buffer, and yet
|
||||
the fclose(stdout) could still fail (due e.g., to a disk full error)
|
||||
when it tries to write out that buffered data. Thus, you would be
|
||||
left with an incomplete output file and the offending program would
|
||||
exit successfully. Even calling fflush is not always sufficient,
|
||||
since some file systems (NFS and CODA) buffer written/flushed data
|
||||
until an actual close call.
|
||||
|
||||
Besides, it's wasteful to check the return value from every call
|
||||
that writes to stdout -- just let the internal stream state record
|
||||
the failure. That's what the ferror test is checking below.
|
||||
|
||||
It's important to detect such failures and exit nonzero because many
|
||||
tools (most notably 'make' and other build-management systems) depend
|
||||
on being able to detect failure in other tools via their exit status. */
|
||||
|
||||
void
|
||||
close_stdout (void)
|
||||
{
|
||||
int prev_fail = ferror (stdout);
|
||||
int fclose_fail = fclose (stdout);
|
||||
|
||||
if (prev_fail || fclose_fail)
|
||||
{
|
||||
if (fclose_fail)
|
||||
error (NILF, _("write error: %s"), strerror (errno));
|
||||
else
|
||||
error (NILF, _("write error"));
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
84
os.h
Normal file
84
os.h
Normal 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
|
||||
723
output.c
Normal file
723
output.c
Normal file
@@ -0,0 +1,723 @@
|
||||
/* Output to stdout / stderr for GNU make
|
||||
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
|
||||
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 "job.h"
|
||||
|
||||
/* GNU make no longer supports pre-ANSI89 environments. */
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FCNTL_H
|
||||
# include <fcntl.h>
|
||||
#else
|
||||
# include <sys/file.h>
|
||||
#endif
|
||||
|
||||
#ifdef WINDOWS32
|
||||
# include <windows.h>
|
||||
# include <io.h>
|
||||
# include "sub_proc.h"
|
||||
#endif /* WINDOWS32 */
|
||||
|
||||
struct output *output_context = NULL;
|
||||
unsigned int stdio_traced = 0;
|
||||
|
||||
#define OUTPUT_NONE (-1)
|
||||
|
||||
#define OUTPUT_ISSET(_out) ((_out)->out >= 0 || (_out)->err >= 0)
|
||||
|
||||
#ifdef HAVE_FCNTL_H
|
||||
# define STREAM_OK(_s) ((fcntl (fileno (_s), F_GETFD) != -1) || (errno != EBADF))
|
||||
#else
|
||||
# define STREAM_OK(_s) 1
|
||||
#endif
|
||||
|
||||
/* Write a string to the current STDOUT or STDERR. */
|
||||
static void
|
||||
_outputs (struct output *out, int is_err, const char *msg)
|
||||
{
|
||||
if (! out || ! out->syncout)
|
||||
{
|
||||
FILE *f = is_err ? stderr : stdout;
|
||||
fputs (msg, f);
|
||||
fflush (f);
|
||||
}
|
||||
else
|
||||
{
|
||||
int fd = is_err ? out->err : out->out;
|
||||
int len = strlen (msg);
|
||||
int r;
|
||||
|
||||
EINTRLOOP (r, lseek (fd, 0, SEEK_END));
|
||||
while (1)
|
||||
{
|
||||
EINTRLOOP (r, write (fd, msg, len));
|
||||
if (r == len || r <= 0)
|
||||
break;
|
||||
len -= r;
|
||||
msg += r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Write a message indicating that we've just entered or
|
||||
left (according to ENTERING) the current directory. */
|
||||
|
||||
static int
|
||||
log_working_directory (int entering)
|
||||
{
|
||||
static char *buf = NULL;
|
||||
static unsigned int len = 0;
|
||||
unsigned int need;
|
||||
const char *fmt;
|
||||
char *p;
|
||||
|
||||
/* Get enough space for the longest possible output. */
|
||||
need = strlen (program) + INTSTR_LENGTH + 2 + 1;
|
||||
if (starting_directory)
|
||||
need += strlen (starting_directory);
|
||||
|
||||
/* Use entire sentences to give the translators a fighting chance. */
|
||||
if (makelevel == 0)
|
||||
if (starting_directory == 0)
|
||||
if (entering)
|
||||
fmt = _("%s: Entering an unknown directory\n");
|
||||
else
|
||||
fmt = _("%s: Leaving an unknown directory\n");
|
||||
else
|
||||
if (entering)
|
||||
fmt = _("%s: Entering directory '%s'\n");
|
||||
else
|
||||
fmt = _("%s: Leaving directory '%s'\n");
|
||||
else
|
||||
if (starting_directory == 0)
|
||||
if (entering)
|
||||
fmt = _("%s[%u]: Entering an unknown directory\n");
|
||||
else
|
||||
fmt = _("%s[%u]: Leaving an unknown directory\n");
|
||||
else
|
||||
if (entering)
|
||||
fmt = _("%s[%u]: Entering directory '%s'\n");
|
||||
else
|
||||
fmt = _("%s[%u]: Leaving directory '%s'\n");
|
||||
|
||||
need += strlen (fmt);
|
||||
|
||||
if (need > len)
|
||||
{
|
||||
buf = xrealloc (buf, need);
|
||||
len = need;
|
||||
}
|
||||
|
||||
p = buf;
|
||||
if (print_data_base_flag)
|
||||
{
|
||||
*(p++) = '#';
|
||||
*(p++) = ' ';
|
||||
}
|
||||
|
||||
if (makelevel == 0)
|
||||
if (starting_directory == 0)
|
||||
sprintf (p, fmt , program);
|
||||
else
|
||||
sprintf (p, fmt, program, starting_directory);
|
||||
else if (starting_directory == 0)
|
||||
sprintf (p, fmt, program, makelevel);
|
||||
else
|
||||
sprintf (p, fmt, program, makelevel, starting_directory);
|
||||
|
||||
_outputs (NULL, 0, buf);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Set a file descriptor to be in O_APPEND mode.
|
||||
If it fails, just ignore it. */
|
||||
|
||||
static void
|
||||
set_append_mode (int fd)
|
||||
{
|
||||
#if defined(F_GETFL) && defined(F_SETFL) && defined(O_APPEND)
|
||||
int flags = fcntl (fd, F_GETFL, 0);
|
||||
if (flags >= 0)
|
||||
fcntl (fd, F_SETFL, flags | O_APPEND);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifndef NO_OUTPUT_SYNC
|
||||
|
||||
/* Semaphore for use in -j mode with output_sync. */
|
||||
static sync_handle_t sync_handle = -1;
|
||||
|
||||
#define FD_NOT_EMPTY(_f) ((_f) != OUTPUT_NONE && lseek ((_f), 0, SEEK_END) > 0)
|
||||
|
||||
/* Set up the sync handle. Disables output_sync on error. */
|
||||
static int
|
||||
sync_init (void)
|
||||
{
|
||||
int combined_output = 0;
|
||||
|
||||
#ifdef WINDOWS32
|
||||
if ((!STREAM_OK (stdout) && !STREAM_OK (stderr))
|
||||
|| (sync_handle = create_mutex ()) == -1)
|
||||
{
|
||||
perror_with_name ("output-sync suppressed: ", "stderr");
|
||||
output_sync = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
combined_output = same_stream (stdout, stderr);
|
||||
prepare_mutex_handle_string (sync_handle);
|
||||
}
|
||||
|
||||
#else
|
||||
if (STREAM_OK (stdout))
|
||||
{
|
||||
struct stat stbuf_o, stbuf_e;
|
||||
|
||||
sync_handle = fileno (stdout);
|
||||
combined_output = (fstat (fileno (stdout), &stbuf_o) == 0
|
||||
&& fstat (fileno (stderr), &stbuf_e) == 0
|
||||
&& stbuf_o.st_dev == stbuf_e.st_dev
|
||||
&& stbuf_o.st_ino == stbuf_e.st_ino);
|
||||
}
|
||||
else if (STREAM_OK (stderr))
|
||||
sync_handle = fileno (stderr);
|
||||
else
|
||||
{
|
||||
perror_with_name ("output-sync suppressed: ", "stderr");
|
||||
output_sync = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return combined_output;
|
||||
}
|
||||
|
||||
/* Support routine for output_sync() */
|
||||
static void
|
||||
pump_from_tmp (int from, FILE *to)
|
||||
{
|
||||
static char buffer[8192];
|
||||
|
||||
#ifdef WINDOWS32
|
||||
int prev_mode;
|
||||
|
||||
/* "from" is opened by open_tmpfd, which does it in binary mode, so
|
||||
we need the mode of "to" to match that. */
|
||||
prev_mode = _setmode (fileno (to), _O_BINARY);
|
||||
#endif
|
||||
|
||||
if (lseek (from, 0, SEEK_SET) == -1)
|
||||
perror ("lseek()");
|
||||
|
||||
while (1)
|
||||
{
|
||||
int len;
|
||||
EINTRLOOP (len, read (from, buffer, sizeof (buffer)));
|
||||
if (len < 0)
|
||||
perror ("read()");
|
||||
if (len <= 0)
|
||||
break;
|
||||
if (fwrite (buffer, len, 1, to) < 1)
|
||||
{
|
||||
perror ("fwrite()");
|
||||
break;
|
||||
}
|
||||
fflush (to);
|
||||
}
|
||||
|
||||
#ifdef WINDOWS32
|
||||
/* Switch "to" back to its original mode, so that log messages by
|
||||
Make have the same EOL format as without --output-sync. */
|
||||
_setmode (fileno (to), prev_mode);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Obtain the lock for writing output. */
|
||||
static void *
|
||||
acquire_semaphore (void)
|
||||
{
|
||||
static struct flock fl;
|
||||
|
||||
fl.l_type = F_WRLCK;
|
||||
fl.l_whence = SEEK_SET;
|
||||
fl.l_start = 0;
|
||||
fl.l_len = 1;
|
||||
if (fcntl (sync_handle, F_SETLKW, &fl) != -1)
|
||||
return &fl;
|
||||
perror ("fcntl()");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Release the lock for writing output. */
|
||||
static void
|
||||
release_semaphore (void *sem)
|
||||
{
|
||||
struct flock *flp = (struct flock *)sem;
|
||||
flp->l_type = F_UNLCK;
|
||||
if (fcntl (sync_handle, F_SETLKW, flp) == -1)
|
||||
perror ("fcntl()");
|
||||
}
|
||||
|
||||
/* Returns a file descriptor to a temporary file. The file is automatically
|
||||
closed/deleted on exit. Don't use a FILE* stream. */
|
||||
int
|
||||
output_tmpfd (void)
|
||||
{
|
||||
int fd = -1;
|
||||
FILE *tfile = tmpfile ();
|
||||
|
||||
if (! tfile)
|
||||
pfatal_with_name ("tmpfile");
|
||||
|
||||
/* Create a duplicate so we can close the stream. */
|
||||
fd = dup (fileno (tfile));
|
||||
if (fd < 0)
|
||||
pfatal_with_name ("dup");
|
||||
|
||||
fclose (tfile);
|
||||
|
||||
set_append_mode (fd);
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
/* Adds file descriptors to the child structure to support output_sync; one
|
||||
for stdout and one for stderr as long as they are open. If stdout and
|
||||
stderr share a device they can share a temp file too.
|
||||
Will reset output_sync on error. */
|
||||
static void
|
||||
setup_tmpfile (struct output *out)
|
||||
{
|
||||
/* Is make's stdout going to the same place as stderr? */
|
||||
static int combined_output = -1;
|
||||
|
||||
if (combined_output < 0)
|
||||
combined_output = sync_init ();
|
||||
|
||||
if (STREAM_OK (stdout))
|
||||
{
|
||||
int fd = output_tmpfd ();
|
||||
if (fd < 0)
|
||||
goto error;
|
||||
CLOSE_ON_EXEC (fd);
|
||||
out->out = fd;
|
||||
}
|
||||
|
||||
if (STREAM_OK (stderr))
|
||||
{
|
||||
if (out->out != OUTPUT_NONE && combined_output)
|
||||
out->err = out->out;
|
||||
else
|
||||
{
|
||||
int fd = output_tmpfd ();
|
||||
if (fd < 0)
|
||||
goto error;
|
||||
CLOSE_ON_EXEC (fd);
|
||||
out->err = fd;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
/* If we failed to create a temp file, disable output sync going forward. */
|
||||
error:
|
||||
output_close (out);
|
||||
output_sync = OUTPUT_SYNC_NONE;
|
||||
}
|
||||
|
||||
/* Synchronize the output of jobs in -j mode to keep the results of
|
||||
each job together. This is done by holding the results in temp files,
|
||||
one for stdout and potentially another for stderr, and only releasing
|
||||
them to "real" stdout/stderr when a semaphore can be obtained. */
|
||||
|
||||
void
|
||||
output_dump (struct output *out)
|
||||
{
|
||||
int outfd_not_empty = FD_NOT_EMPTY (out->out);
|
||||
int errfd_not_empty = FD_NOT_EMPTY (out->err);
|
||||
|
||||
if (outfd_not_empty || errfd_not_empty)
|
||||
{
|
||||
int traced = 0;
|
||||
|
||||
/* Try to acquire the semaphore. If it fails, dump the output
|
||||
unsynchronized; still better than silently discarding it.
|
||||
We want to keep this lock for as little time as possible. */
|
||||
void *sem = acquire_semaphore ();
|
||||
|
||||
/* Log the working directory for this dump. */
|
||||
if (print_directory_flag && output_sync != OUTPUT_SYNC_RECURSE)
|
||||
traced = log_working_directory (1);
|
||||
|
||||
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 (0);
|
||||
|
||||
/* Exit the critical section. */
|
||||
if (sem)
|
||||
release_semaphore (sem);
|
||||
|
||||
/* Truncate and reset the output, in case we use it again. */
|
||||
if (out->out != OUTPUT_NONE)
|
||||
{
|
||||
int e;
|
||||
lseek (out->out, 0, SEEK_SET);
|
||||
EINTRLOOP (e, ftruncate (out->out, 0));
|
||||
}
|
||||
if (out->err != OUTPUT_NONE && out->err != out->out)
|
||||
{
|
||||
int e;
|
||||
lseek (out->err, 0, SEEK_SET);
|
||||
EINTRLOOP (e, ftruncate (out->err, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* NO_OUTPUT_SYNC */
|
||||
|
||||
|
||||
/* Provide support for temporary files. */
|
||||
|
||||
#ifndef HAVE_STDLIB_H
|
||||
# ifdef HAVE_MKSTEMP
|
||||
int mkstemp (char *template);
|
||||
# else
|
||||
char *mktemp (char *template);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
FILE *
|
||||
output_tmpfile (char **name, const char *template)
|
||||
{
|
||||
#ifdef HAVE_FDOPEN
|
||||
int fd;
|
||||
#endif
|
||||
|
||||
#if defined HAVE_MKSTEMP || defined HAVE_MKTEMP
|
||||
# define TEMPLATE_LEN strlen (template)
|
||||
#else
|
||||
# define TEMPLATE_LEN L_tmpnam
|
||||
#endif
|
||||
*name = xmalloc (TEMPLATE_LEN + 1);
|
||||
strcpy (*name, template);
|
||||
|
||||
#if defined HAVE_MKSTEMP && defined HAVE_FDOPEN
|
||||
/* It's safest to use mkstemp(), if we can. */
|
||||
fd = mkstemp (*name);
|
||||
if (fd == -1)
|
||||
return 0;
|
||||
return fdopen (fd, "w");
|
||||
#else
|
||||
# ifdef HAVE_MKTEMP
|
||||
(void) mktemp (*name);
|
||||
# else
|
||||
(void) tmpnam (*name);
|
||||
# endif
|
||||
|
||||
# ifdef HAVE_FDOPEN
|
||||
/* Can't use mkstemp(), but guard against a race condition. */
|
||||
EINTRLOOP (fd, open (*name, O_CREAT|O_EXCL|O_WRONLY, 0600));
|
||||
if (fd == -1)
|
||||
return 0;
|
||||
return fdopen (fd, "w");
|
||||
# else
|
||||
/* Not secure, but what can we do? */
|
||||
return fopen (*name, "w");
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* This code is stolen from gnulib.
|
||||
If/when we abandon the requirement to work with K&R compilers, we can
|
||||
remove this (and perhaps other parts of GNU make!) and migrate to using
|
||||
gnulib directly.
|
||||
|
||||
This is called only through atexit(), which means die() has already been
|
||||
invoked. So, call exit() here directly. Apparently that works...?
|
||||
*/
|
||||
|
||||
/* Close standard output, exiting with status 'exit_failure' on failure.
|
||||
If a program writes *anything* to stdout, that program should close
|
||||
stdout and make sure that it succeeds before exiting. Otherwise,
|
||||
suppose that you go to the extreme of checking the return status
|
||||
of every function that does an explicit write to stdout. The last
|
||||
printf can succeed in writing to the internal stream buffer, and yet
|
||||
the fclose(stdout) could still fail (due e.g., to a disk full error)
|
||||
when it tries to write out that buffered data. Thus, you would be
|
||||
left with an incomplete output file and the offending program would
|
||||
exit successfully. Even calling fflush is not always sufficient,
|
||||
since some file systems (NFS and CODA) buffer written/flushed data
|
||||
until an actual close call.
|
||||
|
||||
Besides, it's wasteful to check the return value from every call
|
||||
that writes to stdout -- just let the internal stream state record
|
||||
the failure. That's what the ferror test is checking below.
|
||||
|
||||
It's important to detect such failures and exit nonzero because many
|
||||
tools (most notably 'make' and other build-management systems) depend
|
||||
on being able to detect failure in other tools via their exit status. */
|
||||
|
||||
static void
|
||||
close_stdout (void)
|
||||
{
|
||||
int prev_fail = ferror (stdout);
|
||||
int fclose_fail = fclose (stdout);
|
||||
|
||||
if (prev_fail || fclose_fail)
|
||||
{
|
||||
if (fclose_fail)
|
||||
perror_with_name (_("write error: stdout"), "");
|
||||
else
|
||||
O (error, NILF, _("write error: stdout"));
|
||||
exit (MAKE_TROUBLE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
output_init (struct output *out)
|
||||
{
|
||||
if (out)
|
||||
{
|
||||
out->out = out->err = OUTPUT_NONE;
|
||||
out->syncout = !!output_sync;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Configure this instance of make. Be sure stdout is line-buffered. */
|
||||
|
||||
#ifdef HAVE_SETVBUF
|
||||
# ifdef SETVBUF_REVERSED
|
||||
setvbuf (stdout, _IOLBF, xmalloc (BUFSIZ), BUFSIZ);
|
||||
# else /* setvbuf not reversed. */
|
||||
/* Some buggy systems lose if we pass 0 instead of allocating ourselves. */
|
||||
setvbuf (stdout, 0, _IOLBF, BUFSIZ);
|
||||
# endif /* setvbuf reversed. */
|
||||
#elif HAVE_SETLINEBUF
|
||||
setlinebuf (stdout);
|
||||
#endif /* setlinebuf missing. */
|
||||
|
||||
/* Force stdout/stderr into append mode. This ensures parallel jobs won't
|
||||
lose output due to overlapping writes. */
|
||||
set_append_mode (fileno (stdout));
|
||||
set_append_mode (fileno (stderr));
|
||||
|
||||
#ifdef HAVE_ATEXIT
|
||||
if (STREAM_OK (stdout))
|
||||
atexit (close_stdout);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
output_close (struct output *out)
|
||||
{
|
||||
if (! out)
|
||||
{
|
||||
if (stdio_traced)
|
||||
log_working_directory (0);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef NO_OUTPUT_SYNC
|
||||
output_dump (out);
|
||||
#endif
|
||||
|
||||
if (out->out >= 0)
|
||||
close (out->out);
|
||||
if (out->err >= 0 && out->err != out->out)
|
||||
close (out->err);
|
||||
|
||||
output_init (out);
|
||||
}
|
||||
|
||||
/* We're about to generate output: be sure it's set up. */
|
||||
void
|
||||
output_start (void)
|
||||
{
|
||||
#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 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
|
||||
outputs (int is_err, const char *msg)
|
||||
{
|
||||
if (! msg || *msg == '\0')
|
||||
return;
|
||||
|
||||
output_start ();
|
||||
|
||||
_outputs (output_context, is_err, msg);
|
||||
}
|
||||
|
||||
|
||||
static struct fmtstring
|
||||
{
|
||||
char *buffer;
|
||||
size_t size;
|
||||
} fmtbuf = { NULL, 0 };
|
||||
|
||||
static char *
|
||||
get_buffer (size_t need)
|
||||
{
|
||||
/* Make sure we have room. NEED includes space for \0. */
|
||||
if (need > fmtbuf.size)
|
||||
{
|
||||
fmtbuf.size += need * 2;
|
||||
fmtbuf.buffer = xrealloc (fmtbuf.buffer, fmtbuf.size);
|
||||
}
|
||||
|
||||
fmtbuf.buffer[need-1] = '\0';
|
||||
|
||||
return fmtbuf.buffer;
|
||||
}
|
||||
|
||||
/* Print a message on stdout. */
|
||||
|
||||
void
|
||||
message (int prefix, size_t len, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char *p;
|
||||
|
||||
len += strlen (fmt) + strlen (program) + INTSTR_LENGTH + 4 + 1 + 1;
|
||||
p = get_buffer (len);
|
||||
|
||||
if (prefix)
|
||||
{
|
||||
if (makelevel == 0)
|
||||
sprintf (p, "%s: ", program);
|
||||
else
|
||||
sprintf (p, "%s[%u]: ", program, makelevel);
|
||||
p += strlen (p);
|
||||
}
|
||||
|
||||
va_start (args, fmt);
|
||||
vsprintf (p, fmt, args);
|
||||
va_end (args);
|
||||
|
||||
strcat (p, "\n");
|
||||
|
||||
assert (fmtbuf.buffer[len-1] == '\0');
|
||||
outputs (0, fmtbuf.buffer);
|
||||
}
|
||||
|
||||
/* Print an error message. */
|
||||
|
||||
void
|
||||
error (const floc *flocp, size_t len, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char *p;
|
||||
|
||||
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)
|
||||
sprintf (p, "%s:%lu: ", flocp->filenm, flocp->lineno + flocp->offset);
|
||||
else if (makelevel == 0)
|
||||
sprintf (p, "%s: ", program);
|
||||
else
|
||||
sprintf (p, "%s[%u]: ", program, makelevel);
|
||||
p += strlen (p);
|
||||
|
||||
va_start (args, fmt);
|
||||
vsprintf (p, fmt, args);
|
||||
va_end (args);
|
||||
|
||||
strcat (p, "\n");
|
||||
|
||||
assert (fmtbuf.buffer[len-1] == '\0');
|
||||
outputs (1, fmtbuf.buffer);
|
||||
}
|
||||
|
||||
/* Print an error message and exit. */
|
||||
|
||||
void
|
||||
fatal (const floc *flocp, size_t len, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
const char *stop = _(". Stop.\n");
|
||||
char *p;
|
||||
|
||||
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)
|
||||
sprintf (p, "%s:%lu: *** ", flocp->filenm, flocp->lineno + flocp->offset);
|
||||
else if (makelevel == 0)
|
||||
sprintf (p, "%s: *** ", program);
|
||||
else
|
||||
sprintf (p, "%s[%u]: *** ", program, makelevel);
|
||||
p += strlen (p);
|
||||
|
||||
va_start (args, fmt);
|
||||
vsprintf (p, fmt, args);
|
||||
va_end (args);
|
||||
|
||||
strcat (p, stop);
|
||||
|
||||
assert (fmtbuf.buffer[len-1] == '\0');
|
||||
outputs (1, fmtbuf.buffer);
|
||||
|
||||
die (MAKE_FAILURE);
|
||||
}
|
||||
|
||||
/* Print an error message from errno. */
|
||||
|
||||
void
|
||||
perror_with_name (const char *str, const char *name)
|
||||
{
|
||||
const char *err = strerror (errno);
|
||||
OSSS (error, NILF, _("%s%s: %s"), str, name, err);
|
||||
}
|
||||
|
||||
/* Print an error message from errno and exit. */
|
||||
|
||||
void
|
||||
pfatal_with_name (const char *name)
|
||||
{
|
||||
const char *err = strerror (errno);
|
||||
OSS (fatal, NILF, _("%s: %s"), name, err);
|
||||
|
||||
/* NOTREACHED */
|
||||
}
|
||||
51
output.h
Normal file
51
output.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/* Output to stdout / stderr for GNU make
|
||||
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
|
||||
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/>. */
|
||||
|
||||
struct output
|
||||
{
|
||||
int out;
|
||||
int err;
|
||||
unsigned int syncout:1; /* True if we want to synchronize output. */
|
||||
};
|
||||
|
||||
extern struct output *output_context;
|
||||
extern unsigned int stdio_traced;
|
||||
|
||||
#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
|
||||
output (this should only be done once). */
|
||||
void output_init (struct output *out);
|
||||
void output_close (struct output *out);
|
||||
|
||||
/* In situations where output may be about to be displayed but we're not
|
||||
sure if we've set it up yet, call this. */
|
||||
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);
|
||||
|
||||
#ifndef NO_OUTPUT_SYNC
|
||||
int output_tmpfd (void);
|
||||
/* Dump any child output content to stdout, and reset it. */
|
||||
void output_dump (struct output *out);
|
||||
#endif
|
||||
93
po/ChangeLog
93
po/ChangeLog
@@ -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/>.
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -27,9 +27,12 @@ guile.c
|
||||
hash.c
|
||||
implicit.c
|
||||
job.c
|
||||
job.h
|
||||
load.c
|
||||
main.c
|
||||
misc.c
|
||||
output.c
|
||||
posixos.c
|
||||
read.c
|
||||
remake.c
|
||||
remote-cstms.c
|
||||
@@ -41,3 +44,4 @@ variable.h
|
||||
vmsfunctions.c
|
||||
vmsjobs.c
|
||||
vpath.c
|
||||
w32/w32os.c
|
||||
|
||||
431
posixos.c
Normal file
431
posixos.c
Normal 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
59
prepare_vms.com
Normal 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"
|
||||
391
readme.vms
391
readme.vms
@@ -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/>.
|
||||
373
remake.c
373
remake.c
@@ -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,14 +53,19 @@ 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;
|
||||
|
||||
/* Current value for pruning the scan of the goal chain (toggle 0/1). */
|
||||
static unsigned int considered;
|
||||
/* Set to the goal dependency. Mostly needed for remaking makefiles. */
|
||||
static struct goaldep *goal_list;
|
||||
static struct dep *goal_dep;
|
||||
|
||||
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 int touch_file (struct file *file);
|
||||
/* Current value for pruning the scan of the goal chain.
|
||||
All files start with considered == 0. */
|
||||
static unsigned int considered = 0;
|
||||
|
||||
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);
|
||||
static const char *library_search (const char *lib, FILE_TIMESTAMP *mtime_ptr);
|
||||
@@ -76,32 +79,23 @@ static const char *library_search (const char *lib, FILE_TIMESTAMP *mtime_ptr);
|
||||
targets, and we should only make one goal at a time and return as soon as
|
||||
one goal whose 'changed' member is nonzero is successfully made. */
|
||||
|
||||
int
|
||||
update_goal_chain (struct dep *goals)
|
||||
enum update_status
|
||||
update_goal_chain (struct goaldep *goaldeps)
|
||||
{
|
||||
int t = touch_flag, q = question_flag, n = just_print_flag;
|
||||
int status = -1;
|
||||
enum update_status status = us_none;
|
||||
|
||||
/* Duplicate the chain so we can remove things from it. */
|
||||
|
||||
struct dep *goals = copy_dep_chain ((struct dep *)goaldeps);
|
||||
|
||||
goal_list = rebuilding_makefiles ? goaldeps : NULL;
|
||||
|
||||
#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);
|
||||
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* All files start with the considered bit 0, so the global value is 1. */
|
||||
considered = 1;
|
||||
/* Start a fresh batch of consideration. */
|
||||
++considered;
|
||||
|
||||
/* Update all the goals until they are all finished. */
|
||||
|
||||
@@ -125,14 +119,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 x;
|
||||
enum update_status fail;
|
||||
|
||||
file->dontcare = g->dontcare;
|
||||
file->dontcare = ANY_SET (g->flags, RM_DONTCARE);
|
||||
|
||||
check_renamed (file);
|
||||
if (rebuilding_makefiles)
|
||||
@@ -152,7 +148,7 @@ update_goal_chain (struct dep *goals)
|
||||
actually run. */
|
||||
ocommands_started = commands_started;
|
||||
|
||||
x = update_file (file, rebuilding_makefiles ? 1 : 0);
|
||||
fail = update_file (file, rebuilding_makefiles ? 1 : 0);
|
||||
check_renamed (file);
|
||||
|
||||
/* Set the goal's 'changed' flag if any commands were started
|
||||
@@ -161,14 +157,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 ((x != 0 || file->updated) && status < 1)
|
||||
if ((fail || file->updated) && status < us_question)
|
||||
{
|
||||
if (file->update_status != 0)
|
||||
/* 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. */
|
||||
@@ -195,7 +189,7 @@ update_goal_chain (struct dep *goals)
|
||||
enter an infinite loop. */
|
||||
if (!rebuilding_makefiles
|
||||
|| (!just_print_flag && !question_flag))
|
||||
status = 0;
|
||||
status = us_success;
|
||||
if (rebuilding_makefiles && file->dontcare)
|
||||
/* This is a default makefile; stop remaking. */
|
||||
stop = 1;
|
||||
@@ -222,16 +216,16 @@ update_goal_chain (struct dep *goals)
|
||||
print a message saying nothing needs doing. */
|
||||
|
||||
if (!rebuilding_makefiles
|
||||
/* If the update_status is zero, we updated successfully
|
||||
/* If the update_status is success, we updated successfully
|
||||
or not at all. G->changed will have been set above if
|
||||
any commands were actually started for this goal. */
|
||||
&& file->update_status == 0 && !g->changed
|
||||
&& 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)
|
||||
@@ -254,10 +248,10 @@ update_goal_chain (struct dep *goals)
|
||||
}
|
||||
}
|
||||
|
||||
/* If we reached the end of the dependency graph toggle the considered
|
||||
flag for the next pass. */
|
||||
/* If we reached the end of the dependency graph update CONSIDERED
|
||||
for the next pass. */
|
||||
if (g == 0)
|
||||
considered = !considered;
|
||||
++considered;
|
||||
}
|
||||
|
||||
if (rebuilding_makefiles)
|
||||
@@ -270,8 +264,32 @@ 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, 1 if unsuccessful;
|
||||
Return 0 if successful, non-0 if unsuccessful;
|
||||
but with some flag settings, just call 'exit' if unsuccessful.
|
||||
|
||||
DEPTH is the depth in recursions of this function.
|
||||
@@ -282,11 +300,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)
|
||||
{
|
||||
register int status = 0;
|
||||
register struct file *f;
|
||||
enum update_status status = us_success;
|
||||
struct file *f;
|
||||
|
||||
f = file->double_colon ? file->double_colon : file;
|
||||
|
||||
@@ -297,12 +315,13 @@ update_file (struct file *file, unsigned int depth)
|
||||
if (f->considered == considered)
|
||||
{
|
||||
/* Check for the case where a target has been tried and failed but
|
||||
the diagnostics hasn't been issued. If we need the diagnostics
|
||||
the diagnostics haven't been issued. If we need the diagnostics
|
||||
then we will have to continue. */
|
||||
if (!(f->updated && f->update_status > 0 && !f->dontcare && f->no_diag))
|
||||
if (!(f->updated && f->update_status > us_none
|
||||
&& !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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -310,26 +329,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
|
||||
@@ -342,7 +363,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;
|
||||
@@ -363,7 +388,7 @@ complain (struct file *file)
|
||||
|
||||
for (d = file->deps; d != 0; d = d->next)
|
||||
{
|
||||
if (d->file->updated && d->file->update_status > 0 && file->no_diag)
|
||||
if (d->file->updated && d->file->update_status > us_none && file->no_diag)
|
||||
{
|
||||
complain (d->file);
|
||||
break;
|
||||
@@ -372,37 +397,43 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
/* Consider a single 'struct file' and update it as appropriate. */
|
||||
/* 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;
|
||||
@@ -412,7 +443,7 @@ update_file_1 (struct file *file, unsigned int depth)
|
||||
|
||||
if (file->updated)
|
||||
{
|
||||
if (file->update_status > 0)
|
||||
if (file->update_status > us_none)
|
||||
{
|
||||
DBF (DB_VERBOSE,
|
||||
_("Recently tried and failed to update file '%s'.\n"));
|
||||
@@ -476,8 +507,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;
|
||||
}
|
||||
|
||||
@@ -519,6 +551,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;
|
||||
@@ -530,8 +563,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. */
|
||||
@@ -553,7 +586,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)
|
||||
@@ -577,12 +612,12 @@ update_file_1 (struct file *file, unsigned int depth)
|
||||
while (f != 0);
|
||||
}
|
||||
|
||||
if (dep_status != 0 && !keep_going_flag)
|
||||
if (dep_status && !keep_going_flag)
|
||||
break;
|
||||
|
||||
if (!running)
|
||||
/* The prereq is considered changed if the timestamp has changed while
|
||||
it was built, OR it doesn't exist. */
|
||||
/* The prereq is considered changed if the timestamp has changed
|
||||
while it was built, OR it doesn't exist. */
|
||||
d->changed = ((file_mtime (d->file) != mtime)
|
||||
|| (mtime == NONEXISTENT_MTIME));
|
||||
|
||||
@@ -599,6 +634,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);
|
||||
@@ -615,9 +651,11 @@ update_file_1 (struct file *file, unsigned int depth)
|
||||
/* We may have already considered this file, when we didn't know
|
||||
we'd need to update it. Force update_file() to consider it and
|
||||
not prune it. */
|
||||
d->file->considered = !considered;
|
||||
d->file->considered = 0;
|
||||
|
||||
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)
|
||||
@@ -638,7 +676,7 @@ update_file_1 (struct file *file, unsigned int depth)
|
||||
while (f != 0);
|
||||
}
|
||||
|
||||
if (dep_status != 0 && !keep_going_flag)
|
||||
if (dep_status && !keep_going_flag)
|
||||
break;
|
||||
|
||||
if (!running)
|
||||
@@ -662,9 +700,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 = dep_status;
|
||||
/* 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;
|
||||
@@ -673,8 +712,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;
|
||||
}
|
||||
@@ -820,17 +859,16 @@ update_file_1 (struct file *file, unsigned int depth)
|
||||
|
||||
switch (file->update_status)
|
||||
{
|
||||
case 2:
|
||||
case us_failed:
|
||||
DBF (DB_BASIC, _("Failed to remake target file '%s'.\n"));
|
||||
break;
|
||||
case 0:
|
||||
case us_success:
|
||||
DBF (DB_BASIC, _("Successfully remade target file '%s'.\n"));
|
||||
break;
|
||||
case 1:
|
||||
DBF (DB_BASIC, _("Target file '%s' needs remade under -q.\n"));
|
||||
case us_question:
|
||||
DBF (DB_BASIC, _("Target file '%s' needs to be remade under -q.\n"));
|
||||
break;
|
||||
default:
|
||||
assert (file->update_status >= 0 && file->update_status <= 2);
|
||||
case us_none:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -842,7 +880,7 @@ update_file_1 (struct file *file, unsigned int depth)
|
||||
files listed in its 'also_make' member. Under -t, this function also
|
||||
touches FILE.
|
||||
|
||||
On return, FILE->update_status will no longer be -1 if it was. */
|
||||
On return, FILE->update_status will no longer be us_none if it was. */
|
||||
|
||||
void
|
||||
notice_finished_file (struct file *file)
|
||||
@@ -856,12 +894,12 @@ notice_finished_file (struct file *file)
|
||||
|
||||
if (touch_flag
|
||||
/* The update status will be:
|
||||
-1 if this target was not remade;
|
||||
0 if 0 or more commands (+ or ${MAKE}) were run and won;
|
||||
1 if some commands were run and lost.
|
||||
us_success if 0 or more commands (+ or ${MAKE}) were run and won;
|
||||
us_none if this target was not remade;
|
||||
>us_none if some commands were run and lost.
|
||||
We touch the target if it has commands which either were not run
|
||||
or won when they ran (i.e. status is 0). */
|
||||
&& file->update_status == 0)
|
||||
&& file->update_status == us_success)
|
||||
{
|
||||
if (file->cmds != 0 && file->cmds->any_recurse)
|
||||
{
|
||||
@@ -876,7 +914,7 @@ notice_finished_file (struct file *file)
|
||||
{
|
||||
have_nonrecursing:
|
||||
if (file->phony)
|
||||
file->update_status = 0;
|
||||
file->update_status = us_success;
|
||||
/* According to POSIX, -t doesn't affect targets with no cmds. */
|
||||
else if (file->cmds != 0)
|
||||
{
|
||||
@@ -950,7 +988,7 @@ notice_finished_file (struct file *file)
|
||||
f->last_mtime = max_mtime;
|
||||
}
|
||||
|
||||
if (ran && file->update_status != -1)
|
||||
if (ran && file->update_status != us_none)
|
||||
/* We actually tried to update FILE, which has
|
||||
updated its also_make's as well (if it worked).
|
||||
If it didn't work, it wouldn't work again for them.
|
||||
@@ -968,10 +1006,10 @@ notice_finished_file (struct file *file)
|
||||
never be done because the target is already updated. */
|
||||
f_mtime (d->file, 0);
|
||||
}
|
||||
else if (file->update_status == -1)
|
||||
else if (file->update_status == us_none)
|
||||
/* Nothing was done for FILE, but it needed nothing done.
|
||||
So mark it now as "succeeded". */
|
||||
file->update_status = 0;
|
||||
file->update_status = us_success;
|
||||
}
|
||||
|
||||
/* Check whether another file (whose mtime is THIS_MTIME) needs updating on
|
||||
@@ -980,13 +1018,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);
|
||||
@@ -1050,7 +1088,7 @@ check_dep (struct file *file, unsigned int depth,
|
||||
/* If the target was waiting for a dependency it has to be
|
||||
reconsidered, as that dependency might have finished. */
|
||||
if (file->command_state == cs_deps_running)
|
||||
file->considered = !considered;
|
||||
file->considered = 0;
|
||||
|
||||
set_command_state (file, cs_not_started);
|
||||
}
|
||||
@@ -1059,12 +1097,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;
|
||||
@@ -1082,12 +1121,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
|
||||
@@ -1112,28 +1153,30 @@ check_dep (struct file *file, unsigned int depth,
|
||||
return dep_status;
|
||||
}
|
||||
|
||||
/* Touch FILE. Return zero if successful, one if not. */
|
||||
/* Touch FILE. Return us_success if successful, us_failed if not. */
|
||||
|
||||
#define TOUCH_ERROR(call) return (perror_with_name (call, file->name), 1)
|
||||
#define TOUCH_ERROR(call) do{ perror_with_name ((call), file->name); \
|
||||
return us_failed; }while(0)
|
||||
|
||||
static int
|
||||
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)
|
||||
return 0;
|
||||
return us_success;
|
||||
|
||||
#ifndef NO_ARCHIVES
|
||||
if (ar_name (file->name))
|
||||
return ar_touch (file->name);
|
||||
return ar_touch (file->name) ? us_failed : us_success;
|
||||
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
|
||||
@@ -1146,18 +1189,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: ");
|
||||
}
|
||||
@@ -1165,7 +1214,7 @@ touch_file (struct file *file)
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return us_success;
|
||||
}
|
||||
|
||||
/* Having checked and updated the dependencies of FILE,
|
||||
@@ -1179,17 +1228,17 @@ remake_file (struct file *file)
|
||||
{
|
||||
if (file->phony)
|
||||
/* Phony target. Pretend it succeeded. */
|
||||
file->update_status = 0;
|
||||
file->update_status = us_success;
|
||||
else if (file->is_target)
|
||||
/* This is a nonexistent target file we cannot make.
|
||||
Pretend it was successfully remade. */
|
||||
file->update_status = 0;
|
||||
file->update_status = us_success;
|
||||
else
|
||||
{
|
||||
/* This is a dependency file we cannot remake. Fail. */
|
||||
if (!rebuilding_makefiles || !file->dontcare)
|
||||
complain (file);
|
||||
file->update_status = 2;
|
||||
file->update_status = us_failed;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1204,7 +1253,7 @@ remake_file (struct file *file)
|
||||
}
|
||||
|
||||
/* This tells notice_finished_file it is ok to touch the file. */
|
||||
file->update_status = 0;
|
||||
file->update_status = us_success;
|
||||
}
|
||||
|
||||
/* This does the touching under -t. */
|
||||
@@ -1223,6 +1272,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. */
|
||||
|
||||
@@ -1256,7 +1306,7 @@ f_mtime (struct file *file, int search)
|
||||
arlen = strlen (arfile->hname);
|
||||
memlen = strlen (memname);
|
||||
|
||||
name = xmalloc (arlen + 1 + memlen + 2);
|
||||
name = alloca (arlen + 1 + memlen + 2);
|
||||
memcpy (name, arfile->hname, arlen);
|
||||
name[arlen] = '(';
|
||||
memcpy (name + arlen + 1, memname, memlen);
|
||||
@@ -1266,9 +1316,9 @@ f_mtime (struct file *file, int search)
|
||||
/* If the archive was found with GPATH, make the change permanent;
|
||||
otherwise defer it until later. */
|
||||
if (arfile->name == arfile->hname)
|
||||
rename_file (file, name);
|
||||
rename_file (file, strcache_add (name));
|
||||
else
|
||||
rehash_file (file, name);
|
||||
rehash_file (file, strcache_add (name));
|
||||
check_renamed (file);
|
||||
}
|
||||
|
||||
@@ -1299,6 +1349,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. */
|
||||
@@ -1307,7 +1359,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);
|
||||
@@ -1367,8 +1426,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)
|
||||
@@ -1380,18 +1440,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
|
||||
@@ -1400,11 +1464,11 @@ f_mtime (struct file *file, int search)
|
||||
started. So, turn off the intermediate bit so make doesn't
|
||||
delete it, since it didn't create it. */
|
||||
if (mtime != NONEXISTENT_MTIME && file->command_state == cs_not_started
|
||||
&& file->command_state == cs_not_started
|
||||
&& !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);
|
||||
@@ -1519,7 +1583,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",
|
||||
@@ -1549,7 +1613,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)"));
|
||||
|
||||
@@ -1579,7 +1643,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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -19,7 +19,6 @@ 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 "job.h"
|
||||
#include "filedef.h"
|
||||
#include "commands.h"
|
||||
#include "job.h"
|
||||
@@ -152,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;
|
||||
}
|
||||
|
||||
@@ -193,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! */
|
||||
|
||||
@@ -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
16
rule.c
@@ -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_FILE_SEQ (&ptr, struct dep, '\0', NULL, 0);
|
||||
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
5
rule.h
@@ -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);
|
||||
|
||||
@@ -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
|
||||
@@ -244,7 +244,7 @@ strsignal (int sig)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
if (sig > 0 || sig < NSIG)
|
||||
if (sig > 0 && sig < NSIG)
|
||||
return (char *) sys_siglist[sig];
|
||||
|
||||
sprintf (buf, "Signal %d", sig);
|
||||
|
||||
147
strcache.c
147
strcache.c
@@ -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;
|
||||
|
||||
|
||||
@@ -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
1
tests/.gitignore
vendored
@@ -1 +1,2 @@
|
||||
config-flags.pm
|
||||
work
|
||||
|
||||
@@ -1,3 +1,131 @@
|
||||
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.
|
||||
* run_make_tests.pl (run_make_test): Allow the answer string to be
|
||||
undef, which means that we shouldn't compare it at all. Only the
|
||||
exit code matters in this case.
|
||||
* test_driver.pl (compare_output): Ditto.
|
||||
Test for Savannah bug #27374.
|
||||
|
||||
* scripts/features/parallelism: Test broken jobserver on recursion.
|
||||
Test for Savannah bug #39934.
|
||||
|
||||
* scripts/options/eval: Verify --eval during restart.
|
||||
Test for Savannah bug #39203.
|
||||
|
||||
2013-09-14 Paul Smith <psmith@gnu.org>
|
||||
|
||||
* scripts/features/output-sync: Verify -Orecurse properly.
|
||||
|
||||
2013-09-12 Paul Smith <psmith@gnu.org>
|
||||
|
||||
* scripts/features/output-sync: Modify for output sync behavior.
|
||||
* scripts/variables/MAKE_RESTARTS: Ditto.
|
||||
* scripts/variables/MAKEFLAGS: Remove mode for --trace.
|
||||
* scripts/variables/GNUMAKEFLAGS: Ditto.
|
||||
|
||||
2013-07-22 Paul Smith <psmith@gnu.org>
|
||||
|
||||
* scripts/features/rule_glob: Add tests for wildcards in rules.
|
||||
Test for Savannah bug #39310.
|
||||
|
||||
2013-07-09 Paul Smith <psmith@gnu.org>
|
||||
|
||||
* scripts/features/se_implicit: Add a test for SE rules depending
|
||||
on other SE rules to be built.
|
||||
|
||||
2013-05-26 Paul Smith <psmith@gnu.org>
|
||||
|
||||
* scripts/features/archives: Test for Savannah bug #38442.
|
||||
|
||||
* scripts/misc/bs-nl: Test for Savannah bug #39035.
|
||||
Add a test for Savannah bug #38945.
|
||||
|
||||
2013-05-22 Paul Smith <psmith@gnu.org>
|
||||
|
||||
* scripts/options/dash-n: Fix results after MAKEFLAGS fixes.
|
||||
* scripts/variables/MAKEFLAGS: Ditto.
|
||||
* scripts/variables/GNUMAKEFLAGS: Ditto.
|
||||
|
||||
2013-05-14 Paul Smith <psmith@gnu.org>
|
||||
|
||||
* scripts/features/loadapi: Add plugin_is_GPL_compatible symbol.
|
||||
@@ -1285,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
|
||||
@@ -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
|
||||
|
||||
@@ -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
19
tests/config-flags.pm.in
Normal 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
53
tests/config_flags_pm.com
Executable 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
|
||||
$!
|
||||
@@ -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
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user