mirror of
https://github.com/mirror/make.git
synced 2026-08-20 00:43:29 +08:00
Compare commits
204 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 |
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,213 @@
|
||||
2013-10-09 Paul Smith <psmith@gnu.org>
|
||||
|
||||
Version 4.0 released.
|
||||
|
||||
* configure.ac: Updated for the release.
|
||||
* NEWS: Updated for the release.
|
||||
|
||||
* maintMakefile (tag-release): New target to add a Git tag.
|
||||
* read.c (eval): Typo fix.
|
||||
* ChangeLog.1: Typo fixes.
|
||||
* w32/subproc/sub_proc.c (process_cleanup): Typo fix.
|
||||
|
||||
2013-10-07 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* w32/compat/posixfcn.c (tmpfile): Move declaration of h before
|
||||
the first executable statement. Reported by Gisle Vanem
|
||||
<gvanem@yahoo.no>.
|
||||
|
||||
2013-10-05 Paul Smith <psmith@gnu.org>
|
||||
|
||||
* makeint.h (MAP_USERFUNC): A new map type for function names.
|
||||
* main.c (initialize_stopchar_map): Set up the function name map.
|
||||
|
||||
* gnumake.h (gmk_func_ptr): Define a type for function pointers.
|
||||
(gmk_add_function): Convert the last argument to FLAGS.
|
||||
(GMK_FUNC_*): Define flags for the function. Change the default
|
||||
behavior to "expand" since that's the most common one.
|
||||
|
||||
* function.c (function_table_entry): Use new function pointer type.
|
||||
(lookup_function): Accept any valid function name character based
|
||||
on the MAP_USERFUNC values.
|
||||
(define_new_function): Use the new calling signature. Verify that
|
||||
registered functions have valid names.
|
||||
|
||||
* guile.c (guile_gmake_setup): Use new calling signatures.
|
||||
* loadapi.c (gmk_add_function): Ditto.
|
||||
* variable.h (define_new_function): Ditto.
|
||||
|
||||
* doc/make.texi (Loaded Object API): Make the registered function
|
||||
API documentation more clear.
|
||||
|
||||
2013-10-03 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* function.c (abspath): Reset root_len to one for Cygwin only when
|
||||
HAVE_DOS_PATHS is defined. Suggested by Christopher Faylor.
|
||||
|
||||
2013-10-02 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* w32/compat/posixfcn.c (tmpfile): New function, a replacement for
|
||||
the Windows libc version.
|
||||
|
||||
Fix $abspath on Cygwin when HAVE_DOS_PATHS is in effect.
|
||||
* function.c (IS_ABSOLUTE) [__CYGWIN__]: Special definition for
|
||||
Cygwin.
|
||||
(abspath) [__CYGWIN__]: Reset root_len to 1 if the absolute file
|
||||
name has the Posix /foo/bar form.
|
||||
[HAVE_DOS_PATHS]: Use root_len instead of hard-coded 2.
|
||||
|
||||
2013-10-01 Paul Smith <psmith@gnu.org>
|
||||
|
||||
* configure.ac: Update version to 3.99.93.
|
||||
* NEWS: Ditto.
|
||||
|
||||
2013-09-30 Paul Smith <psmith@gnu.org>
|
||||
|
||||
* guile.c: Portability fixes for Guile 1.8.
|
||||
|
||||
2013-09-29 Paul Smith <psmith@gnu.org>
|
||||
|
||||
* output.c (output_dump): Always write Enter/Leave messages to stdio.
|
||||
(log_working_directory): This now always writes to stdio, so we
|
||||
don't need the struct output parameter anymore.
|
||||
(output_start): Show the working directory when output_sync is not
|
||||
set or is recursive.
|
||||
* main.c (main): Ensure the special "already shown Enter message"
|
||||
token is removed from MAKE_RESTARTS before the user can see it.
|
||||
* function.c (func_shell_base): If the output_context stderr
|
||||
exists but is invalid, write to the real stderr.
|
||||
Fixes suggested by Frank Heckenbach <f.heckenbach@fh-soft.de>.
|
||||
|
||||
* output.c: Guard unistd.h inclusion, add io.h.
|
||||
* gnumake.h: Move GMK_EXPORT before the declarations.
|
||||
* make_msvc_net2003.vcproj: Add missing files.
|
||||
Changes for MSVC suggested by Gerte Hoogewerf <g.hoogewerf@gmail.com>
|
||||
|
||||
* function.c (func_shell_base) [EMX]: Fix EMX support for output-sync.
|
||||
* job.c (child_execute_job) [EMX]: Ditto.
|
||||
* job.h (child_execute_job) [EMX]: Ditto.
|
||||
* w32/compat/posixfcn.c: Invert the test for NO_OUTPUT_SYNC.
|
||||
|
||||
* guile.c (GSUBR_TYPE): Pre-2.0 Guile doesn't provide a typedef
|
||||
for gsubr pointers. Create one.
|
||||
(guile_define_module): Use it.
|
||||
(internal_guile_eval): Force UTF-8 encoding for Guile strings.
|
||||
|
||||
* main.c (main): Clear GNUMAKEFLAGS after parsing, to avoid
|
||||
proliferation of options.
|
||||
* NEWS: Document it.
|
||||
* doc/make.texi (Options/Recursion): Ditto.
|
||||
|
||||
2013-09-23 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* w32/compat/posixfcn.c: Fix the forgotten OUTPUT_SYNC conditional.
|
||||
|
||||
* job.h: Ditto, but in a comment.
|
||||
|
||||
2013-09-22 Paul Smith <psmith@gnu.org>
|
||||
|
||||
* configure.ac: Update version to 3.99.92.
|
||||
* NEWS: Ditto.
|
||||
|
||||
* implicit.c (pattern_search): After second expansion be sure to
|
||||
handle order-only markers inside the expansion properly.
|
||||
Fixes Savannah bug #31155.
|
||||
|
||||
* guile.c (guile_define_module): Technically a void* cannot
|
||||
contain a pointer-to-function and some compilers warn about this.
|
||||
Cast the function pointers.
|
||||
* load.c (load_object): Ditto.
|
||||
|
||||
* read.c (eval): If load_file() returns -1, don't add this to the
|
||||
"to be rebuilt" list.
|
||||
* doc/make.texi (load Directive): Document it.
|
||||
|
||||
* guile.c (guile_gmake_setup): Don't initialize Guile so early.
|
||||
(func_guile): Lazily initialize Guile the first time the $(guile ..)
|
||||
function is invoked. Guile can steal file descriptors which
|
||||
confuses our jobserver FD checking, so we don't want to initialize
|
||||
it before we have to.
|
||||
|
||||
VMS port updates by Hartmut Becker <becker.ismaning@freenet.de>
|
||||
|
||||
* makefile.com: Add output to the filelist.
|
||||
* output.c (va_copy): Add an implementation of this macro for VMS.
|
||||
* commands.c: Ensure filedef.h is #included before dep.h.
|
||||
* dir.c: Ditto.
|
||||
* file.c: Ditto.
|
||||
* guile.c: Ditto.
|
||||
* main.c: Ditto.
|
||||
* misc.c: Ditto.
|
||||
* read.c: Ditto.
|
||||
* rule.c: Ditto.
|
||||
* variable.c: Ditto.
|
||||
* readme.vms: Renamed to README.VMS and updates for this release.
|
||||
* Makefile.am: Ditto.
|
||||
* NEWS: Ditto.
|
||||
* README.template: Ditto.
|
||||
* Makefile.DOS.template: Ditto.
|
||||
|
||||
2013-09-21 Paul Smith <psmith@gnu.org>
|
||||
|
||||
* maintMakefile (check-alt-config): Create a target to test
|
||||
alternative configurations. Each one will build make with a
|
||||
different configuration then run the test suite.
|
||||
|
||||
Invert the output-sync #define to NO_OUTPUT_SYNC
|
||||
|
||||
* configure.ac: Don't set OUTPUT_SYNC.
|
||||
* makeint.h: Ditto.
|
||||
* main.c: Use NO_OUTPUT_SYNC instead of OUTPUT_SYNC.
|
||||
* output.c: Ditto.
|
||||
* output.h: Ditto.
|
||||
* job.h: Ditto.
|
||||
* job.c: Ditto.
|
||||
* config.ami.template: Set NO_OUTPUT_SYNC.
|
||||
* config.h-vms.template: Ditto.
|
||||
* config.h.W32.template: Ditto.
|
||||
* configh.dos.template: Ditto.
|
||||
|
||||
Output generated while reading makefiles should be synced.
|
||||
|
||||
* main.c (make_sync): Define a context for syncing while reading
|
||||
makefiles and other top-level operations.
|
||||
(main): If we request syncing, enable it while we are parsing
|
||||
options, reading makefiles, etc. to capture that output. Just
|
||||
before we start to run rules, dump the output if any.
|
||||
(die): Dump any output we've been syncing before we die
|
||||
* output.h (OUTPUT_SET): Disable output_context if not syncout.
|
||||
|
||||
Stderr generated from shell functions in recipes should be synced.
|
||||
|
||||
* job.h (FD_STDIN, FD_STDOUT, FD_STDERR): Create new macros to
|
||||
avoid magic numbers.
|
||||
(child_execute_job): Take a FD for stderr.
|
||||
* job.c (child_execute_job): Handle STDERR FD's in addition to
|
||||
stdin and stdout.
|
||||
(start_job_command): Call child_execute_job() with the new STDERR
|
||||
parameter. Instead of performing the dup() here, send it to
|
||||
child_execute_job() where it's already being done.
|
||||
* function.c (func_shell_base): Pass the OUTPUT_CONTEXT stderr to
|
||||
child_execute_job() if it's set, otherwise FD_STDERR.
|
||||
* main.c (main): Pass FD_STDERR to child_execute_job().
|
||||
|
||||
2013-09-19 Paul Smith <psmith@gnu.org>
|
||||
|
||||
* main.c (main): Set MAKE_RESTARTS to negative before re-exec if
|
||||
we've already generated an "Entering" message. If we are started
|
||||
and notice that MAKE_RESTARTS is negative, assume we already wrote
|
||||
"Entering" and don't write it again.
|
||||
|
||||
2013-09-18 Paul Smith <psmith@gnu.org>
|
||||
|
||||
* main.c (main): Set starting_directory before we write any
|
||||
errors. Fixes Savannah bug #40043.
|
||||
|
||||
2013-09-16 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* output.c [WINDOWS32]: Include windows.h and sub_proc.h, to avoid
|
||||
compiler warnings for CLOSE_ON_EXEC.
|
||||
|
||||
2013-09-16 Paul Smith <psmith@gnu.org>
|
||||
|
||||
* configure.ac: Update version to 3.99.91.
|
||||
@@ -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 output.c read.c remake.c rule.c \
|
||||
signame.c strcache.c variable.c version.c vpath.c hash.c \
|
||||
$(remote)
|
||||
|
||||
if HAVE_GUILE
|
||||
make_SOURCES += guile.c
|
||||
endif
|
||||
function.c getopt.c getopt1.c guile.c implicit.c job.c load.c \
|
||||
loadapi.c main.c misc.c $(ossrc) output.c read.c remake.c \
|
||||
rule.c signame.c strcache.c variable.c version.c vpath.c \
|
||||
hash.c $(remote)
|
||||
|
||||
EXTRA_make_SOURCES = vmsjobs.c remote-stub.c remote-cstms.c
|
||||
|
||||
noinst_HEADERS = commands.h dep.h filedef.h job.h makeint.h rule.h variable.h \
|
||||
debug.h getopt.h gettext.h hash.h output.h
|
||||
debug.h getopt.h gettext.h hash.h output.h os.h
|
||||
|
||||
make_LDADD = @LIBOBJS@ @ALLOCA@ $(GLOBLIB) @GETLOADAVG_LIBS@ @LIBINTL@ \
|
||||
$(GUILE_LIBS)
|
||||
@@ -75,28 +74,22 @@ endif
|
||||
|
||||
# Extra stuff to include in the distribution.
|
||||
|
||||
EXTRA_DIST = README build.sh.in $(man_MANS) \
|
||||
EXTRA_DIST = ChangeLog README build.sh.in $(man_MANS) \
|
||||
README.customs README.OS2 \
|
||||
SCOPTIONS SMakefile \
|
||||
README.Amiga Makefile.ami config.ami make.lnk amiga.c amiga.h \
|
||||
README.DOS Makefile.DOS configure.bat dosbuild.bat configh.dos\
|
||||
README.W32 NMakefile config.h.W32 build_w32.bat subproc.bat \
|
||||
make_msvc_net2003.sln make_msvc_net2003.vcproj \
|
||||
readme.vms makefile.vms makefile.com config.h-vms \
|
||||
vmsdir.h vmsfunctions.c vmsify.c \
|
||||
README.VMS makefile.vms makefile.com config.h-vms \
|
||||
vmsdir.h vmsfunctions.c vmsify.c vms_exit.c vms_progname.c \
|
||||
vms_export_symbol.c vms_export_symbol_test.com \
|
||||
gmk-default.scm gmk-default.h
|
||||
|
||||
# This is built during configure, but behind configure's back
|
||||
|
||||
DISTCLEANFILES = build.sh
|
||||
|
||||
# Forward targets
|
||||
|
||||
html:
|
||||
cd doc && $(MAKE) $(AM_MAKEFLAGS) $@
|
||||
|
||||
.PHONY: html
|
||||
|
||||
# --------------- Internationalization Section
|
||||
|
||||
localedir = $(datadir)/locale
|
||||
@@ -136,8 +129,8 @@ guile.$(OBJEXT): gmk-default.h
|
||||
gmk-default.h: $(srcdir)/gmk-default.scm
|
||||
(echo 'static const char *const GUILE_module_defn = " '\\ \
|
||||
&& sed -e 's/;.*//' -e '/^[ \t]*$$/d' -e 's/"/\\"/g' -e 's/$$/ \\/' \
|
||||
$(srcdir)/gmk-default.scm \
|
||||
&& echo '";') > $@
|
||||
$(srcdir)/gmk-default.scm \
|
||||
&& echo '";') > $@
|
||||
|
||||
# --------------- Local DIST Section
|
||||
|
||||
@@ -183,8 +176,9 @@ loadavg_LDADD = @GETLOADAVG_LIBS@
|
||||
#
|
||||
MAKETESTFLAGS =
|
||||
|
||||
check-regression:
|
||||
check-regression: tests/config-flags.pm
|
||||
@if test -f '$(srcdir)/tests/run_make_tests'; then \
|
||||
ulimit -n 128; \
|
||||
if $(PERL) -v >/dev/null 2>&1; then \
|
||||
case `cd '$(srcdir)'; pwd` in `pwd`) : ;; \
|
||||
*) test -d tests || mkdir tests; \
|
||||
@@ -199,9 +193,9 @@ check-regression:
|
||||
else \
|
||||
echo "Can't find a working Perl ($(PERL)); the test suite requires Perl."; \
|
||||
fi; \
|
||||
else \
|
||||
else \
|
||||
echo "Can't find the GNU Make test suite ($(srcdir)/tests)."; \
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
# --------------- Maintainer's Section
|
||||
|
||||
@@ -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
|
||||
|
||||
399
NEWS
399
NEWS
@@ -1,6 +1,6 @@
|
||||
GNU make NEWS -*-indented-text-*-
|
||||
History of user-visible changes.
|
||||
16 Sep 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.91
|
||||
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
|
||||
@@ -47,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
|
||||
@@ -58,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
|
||||
@@ -73,7 +174,8 @@ http://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=101&set
|
||||
* New variable: $(GNUMAKEFLAGS) will be parsed for make flags, just like
|
||||
MAKEFLAGS is. It can be set in the environment or the makefile, containing
|
||||
GNU make-specific flags to allow your makefile to be portable to other
|
||||
versions of make. GNU make never sets or modifies GNUMAKEFLAGS.
|
||||
versions of make. Once this variable is parsed, GNU make will set it to the
|
||||
empty string so that flags will not be duplicated on recursion.
|
||||
|
||||
* New variable: `MAKE_HOST' gives the name of the host architecture
|
||||
make was compiled for. This is the same value you see after 'Built for'
|
||||
@@ -81,8 +183,10 @@ http://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=101&set
|
||||
|
||||
* Behavior of MAKEFLAGS and MFLAGS is more rigorously defined. All simple
|
||||
flags are grouped together in the first word of MAKEFLAGS. No options that
|
||||
accept arguments appear there. If no simple flags are present MAKEFLAGS
|
||||
begins with a space. MFLAGS never begins with "- ".
|
||||
accept arguments appear in the first word. If no simple flags are present
|
||||
MAKEFLAGS begins with a space. Flags with both short and long versions
|
||||
always use the short versions in MAKEFLAGS. Flags are listed in
|
||||
alphabetical order using ASCII ordering. MFLAGS never begins with "- ".
|
||||
|
||||
* Setting the -r and -R options in MAKEFLAGS inside a makefile now works as
|
||||
expected, removing all built-in rules and variables, respectively.
|
||||
@@ -135,15 +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
|
||||
@@ -217,6 +312,57 @@ http://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=104&set
|
||||
after the variable name, to allow for simple, conditional, or appending
|
||||
multi-line variable assignment.
|
||||
|
||||
* VMS-specific changes:
|
||||
|
||||
* Michael Gehre (at VISTEC-SEMI dot COM) supplied a fix for a problem with
|
||||
timestamps of object modules in OLBs. The timestamps were not correctly
|
||||
adjusted to GMT based time, if the local VMS time was using a daylight
|
||||
saving algorithm and if daylight saving was switched off.
|
||||
|
||||
* John Eisenbraun (at HP dot COM) supplied fixes and and an enhancement to
|
||||
append output redirection in action lines.
|
||||
|
||||
* Rework of ctrl+c and ctrl+y handling.
|
||||
|
||||
* Fix a problem with cached strings, which showed on case-insensitive file
|
||||
systems.
|
||||
|
||||
* Build fixes for const-ified code in VMS specific sources.
|
||||
|
||||
* A note on appending the redirected output. With this change, a simple
|
||||
mechanism is implemented to make ">>" work in action lines. In VMS
|
||||
there is no simple feature like ">>" to have DCL command or program
|
||||
output redirected and appended to a file. GNU make for VMS already
|
||||
implements the redirection of output. If such a redirection is detected,
|
||||
an ">" on the action line, GNU make creates a DCL command procedure to
|
||||
execute the action and to redirect its output. Based on that, now ">>"
|
||||
is also recognized and a similar but different command procedure is
|
||||
created to implement the append. The main idea here is to create a
|
||||
temporary file which collects the output and which is appended to the
|
||||
wanted output file. Then the temporary file is deleted. This is all done
|
||||
in the command procedure to keep changes in make small and simple. This
|
||||
obviously has some limitations but it seems good enough compared with
|
||||
the current ">" implementation. (And in my opinion, redirection is not
|
||||
really what GNU make has to do.) With this approach, it may happen that
|
||||
the temporary file is not yet appended and is left in SYS$SCRATCH.
|
||||
The temporary file names look like "CMDxxxxx.". Any time the created
|
||||
command procedure can not complete, this happens. Pressing Ctrl+Y to
|
||||
abort make is one case. In case of Ctrl+Y the associated command
|
||||
procedure is left in SYS$SCRATCH as well. Its name is CMDxxxxx.COM.
|
||||
|
||||
* Change in the Ctrl+Y handling. The CtrlY handler now uses $delprc to
|
||||
delete all children. This way also actions with DCL commands will be
|
||||
stopped. As before the CtrlY handler then sends SIGQUIT to itself,
|
||||
which is handled in common code.
|
||||
|
||||
* Change in deleteing temporary command files. Temporary command files
|
||||
are now deleted in the vms child termination handler. That deletes
|
||||
them even if a Ctrl+C was pressed.
|
||||
|
||||
* The behavior of pressing Ctrl+C is not changed. It still has only an
|
||||
effect, after the current action is terminated. If that doesn't happen
|
||||
or takes too long, Ctrl+Y should be used instead.
|
||||
|
||||
|
||||
Version 3.81 (01 Apr 2006)
|
||||
|
||||
@@ -231,8 +377,8 @@ Version 3.81 (01 Apr 2006)
|
||||
any prerequisite that does not exist, even though that prerequisite
|
||||
might have caused the target to rebuild. Starting with the _next_
|
||||
release of GNU make, '$?' will contain all prerequisites that caused
|
||||
the target to be considered out of date. See this Savannah bug:
|
||||
http://savannah.gnu.org/bugs/index.php?func=detailitem&item_id=16051
|
||||
the target to be considered out of date.
|
||||
See http://savannah.gnu.org/bugs/?16051
|
||||
|
||||
* WARNING: Backward-incompatibility!
|
||||
GNU make now implements a generic "second expansion" feature on the
|
||||
@@ -341,7 +487,7 @@ Version 3.81 (01 Apr 2006)
|
||||
could be found on the system.
|
||||
|
||||
* On VMS there is now support for case-sensitive filesystems such as ODS5.
|
||||
See the readme.vms file for information.
|
||||
See the README.VMS file for information.
|
||||
|
||||
* Parallel builds (-jN) no longer require a working Bourne shell on
|
||||
Windows platforms. They work even with the stock Windows shells, such
|
||||
@@ -436,6 +582,42 @@ Version 3.80 (03 Oct 2002)
|
||||
|
||||
* Updated to autoconf 2.54 and automake 1.7. Users should not be impacted.
|
||||
|
||||
* VMS-specific changes:
|
||||
|
||||
* In default.c define variable ARCH as IA64 for VMS on Itanium systems.
|
||||
|
||||
* In makefile.vms avoid name collision for glob and globfree.
|
||||
|
||||
* This is the VMS port of GNU Make done by Hartmut.Becker@compaq.com.
|
||||
|
||||
It is based on the specific version 3.77k and on 3.78.1. 3.77k was done
|
||||
by Klaus Kämpf <kkaempf@rmi.de>, the code was based on the VMS port of
|
||||
GNU Make 3.60 by Mike Moretti.
|
||||
|
||||
It was ported on OpenVMS/Alpha V7.1, DECC V5.7-006. It was re-build and
|
||||
tested on OpenVMS/Alpha V7.2, OpenVMS/VAX 7.1 and 5.5-2. Different
|
||||
versions of DECC were used. VAXC was tried: it fails; but it doesn't
|
||||
seem worth to get it working. There are still some PTRMISMATCH warnings
|
||||
during the compile. Although perl is working on VMS the test scripts
|
||||
don't work. The function $shell is still missing.
|
||||
|
||||
There is a known bug in some of the VMS CRTLs. It is in the shipped
|
||||
versions of VMS V7.2 and V7.2-1 and in the currently (October 1999)
|
||||
available ECOs for VMS V7.1 and newer versions. It is fixed in versions
|
||||
shipped with newer VMS versions and all ECO kits after October 1999. It
|
||||
only shows up during the daylight saving time period (DST): stat()
|
||||
returns a modification time 1 hour ahead. This results in GNU make
|
||||
warning messages. For a just created source you will see:
|
||||
|
||||
$ gmake x.exe
|
||||
gmake.exe;1: *** Warning: File 'x.c' has modification time in the future
|
||||
(940582863 > 940579269)
|
||||
cc /obj=x.obj x.c
|
||||
link x.obj /exe=x.exe
|
||||
gmake.exe;1: *** Warning: Clock skew detected. Your build may be
|
||||
incomplete.
|
||||
|
||||
|
||||
A complete list of bugs fixed in this version is available here:
|
||||
|
||||
http://savannah.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=102
|
||||
@@ -491,7 +673,57 @@ Version 3.79 (04 Apr 2000)
|
||||
returned.
|
||||
|
||||
* Hartmut Becker provided many updates for the VMS port of GNU make.
|
||||
See the readme.vms file for more details.
|
||||
See the README.VMS file for more details.
|
||||
|
||||
* VMS-specific changes:
|
||||
|
||||
* Fix a problem with automatically remaking makefiles. GNU make uses an
|
||||
execve to restart itself after a successful remake of the makefile. On
|
||||
UNIX systems execve replaces the running program with a new one and
|
||||
resets all signal handling to the default. On VMS execve creates a child
|
||||
process, signal and exit handlers of the parent are still active, and,
|
||||
unfortunately, corrupt the exit code from the child. Fix in job.c:
|
||||
ignore SIGCHLD.
|
||||
|
||||
* Added some switches to reflect latest features of DECC. Modifications in
|
||||
makefile.vms.
|
||||
|
||||
* Set some definitions to reflect latest features of DECC. Modifications in
|
||||
config.h-vms (which is copied to config.h).
|
||||
|
||||
* Added extern strcmpi declaration to avoid 'implicitly declared' messages.
|
||||
Modification in make.h.
|
||||
|
||||
* Default rule for C++, conditionals for gcc (GCC_IS_NATIVE) or DEC/Digital/
|
||||
Compaq c/c++ compilers. Modifications in default.c.
|
||||
|
||||
* Usage of opendir() and friends, suppress file version. Modifications in
|
||||
dir.c.
|
||||
|
||||
* Added VMS specific code to handle ctrl+c and ctrl+y to abort make.
|
||||
Modifications in job.c.
|
||||
|
||||
* Added support to have case sensitive targets and dependencies but to
|
||||
still use case blind file names. This is especially useful for Java
|
||||
makefiles on VMS:
|
||||
|
||||
.SUFFIXES :
|
||||
.SUFFIXES : .class .java
|
||||
.java.class :
|
||||
javac "$<
|
||||
HelloWorld.class : HelloWorld.java
|
||||
|
||||
* A new macro WANT_CASE_SENSITIVE_TARGETS in config.h-vms was introduced.
|
||||
It needs to be enabled to get this feature; default is disabled. The
|
||||
macro HAVE_CASE_INSENSITIVE_FS must not be touched: it is still enabled.
|
||||
Modifications in file.c and config.h-vms.
|
||||
|
||||
* Bootstrap make to start building make is still makefile.com, but make
|
||||
needs to be re-made with a make to make a correct version: ignore all
|
||||
possible warnings, delete all objects, rename make.exe to a different
|
||||
name and run it.
|
||||
|
||||
* Made some minor modifications to the bootstrap build makefile.com.
|
||||
|
||||
Version 3.78 (22 Sep 1999)
|
||||
|
||||
@@ -594,6 +826,45 @@ Version 3.77 (28 Jul 1998)
|
||||
|
||||
* Updates to the Windows 95/NT port from Rob Tulloh (see README.W32),
|
||||
and to the DOS port from Eli Zaretski (see README.DOS).
|
||||
|
||||
* VMS-specific changes:
|
||||
|
||||
* This is the VMS port of GNU Make.
|
||||
It is based on the VMS port of GNU Make 3.60 by Mike Moretti.
|
||||
This port was done by Klaus Kämpf <kkaempf@rmi.de>
|
||||
|
||||
* There is first-level support available from proGIS Software, Germany.
|
||||
Visit their web-site at http://www.progis.de to get information
|
||||
about other vms software and forthcoming updates to gnu make.
|
||||
|
||||
* /bin/sh style I/O redirection is supported. You can now write lines like
|
||||
mcr sys$disk:[]program.exe < input.txt > output.txt &> error.txt
|
||||
|
||||
* Makefile variables are looked up in the current environment. You can set
|
||||
symbols or logicals in DCL and evaluate them in the Makefile via
|
||||
$(<name-of-symbol-or-logical>). Variables defined in the Makefile
|
||||
override VMS symbols/logicals !
|
||||
|
||||
* Functions for file names are working now. See the GNU Make manual for
|
||||
$(dir ...) and $(wildcard ...). Unix-style and VMS-style names are
|
||||
supported as arguments.
|
||||
|
||||
* The default rules are set up for GNU C. Building an executable from a
|
||||
single source file is as easy as 'make file.exe'.
|
||||
|
||||
* The variable $(ARCH) is predefined as ALPHA or VAX resp. Makefiles for
|
||||
different VMS systems can now be written by checking $(ARCH) as in
|
||||
ifeq ($(ARCH),ALPHA)
|
||||
$(ECHO) "On the Alpha"
|
||||
else
|
||||
$(ECHO) "On the VAX"
|
||||
endif
|
||||
|
||||
* Command lines of excessive length are correctly broken and written to a
|
||||
batch file in sys$scratch for later execution. There's no limit to the
|
||||
lengths of commands (and no need for .opt files :-) any more.
|
||||
|
||||
* Empty commands are handled correctly and don't end in a new DCL process.
|
||||
|
||||
Version 3.76.1 (19 Sep 1997)
|
||||
|
||||
@@ -642,8 +913,54 @@ Version 3.76 (16 Sep 1997)
|
||||
concerning this port to Eli Zaretskii <eliz@is.elta.co.il> or DJ
|
||||
Delorie <dj@delorie.com>.
|
||||
|
||||
* John W. Eaton has updated the VMS port to support libraries and VPATH.
|
||||
|
||||
* VMS-specific changes:
|
||||
|
||||
* John W. Eaton has updated the VMS port to support libraries and VPATH.
|
||||
|
||||
* The cd command is supported if it's called as $(CD). This invokes
|
||||
the 'builtin_cd' command which changes the directory.
|
||||
Calling 'set def' doesn't do the trick, since a sub-shell is
|
||||
spawned for this command, the directory is changed *in this sub-shell*
|
||||
and the sub-shell ends.
|
||||
|
||||
* Libraries are not supported. They were in GNU Make 3.60 but somehow I
|
||||
didn't care porting the code. If there is enough interest, I'll do it at
|
||||
some later time.
|
||||
|
||||
* The variable $^ separates files with commas instead of spaces (It's the
|
||||
natural thing to do for VMS).
|
||||
|
||||
* See defaults.c for VMS default suffixes and my definitions for default
|
||||
rules and variables.
|
||||
|
||||
* The shell function is not implemented yet.
|
||||
|
||||
* Load average routines haven't been implemented for VMS yet.
|
||||
|
||||
* The default include directory for including other makefiles is
|
||||
SYS$SYSROOT:[SYSLIB] (I don't remember why I didn't just use
|
||||
SYS$LIBRARY: instead; maybe it wouldn't work that way).
|
||||
|
||||
* The default makefiles make looks for are: makefile.vms, gnumakefile,
|
||||
makefile., and gnumakefile. .
|
||||
|
||||
* The stat() function and handling of time stamps in VMS is broken, so I
|
||||
replaced it with a hack in vmsfunctions.c. I will provide a full rewrite
|
||||
somewhere in the future. Be warned, the time resolution inside make is
|
||||
less than what vms provides. This might be a problem on the faster Alphas.
|
||||
|
||||
* You can use a : in a filename only if you precede it with a backslash ('\').
|
||||
E.g.- hobbes\:[bogas.files]
|
||||
|
||||
* Make ignores success, informational, or warning errors (-S-, -I-, or -W-).
|
||||
But it will stop on -E- and -F- errors. (unless you do something
|
||||
to override this in your makefile, or whatever).
|
||||
|
||||
* Remote stuff isn't implemented yet.
|
||||
|
||||
* Multiple line DCL commands, such as "if" statements, must be put inside
|
||||
command files. You can run a command file by using \@.
|
||||
|
||||
Version 3.75 (27 Aug 1996)
|
||||
|
||||
* The directory messages printed by `-w' and implicitly in sub-makes,
|
||||
@@ -664,6 +981,14 @@ Version 3.75 (27 Aug 1996)
|
||||
* Rob Tulloh of Tivoli Systems has contributed a port to Windows NT or 95.
|
||||
See README.W32 for details, and direct all Windows-related questions to
|
||||
<rob_tulloh@tivoli.com>.
|
||||
|
||||
* VMS-specific changes:
|
||||
|
||||
* Lots of default settings are adapted for VMS. See default.c.
|
||||
|
||||
* Long command lines are now converted to command files.
|
||||
|
||||
* Comma (',') as a separator is now allowed. See makefile.vms for an example.
|
||||
|
||||
Version 3.73 (05 Apr 1995)
|
||||
|
||||
@@ -759,7 +1084,7 @@ Version 3.69 (07 Nov 1993)
|
||||
have reversed the change made in version 3.68 because it turned out to
|
||||
cause a paradoxical situation in cases like:
|
||||
|
||||
export variable = $(shell echo value)
|
||||
export variable = $(shell echo value)
|
||||
|
||||
When Make attempted to put this variable in the environment for a
|
||||
recipe, it would try expand the value by running the shell command
|
||||
@@ -782,8 +1107,8 @@ Version 3.68 (28 Jul 1993)
|
||||
foo.a(b.o) bar.a(c.o) bar.a(d.o)'.
|
||||
|
||||
* A suffix rule `.X.a' now produces two pattern rules:
|
||||
(%.o): %.X # Previous versions produced only this.
|
||||
%.a: %.X # Now produces this as well, just like other suffixes.
|
||||
(%.o): %.X # Previous versions produced only this.
|
||||
%.a: %.X # Now produces this as well, just like other suffixes.
|
||||
|
||||
* The new flag `--warn-undefined-variables' says to issue a warning message
|
||||
whenever Make expands a reference to an undefined variable.
|
||||
@@ -853,15 +1178,15 @@ Version 3.63 (22 Jan 1993)
|
||||
no longer automatically put into the environments of the recipe lines that
|
||||
Make runs. Instead, only variables specified on the command line or in
|
||||
the environment are exported by default. To export others, use:
|
||||
export VARIABLE
|
||||
export VARIABLE
|
||||
or you can define variables with:
|
||||
export VARIABLE = VALUE
|
||||
export VARIABLE = VALUE
|
||||
or:
|
||||
export VARIABLE := VALUE
|
||||
export VARIABLE := VALUE
|
||||
You can use just:
|
||||
export
|
||||
export
|
||||
or:
|
||||
.EXPORT_ALL_VARIABLES:
|
||||
.EXPORT_ALL_VARIABLES:
|
||||
to get the old behavior. See the node `Variables/Recursion' in the manual
|
||||
for a full description.
|
||||
|
||||
@@ -881,9 +1206,9 @@ Version 3.63 (22 Jan 1993)
|
||||
|
||||
* A single `include' directive can now specify more than one makefile to
|
||||
include, like this:
|
||||
include file1 file2
|
||||
include file1 file2
|
||||
You can also use shell file name patterns in an `include' directive:
|
||||
include *.mk
|
||||
include *.mk
|
||||
|
||||
* The default directories to search for included makefiles, and for
|
||||
libraries specified with `-lNAME', are now set by configuration.
|
||||
@@ -1019,7 +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.
|
||||
@@ -1199,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,6 +89,7 @@ OBJS = \
|
||||
$(OUTDIR)/hash.obj \
|
||||
$(OUTDIR)/implicit.obj \
|
||||
$(OUTDIR)/job.obj \
|
||||
$(OUTDIR)/load.obj \
|
||||
$(OUTDIR)/main.obj \
|
||||
$(OUTDIR)/misc.obj \
|
||||
$(OUTDIR)/output.obj \
|
||||
@@ -105,6 +106,8 @@ OBJS = \
|
||||
$(OUTDIR)/fnmatch.obj \
|
||||
$(OUTDIR)/dirent.obj \
|
||||
$(OUTDIR)/pathstuff.obj \
|
||||
$(OUTDIR)/posixfcn.obj \
|
||||
$(OUTDIR)/w32os.obj \
|
||||
$(guile)
|
||||
|
||||
$(OUTDIR)/make.exe: $(OUTDIR) $(OBJS)
|
||||
@@ -121,5 +124,9 @@ $(OUTDIR)/fnmatch.obj : glob/fnmatch.c
|
||||
$(CC) $(CFLAGS) /c $?
|
||||
$(OUTDIR)/dirent.obj : w32/compat/dirent.c
|
||||
$(CC) $(CFLAGS) /c $?
|
||||
$(OUTDIR)/posixfcn.obj : w32/compat/posixfcn.c
|
||||
$(CC) $(CFLAGS) /c $?
|
||||
$(OUTDIR)/pathstuff.obj : w32/pathstuff.c
|
||||
$(CC) $(CFLAGS) /c $?
|
||||
$(OUTDIR)/w32os.obj : w32/w32os.c
|
||||
$(CC) $(CFLAGS) /c $?
|
||||
|
||||
@@ -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
|
||||
|
||||
103
README.git
103
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
|
||||
@@ -220,19 +243,27 @@ work on it:
|
||||
Where to Announce
|
||||
-----------------
|
||||
|
||||
Create the announcement in a text file, then sign it with GPG.
|
||||
Create the announcement in a text file, using 'git shortlog',
|
||||
then sign it with GPG:
|
||||
|
||||
gpg --clearsign <announcement.txt>
|
||||
|
||||
Upload to gnu.org, then login and send from my account there.
|
||||
Or, use your mail client's PGP/GPG signing capabilities.
|
||||
|
||||
To: bug-make@gnu.org, help-make@gnu.org, make-w32@gnu.org
|
||||
CC: info-gnu@gnu.org
|
||||
BCC: make-alpha@gnu.org
|
||||
Announce the release:
|
||||
|
||||
Add a news item to the Savannah project site.
|
||||
* For release candidate builds:
|
||||
To: bug-make@gnu.org
|
||||
CC: coordinator@translationproject.org
|
||||
BCC: help-make@gnu.org, make-w32@gnu.org, make-alpha@gnu.org
|
||||
|
||||
Add an update to freshmeat.net.
|
||||
* For release builds
|
||||
To: info-gnu@gnu.org, bug-make@gnu.org
|
||||
CC: coordinator@translationproject.org
|
||||
BCC: help-make@gnu.org, make-w32@gnu.org, make-alpha@gnu.org
|
||||
|
||||
* Add a news item to the Savannah project site.
|
||||
* Add an update to freecode.com (nee freshmeat.net)
|
||||
|
||||
|
||||
Appendix A - For The Brave
|
||||
|
||||
@@ -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
|
||||
|
||||
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;
|
||||
|
||||
|
||||
378
arscan.c
378
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. */
|
||||
@@ -340,7 +420,8 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
|
||||
#ifdef SARMAG
|
||||
{
|
||||
char buf[SARMAG];
|
||||
register int nread = read (desc, buf, SARMAG);
|
||||
int nread;
|
||||
EINTRLOOP (nread, read (desc, buf, SARMAG));
|
||||
if (nread != SARMAG || memcmp (buf, ARMAG, SARMAG))
|
||||
{
|
||||
(void) close (desc);
|
||||
@@ -350,8 +431,8 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
|
||||
#else
|
||||
#ifdef AIAMAG
|
||||
{
|
||||
register int nread = read (desc, &fl_header, FL_HSZ);
|
||||
|
||||
int nread;
|
||||
EINTRLOOP (nread, read (desc, &fl_header, FL_HSZ));
|
||||
if (nread != FL_HSZ)
|
||||
{
|
||||
(void) close (desc);
|
||||
@@ -362,17 +443,20 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
|
||||
re-read the header into the "big" structure. */
|
||||
if (!memcmp (fl_header.fl_magic, AIAMAGBIG, SAIAMAG))
|
||||
{
|
||||
off_t o;
|
||||
|
||||
big_archive = 1;
|
||||
|
||||
/* seek back to beginning of archive */
|
||||
if (lseek (desc, 0, 0) < 0)
|
||||
EINTRLOOP (o, lseek (desc, 0, 0));
|
||||
if (o < 0)
|
||||
{
|
||||
(void) close (desc);
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* re-read the header into the "big" structure */
|
||||
nread = read (desc, &fl_header_big, FL_HSZ_BIG);
|
||||
EINTRLOOP (nread, read (desc, &fl_header_big, FL_HSZ_BIG));
|
||||
if (nread != FL_HSZ_BIG)
|
||||
{
|
||||
(void) close (desc);
|
||||
@@ -395,7 +479,8 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
|
||||
#else
|
||||
unsigned short int buf;
|
||||
#endif
|
||||
register int nread = read (desc, &buf, sizeof (buf));
|
||||
int nread;
|
||||
EINTRLOOP (nread, read (desc, &buf, sizeof (buf)));
|
||||
if (nread != sizeof (buf) || buf != ARMAG)
|
||||
{
|
||||
(void) close (desc);
|
||||
@@ -462,10 +547,12 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
|
||||
int long_name = 0;
|
||||
#endif
|
||||
long int eltsize;
|
||||
int eltmode;
|
||||
unsigned int eltmode;
|
||||
long int fnval;
|
||||
off_t o;
|
||||
|
||||
if (lseek (desc, member_offset, 0) < 0)
|
||||
EINTRLOOP (o, lseek (desc, member_offset, 0));
|
||||
if (o < 0)
|
||||
{
|
||||
(void) close (desc);
|
||||
return -2;
|
||||
@@ -477,8 +564,8 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
|
||||
#ifdef AIAMAGBIG
|
||||
if (big_archive)
|
||||
{
|
||||
nread = read (desc, &member_header_big,
|
||||
AR_MEMHDR_SZ(member_header_big) );
|
||||
EINTRLOOP (nread, read (desc, &member_header_big,
|
||||
AR_MEMHDR_SZ(member_header_big)));
|
||||
|
||||
if (nread != AR_MEMHDR_SZ(member_header_big))
|
||||
{
|
||||
@@ -487,7 +574,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
|
||||
}
|
||||
|
||||
sscanf (member_header_big.ar_namlen, "%4d", &name_len);
|
||||
nread = read (desc, name, name_len);
|
||||
EINTRLOOP (nread, read (desc, name, name_len));
|
||||
|
||||
if (nread != name_len)
|
||||
{
|
||||
@@ -509,8 +596,8 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
|
||||
else
|
||||
#endif
|
||||
{
|
||||
nread = read (desc, &member_header,
|
||||
AR_MEMHDR_SZ(member_header) );
|
||||
EINTRLOOP (nread, read (desc, &member_header,
|
||||
AR_MEMHDR_SZ(member_header)));
|
||||
|
||||
if (nread != AR_MEMHDR_SZ(member_header))
|
||||
{
|
||||
@@ -519,7 +606,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
|
||||
}
|
||||
|
||||
sscanf (member_header.ar_namlen, "%4d", &name_len);
|
||||
nread = read (desc, name, name_len);
|
||||
EINTRLOOP (nread, read (desc, name, name_len));
|
||||
|
||||
if (nread != name_len)
|
||||
{
|
||||
@@ -547,7 +634,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
|
||||
eltmode, arg);
|
||||
|
||||
#else /* Not AIAMAG. */
|
||||
nread = read (desc, &member_header, AR_HDR_SIZE);
|
||||
EINTRLOOP (nread, read (desc, &member_header, AR_HDR_SIZE));
|
||||
if (nread == 0)
|
||||
/* No data left means end of file; that is OK. */
|
||||
break;
|
||||
@@ -616,7 +703,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
|
||||
int namesize = atoi (name + 3);
|
||||
|
||||
name = alloca (namesize + 1);
|
||||
nread = read (desc, name, namesize);
|
||||
EINTRLOOP (nread, read (desc, name, namesize));
|
||||
if (nread != namesize)
|
||||
{
|
||||
close (desc);
|
||||
@@ -687,7 +774,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
|
||||
char *limit;
|
||||
|
||||
namemap = alloca (eltsize);
|
||||
nread = read (desc, namemap, eltsize);
|
||||
EINTRLOOP (nread, read (desc, namemap, eltsize));
|
||||
if (nread != eltsize)
|
||||
{
|
||||
(void) close (desc);
|
||||
@@ -751,9 +838,32 @@ ar_name_equal (const char *name, const char *mem, int truncated)
|
||||
#endif /* !__hpux && !cray */
|
||||
#endif /* !AIAMAG */
|
||||
}
|
||||
#endif /* !VMS */
|
||||
|
||||
return !strcmp (name, mem);
|
||||
#else
|
||||
/* VMS members do not have suffixes, but the filenames usually
|
||||
have.
|
||||
Do we need to strip VMS disk/directory format paths?
|
||||
|
||||
Most VMS compilers etc. by default are case insensitive
|
||||
but produce uppercase external names, incl. module names.
|
||||
However the VMS librarian (ar) and the linker by default
|
||||
are case sensitive: they take what they get, usually
|
||||
uppercase names. So for the non-default settings of the
|
||||
compilers etc. there is a need to have a case sensitive
|
||||
mode. */
|
||||
{
|
||||
int len;
|
||||
len = strlen(mem);
|
||||
int match;
|
||||
char *dot;
|
||||
if ((dot=strrchr(name,'.')))
|
||||
match = (len == dot - name) && !strncasecmp(name, mem, len);
|
||||
else
|
||||
match = !strcasecmp (name, mem);
|
||||
return match;
|
||||
}
|
||||
#endif /* !VMS */
|
||||
}
|
||||
|
||||
#ifndef VMS
|
||||
@@ -762,7 +872,7 @@ static long int
|
||||
ar_member_pos (int desc UNUSED, const char *mem, int truncated,
|
||||
long int hdrpos, long int datapos UNUSED, long int size UNUSED,
|
||||
long int date UNUSED, int uid UNUSED, int gid UNUSED,
|
||||
int mode UNUSED, const void *name)
|
||||
unsigned int mode UNUSED, const void *name)
|
||||
{
|
||||
if (!ar_name_equal (name, mem, truncated))
|
||||
return 0;
|
||||
@@ -782,7 +892,8 @@ ar_member_touch (const char *arname, const char *memname)
|
||||
long int pos = ar_scan (arname, ar_member_pos, memname);
|
||||
int fd;
|
||||
struct ar_hdr ar_hdr;
|
||||
int i;
|
||||
off_t o;
|
||||
int r;
|
||||
unsigned int ui;
|
||||
struct stat statbuf;
|
||||
|
||||
@@ -791,28 +902,32 @@ ar_member_touch (const char *arname, const char *memname)
|
||||
if (!pos)
|
||||
return 1;
|
||||
|
||||
fd = open (arname, O_RDWR, 0666);
|
||||
EINTRLOOP (fd, open (arname, O_RDWR, 0666));
|
||||
if (fd < 0)
|
||||
return -3;
|
||||
/* Read in this member's header */
|
||||
if (lseek (fd, pos, 0) < 0)
|
||||
EINTRLOOP (o, lseek (fd, pos, 0));
|
||||
if (o < 0)
|
||||
goto lose;
|
||||
if (AR_HDR_SIZE != read (fd, &ar_hdr, AR_HDR_SIZE))
|
||||
EINTRLOOP (r, read (fd, &ar_hdr, AR_HDR_SIZE));
|
||||
if (r != AR_HDR_SIZE)
|
||||
goto lose;
|
||||
/* Write back the header, thus touching the archive file. */
|
||||
if (lseek (fd, pos, 0) < 0)
|
||||
EINTRLOOP (o, lseek (fd, pos, 0));
|
||||
if (o < 0)
|
||||
goto lose;
|
||||
if (AR_HDR_SIZE != write (fd, &ar_hdr, AR_HDR_SIZE))
|
||||
EINTRLOOP (r, write (fd, &ar_hdr, AR_HDR_SIZE));
|
||||
if (r != AR_HDR_SIZE)
|
||||
goto lose;
|
||||
/* The file's mtime is the time we we want. */
|
||||
EINTRLOOP (i, fstat (fd, &statbuf));
|
||||
if (i < 0)
|
||||
EINTRLOOP (r, fstat (fd, &statbuf));
|
||||
if (r < 0)
|
||||
goto lose;
|
||||
#if defined(ARFMAG) || defined(ARFZMAG) || defined(AIAMAG) || defined(WINDOWS32)
|
||||
/* Advance member's time to that time */
|
||||
for (ui = 0; ui < sizeof ar_hdr.ar_date; ui++)
|
||||
ar_hdr.ar_date[ui] = ' ';
|
||||
sprintf (TOCHAR (ar_hdr.ar_date), "%ld", (long int) statbuf.st_mtime);
|
||||
sprintf (TOCHAR (ar_hdr.ar_date), "%lu", (long unsigned) statbuf.st_mtime);
|
||||
#ifdef AIAMAG
|
||||
ar_hdr.ar_date[strlen (ar_hdr.ar_date)] = ' ';
|
||||
#endif
|
||||
@@ -820,17 +935,19 @@ ar_member_touch (const char *arname, const char *memname)
|
||||
ar_hdr.ar_date = statbuf.st_mtime;
|
||||
#endif
|
||||
/* Write back this member's header */
|
||||
if (lseek (fd, pos, 0) < 0)
|
||||
EINTRLOOP (o, lseek (fd, pos, 0));
|
||||
if (o < 0)
|
||||
goto lose;
|
||||
if (AR_HDR_SIZE != write (fd, &ar_hdr, AR_HDR_SIZE))
|
||||
EINTRLOOP (r, write (fd, &ar_hdr, AR_HDR_SIZE));
|
||||
if (r != AR_HDR_SIZE)
|
||||
goto lose;
|
||||
close (fd);
|
||||
return 0;
|
||||
|
||||
lose:
|
||||
i = errno;
|
||||
r = errno;
|
||||
close (fd);
|
||||
errno = i;
|
||||
errno = r;
|
||||
return -3;
|
||||
}
|
||||
#endif
|
||||
@@ -840,7 +957,8 @@ ar_member_touch (const char *arname, const char *memname)
|
||||
long int
|
||||
describe_member (int desc, const char *name, int truncated,
|
||||
long int hdrpos, long int datapos, long int size,
|
||||
long int date, int uid, int gid, int mode, const void *arg)
|
||||
long int date, int uid, int gid, unsigned int mode,
|
||||
const void *arg)
|
||||
{
|
||||
extern char *ctime ();
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Shell script to build GNU Make in the absence of any 'make' program.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1993-2013 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1993-2016 Free Software Foundation, Inc.
|
||||
# This file is part of GNU Make.
|
||||
#
|
||||
# GNU Make is free software; you can redistribute it and/or modify it under
|
||||
@@ -22,11 +22,11 @@
|
||||
|
||||
srcdir='@srcdir@'
|
||||
CC='@CC@'
|
||||
CFLAGS='@CFLAGS@'
|
||||
CFLAGS='@CFLAGS@ @GUILE_CFLAGS@'
|
||||
CPPFLAGS='@CPPFLAGS@'
|
||||
LDFLAGS='@LDFLAGS@'
|
||||
LDFLAGS='@AM_LDFLAGS@ @LDFLAGS@'
|
||||
ALLOCA='@ALLOCA@'
|
||||
LOADLIBES='@LIBS@ @LIBINTL@'
|
||||
LOADLIBES='@LIBS@ @GUILE_LIBS@ @LIBINTL@'
|
||||
eval extras=\'@LIBOBJS@\'
|
||||
REMOTE='@REMOTE@'
|
||||
GLOBLIB='@GLOBLIB@'
|
||||
@@ -46,7 +46,7 @@ includedir=${prefix}/include
|
||||
localedir=${prefix}/share/locale
|
||||
aliaspath=${localedir}${PATH_SEPARATOR}.
|
||||
|
||||
defines="-DALIASPATH=\"${aliaspath}\" -DLOCALEDIR=\"${localedir}\" -DLIBDIR=\"${libdir}\" -DINCLUDEDIR=\"${includedir}\""' @DEFS@'
|
||||
defines="-DLOCALEDIR=\"${localedir}\" -DLIBDIR=\"${libdir}\" -DINCLUDEDIR=\"${includedir}\""' @DEFS@'
|
||||
|
||||
# Exit as soon as any command fails.
|
||||
set -e
|
||||
|
||||
493
build_w32.bat
Normal file → Executable file
493
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,292 +15,217 @@ rem
|
||||
rem You should have received a copy of the GNU General Public License along
|
||||
rem with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
if "%1" == "-h" GoTo Usage
|
||||
if "%1" == "--help" GoTo Usage
|
||||
if not exist config.h.W32.template GoTo NotSCM
|
||||
sed -n "s/^AC_INIT(\[GNU make\],\[\([^]]\+\)\].*/s,%%VERSION%%,\1,g/p" configure.ac > config.h.W32.sed
|
||||
echo s,%%PACKAGE%%,make,g >> config.h.W32.sed
|
||||
sed -f config.h.W32.sed config.h.W32.template > config.h.W32
|
||||
echo static const char *const GUILE_module_defn = ^" \> gmk-default.h
|
||||
sed -e "s/;.*//" -e "/^[ \t]*$/d" -e "s/\"/\\\\\"/g" -e "s/$/ \\/" gmk-default.scm >> gmk-default.h
|
||||
echo ^";>> gmk-default.h
|
||||
:NotSCM
|
||||
copy config.h.W32 config.h
|
||||
call :Reset
|
||||
|
||||
if "%1" == "-h" goto Usage
|
||||
if "%1" == "--help" goto Usage
|
||||
|
||||
set MAKE=gnumake
|
||||
set GUILE=Y
|
||||
set COMPILER=msvc
|
||||
|
||||
rem Guile configuration
|
||||
set GUILECFLAGS=
|
||||
set GUILELIBS=
|
||||
set GUILESRC=
|
||||
set NOGUILE=
|
||||
set OPT=-O2
|
||||
set COMPILER=
|
||||
set PKGMSC=
|
||||
:ParseSW
|
||||
if "%1" == "--debug" GoTo SetOpt
|
||||
if "%1" == "--without-guile" GoTo NoGuile
|
||||
if "%1" == "gcc" GoTo SetCC
|
||||
if "%1" == "" GoTo ChkGuile
|
||||
:SetOpt
|
||||
set OPT=-O0
|
||||
if "%1" == "--debug" goto SetDebug
|
||||
if "%1" == "--without-guile" goto NoGuile
|
||||
if "%1" == "gcc" goto SetCC
|
||||
if "%1" == "" goto DoneSW
|
||||
|
||||
:SetDebug
|
||||
set DEBUG=Y
|
||||
shift
|
||||
GoTo ParseSW
|
||||
goto ParseSW
|
||||
|
||||
:NoGuile
|
||||
set NOGUILE=Y
|
||||
echo "Building without Guile"
|
||||
set GUILE=N
|
||||
echo Building without Guile
|
||||
shift
|
||||
GoTo ParseSW
|
||||
goto ParseSW
|
||||
|
||||
:SetCC
|
||||
set COMPILER=gcc
|
||||
echo "Building with GCC"
|
||||
echo Building with GCC
|
||||
shift
|
||||
GoTo ParseSW
|
||||
rem Build with Guile is supported only on NT and later versions
|
||||
:ChkGuile
|
||||
if "%NOGUILE%" == "Y" GoTo GuileDone
|
||||
if not "%OS%" == "Windows_NT" GoTo NoGuile
|
||||
pkg-config --help > guile.tmp 2> NUL
|
||||
if ERRORLEVEL 1 GoTo NoPkgCfg
|
||||
echo "Checking for Guile 2.0"
|
||||
if not "%COMPILER%" == "gcc" set PKGMSC=--msvc-syntax
|
||||
pkg-config --cflags --short-errors "guile-2.0" > guile.tmp
|
||||
if not ERRORLEVEL 1 set /P GUILECFLAGS= < guile.tmp
|
||||
pkg-config --libs --static --short-errors %PKGMSC% "guile-2.0" > guile.tmp
|
||||
if not ERRORLEVEL 1 set /P GUILELIBS= < guile.tmp
|
||||
if not "%GUILECFLAGS%" == "" GoTo GuileDone
|
||||
echo "Checking for Guile 1.8"
|
||||
pkg-config --cflags --short-errors "guile-1.8" > guile.tmp
|
||||
if not ERRORLEVEL 1 set /P GUILECFLAGS= < guile.tmp
|
||||
pkg-config --libs --static --short-errors %PKGMSC% "guile-1.8" > guile.tmp
|
||||
if not ERRORLEVEL 1 set /P GUILELIBS= < guile.tmp
|
||||
if not "%GUILECFLAGS%" == "" GoTo GuileDone
|
||||
echo "No Guile found, building without Guile"
|
||||
GoTo GuileDone
|
||||
:NoPkgCfg
|
||||
echo "pkg-config not found, building without Guile"
|
||||
:GuileDone
|
||||
if not "%GUILECFLAGS%" == "" echo "Guile found, building with Guile"
|
||||
if not "%GUILECFLAGS%" == "" set GUILESRC=guile.c
|
||||
if not "%GUILECFLAGS%" == "" set GUILECFLAGS=%GUILECFLAGS% -DHAVE_GUILE
|
||||
if "%COMPILER%" == "gcc" if "%OPT%" == "-O0" echo "Building without compiler optimizations"
|
||||
cd w32\subproc
|
||||
echo.
|
||||
echo "Creating the subproc library"
|
||||
%ComSpec% /c build.bat
|
||||
cd ..\..
|
||||
goto ParseSW
|
||||
|
||||
if exist link.dbg del link.dbg
|
||||
if exist link.rel del link.rel
|
||||
rem Build with Guile is supported only on NT and later versions
|
||||
:DoneSW
|
||||
echo.
|
||||
echo "Creating GNU Make for Windows 9X/NT/2K/XP/Vista/7/8"
|
||||
if "%COMPILER%" == "gcc" GoTo GCCBuild
|
||||
set make=gnumake
|
||||
echo Creating GNU Make for Windows 9X/NT/2K/XP/Vista/7/8
|
||||
if "%DEBUG%" == "Y" echo Building without compiler optimizations
|
||||
|
||||
if "%COMPILER%" == "gcc" goto GccBuild
|
||||
|
||||
set OUTDIR=.\WinRel
|
||||
set "OPTS=/O2 /D NDEBUG"
|
||||
set LINKOPTS=
|
||||
if "%DEBUG%" == "Y" set OUTDIR=.\WinDebug
|
||||
if "%DEBUG%" == "Y" set "OPTS=/Zi /Od /D _DEBUG"
|
||||
if "%DEBUG%" == "Y" set LINKOPTS=/DEBUG
|
||||
call :Build
|
||||
goto Done
|
||||
|
||||
:GccBuild
|
||||
set OUTDIR=.\GccRel
|
||||
set OPTS=-O2
|
||||
if "%DEBUG%" == "Y" set OPTS=-O0
|
||||
if "%DEBUG%" == "Y" set OUTDIR=.\GccDebug
|
||||
call :Build
|
||||
goto Done
|
||||
|
||||
:Done
|
||||
call :Reset
|
||||
goto :EOF
|
||||
|
||||
:Build
|
||||
:: Clean the directory if it exists
|
||||
if exist %OUTDIR%\nul rmdir /S /Q %OUTDIR%
|
||||
|
||||
:: Recreate it
|
||||
mkdir %OUTDIR%
|
||||
mkdir %OUTDIR%\glob
|
||||
mkdir %OUTDIR%\w32
|
||||
mkdir %OUTDIR%\w32\compat
|
||||
mkdir %OUTDIR%\w32\subproc
|
||||
|
||||
if "%GUILE%" == "Y" call :ChkGuile
|
||||
|
||||
echo.
|
||||
echo Compiling %OUTDIR% version
|
||||
|
||||
if exist config.h.W32.template call :ConfigSCM
|
||||
copy config.h.W32 %OUTDIR%\config.h
|
||||
|
||||
call :Compile ar
|
||||
call :Compile arscan
|
||||
call :Compile commands
|
||||
call :Compile default
|
||||
call :Compile dir
|
||||
call :Compile expand
|
||||
call :Compile file
|
||||
call :Compile function
|
||||
call :Compile getloadavg
|
||||
call :Compile getopt
|
||||
call :Compile getopt1
|
||||
call :Compile glob\fnmatch
|
||||
call :Compile glob\glob
|
||||
call :Compile guile GUILE
|
||||
call :Compile hash
|
||||
call :Compile implicit
|
||||
call :Compile job
|
||||
call :Compile load
|
||||
call :Compile loadapi
|
||||
call :Compile main GUILE
|
||||
call :Compile misc
|
||||
call :Compile output
|
||||
call :Compile read
|
||||
call :Compile remake
|
||||
call :Compile remote-stub
|
||||
call :Compile rule
|
||||
call :Compile signame
|
||||
call :Compile strcache
|
||||
call :Compile variable
|
||||
call :Compile version
|
||||
call :Compile vpath
|
||||
call :Compile w32\compat\posixfcn
|
||||
call :Compile w32\pathstuff
|
||||
call :Compile w32\subproc\misc
|
||||
call :Compile w32\subproc\sub_proc
|
||||
call :Compile w32\subproc\w32err
|
||||
call :Compile w32\w32os
|
||||
|
||||
if not "%COMPILER%" == "gcc" call :Compile w32\compat\dirent
|
||||
|
||||
call :Link
|
||||
|
||||
echo.
|
||||
if not exist %OUTDIR%\%MAKE%.exe echo %OUTDIR% build FAILED!
|
||||
if exist %OUTDIR%\%MAKE%.exe echo %OUTDIR% build succeeded.
|
||||
goto :EOF
|
||||
|
||||
:Compile
|
||||
set EXTRAS=
|
||||
if "%2" == "GUILE" set "EXTRAS=%GUILECFLAGS%"
|
||||
if "%COMPILER%" == "gcc" goto GccCompile
|
||||
|
||||
:: MSVC Compile
|
||||
echo on
|
||||
if not exist .\WinDebug\nul mkdir .\WinDebug
|
||||
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D TIVOLI /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c variable.c
|
||||
echo WinDebug\variable.obj >>link.dbg
|
||||
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c rule.c
|
||||
echo WinDebug\rule.obj >>link.dbg
|
||||
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c remote-stub.c
|
||||
echo WinDebug\remote-stub.obj >>link.dbg
|
||||
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c commands.c
|
||||
echo WinDebug\commands.obj >>link.dbg
|
||||
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c file.c
|
||||
echo WinDebug\file.obj >>link.dbg
|
||||
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c getloadavg.c
|
||||
echo WinDebug\getloadavg.obj >>link.dbg
|
||||
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c default.c
|
||||
echo WinDebug\default.obj >>link.dbg
|
||||
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c signame.c
|
||||
echo WinDebug\signame.obj >>link.dbg
|
||||
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c expand.c
|
||||
echo WinDebug\expand.obj >>link.dbg
|
||||
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c dir.c
|
||||
echo WinDebug\dir.obj >>link.dbg
|
||||
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od %GUILECFLAGS% /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c main.c
|
||||
echo WinDebug\main.obj >>link.dbg
|
||||
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c getopt1.c
|
||||
echo WinDebug\getopt1.obj >>link.dbg
|
||||
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c job.c
|
||||
echo WinDebug\job.obj >>link.dbg
|
||||
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c output.c
|
||||
echo WinDebug\output.obj >>link.dbg
|
||||
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c read.c
|
||||
echo WinDebug\read.obj >>link.dbg
|
||||
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c version.c
|
||||
echo WinDebug\version.obj >>link.dbg
|
||||
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c getopt.c
|
||||
echo WinDebug\getopt.obj >>link.dbg
|
||||
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c arscan.c
|
||||
echo WinDebug\arscan.obj >>link.dbg
|
||||
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c hash.c
|
||||
echo WinDebug\hash.obj >>link.dbg
|
||||
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c strcache.c
|
||||
echo WinDebug\strcache.obj >>link.dbg
|
||||
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c remake.c
|
||||
echo WinDebug\remake.obj >>link.dbg
|
||||
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c misc.c
|
||||
echo WinDebug\misc.obj >>link.dbg
|
||||
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c ar.c
|
||||
echo WinDebug\ar.obj >>link.dbg
|
||||
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c function.c
|
||||
echo WinDebug\function.obj >>link.dbg
|
||||
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c vpath.c
|
||||
echo WinDebug\vpath.obj >>link.dbg
|
||||
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c implicit.c
|
||||
echo WinDebug\implicit.obj >>link.dbg
|
||||
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c loadapi.c
|
||||
echo WinDebug\loadapi.obj >>link.dbg
|
||||
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c load.c
|
||||
echo WinDebug\load.obj >>link.dbg
|
||||
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c .\w32\compat\dirent.c
|
||||
echo WinDebug\dirent.obj >>link.dbg
|
||||
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c .\w32\compat\posixfcn.c
|
||||
echo WinDebug\posixfcn.obj >>link.dbg
|
||||
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c .\glob\glob.c
|
||||
echo WinDebug\glob.obj >>link.dbg
|
||||
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c .\glob\fnmatch.c
|
||||
echo WinDebug\fnmatch.obj >>link.dbg
|
||||
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c .\w32\pathstuff.c
|
||||
echo WinDebug\pathstuff.obj >>link.dbg
|
||||
if "%GUILESRC%" == "" GoTo LinkDbg
|
||||
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od %GUILECFLAGS%% /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c guile.c
|
||||
echo WinDebug\guile.obj >>link.dbg
|
||||
:LinkDbg
|
||||
echo off
|
||||
echo "Linking WinDebug/%make%.exe"
|
||||
rem link.exe %GUILELIBS% kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib w32\subproc\windebug\subproc.lib /NOLOGO /SUBSYSTEM:console /INCREMENTAL:yes /PDB:.\WinDebug/%make%.pdb /DEBUG /OUT:.\WinDebug/%make%.exe .\WinDebug/variable.obj .\WinDebug/rule.obj .\WinDebug/remote-stub.obj .\WinDebug/commands.obj .\WinDebug/file.obj .\WinDebug/getloadavg.obj .\WinDebug/default.obj .\WinDebug/signame.obj .\WinDebug/expand.obj .\WinDebug/dir.obj .\WinDebug/main.obj .\WinDebug/getopt1.obj .\WinDebug/job.obj .\WinDebug/output.obj .\WinDebug/read.obj .\WinDebug/version.obj .\WinDebug/getopt.obj .\WinDebug/arscan.obj .\WinDebug/remake.obj .\WinDebug/hash.obj .\WinDebug/strcache.obj .\WinDebug/misc.obj .\WinDebug/ar.obj .\WinDebug/function.obj .\WinDebug/vpath.obj .\WinDebug/implicit.obj .\WinDebug/dirent.obj .\WinDebug/glob.obj .\WinDebug/fnmatch.obj .\WinDebug/pathstuff.obj
|
||||
echo %GUILELIBS% kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib w32\subproc\windebug\subproc.lib >>link.dbg
|
||||
link.exe /NOLOGO /SUBSYSTEM:console /INCREMENTAL:yes /PDB:.\WinDebug/%make%.pdb /DEBUG /OUT:.\WinDebug/%make%.exe @link.dbg
|
||||
if not exist .\WinDebug/%make%.exe echo "WinDebug build failed"
|
||||
if exist .\WinDebug/%make%.exe echo "WinDebug build succeeded!"
|
||||
if not exist .\WinRel\nul mkdir .\WinRel
|
||||
echo on
|
||||
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /D TIVOLI /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c variable.c
|
||||
echo WinRel\variable.obj >>link.rel
|
||||
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c rule.c
|
||||
echo WinRel\rule.obj >>link.rel
|
||||
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c remote-stub.c
|
||||
echo WinRel\remote-stub.obj >>link.rel
|
||||
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c commands.c
|
||||
echo WinRel\commands.obj >>link.rel
|
||||
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c file.c
|
||||
echo WinRel\file.obj >>link.rel
|
||||
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c getloadavg.c
|
||||
echo WinRel\getloadavg.obj >>link.rel
|
||||
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c default.c
|
||||
echo WinRel\default.obj >>link.rel
|
||||
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c signame.c
|
||||
echo WinRel\signame.obj >>link.rel
|
||||
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c expand.c
|
||||
echo WinRel\expand.obj >>link.rel
|
||||
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c dir.c
|
||||
echo WinRel\dir.obj >>link.rel
|
||||
cl.exe /nologo /MT /W4 /GX /YX /O2 %GUILECFLAGS% /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c main.c
|
||||
echo WinRel\main.obj >>link.rel
|
||||
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c getopt1.c
|
||||
echo WinRel\getopt1.obj >>link.rel
|
||||
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c job.c
|
||||
echo WinRel\job.obj >>link.rel
|
||||
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c output.c
|
||||
echo WinRel\output.obj >>link.rel
|
||||
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c read.c
|
||||
echo WinRel\read.obj >>link.rel
|
||||
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c version.c
|
||||
echo WinRel\version.obj >>link.rel
|
||||
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c getopt.c
|
||||
echo WinRel\getopt.obj >>link.rel
|
||||
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c arscan.c
|
||||
echo WinRel\arscan.obj >>link.rel
|
||||
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c remake.c
|
||||
echo WinRel\remake.obj >>link.rel
|
||||
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c hash.c
|
||||
echo WinRel\hash.obj >>link.rel
|
||||
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c strcache.c
|
||||
echo WinRel\strcache.obj >>link.rel
|
||||
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c misc.c
|
||||
echo WinRel\misc.obj >>link.rel
|
||||
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c ar.c
|
||||
echo WinRel\ar.obj >>link.rel
|
||||
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c function.c
|
||||
echo WinRel\function.obj >>link.rel
|
||||
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c vpath.c
|
||||
echo WinRel\vpath.obj >>link.rel
|
||||
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c implicit.c
|
||||
echo WinRel\implicit.obj >>link.rel
|
||||
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c loadapi.c
|
||||
echo WinRel\loadapi.obj >>link.rel
|
||||
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c load.c
|
||||
echo WinRel\load.obj >>link.rel
|
||||
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c .\w32\compat\dirent.c
|
||||
echo WinRel\dirent.obj >>link.rel
|
||||
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c .\w32\compat\posixfcn.c
|
||||
echo WinRel\posixfcn.obj >>link.rel
|
||||
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c .\glob\glob.c
|
||||
echo WinRel\glob.obj >>link.rel
|
||||
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c .\glob\fnmatch.c
|
||||
echo WinRel\fnmatch.obj >>link.rel
|
||||
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c .\w32\pathstuff.c
|
||||
echo WinRel\pathstuff.obj >>link.rel
|
||||
if "%GUILESRC%" == "" GoTo LinkRel
|
||||
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c guile.c
|
||||
echo WinRel\guile.obj >>link.rel
|
||||
:LinkRel
|
||||
echo off
|
||||
echo "Linking WinRel/%make%.exe"
|
||||
rem link.exe %GUILELIBS% kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib w32\subproc\winrel\subproc.lib /NOLOGO /SUBSYSTEM:console /INCREMENTAL:no /PDB:.\WinRel/%make%.pdb /OUT:.\WinRel/%make%.exe .\WinRel/variable.obj .\WinRel/rule.obj .\WinRel/remote-stub.obj .\WinRel/commands.obj .\WinRel/file.obj .\WinRel/getloadavg.obj .\WinRel/default.obj .\WinRel/signame.obj .\WinRel/expand.obj .\WinRel/dir.obj .\WinRel/main.obj .\WinRel/getopt1.obj .\WinRel/job.obj .\WinRel/output.obj .\WinRel/read.obj .\WinRel/version.obj .\WinRel/getopt.obj .\WinRel/arscan.obj .\WinRel/remake.obj .\WinRel/misc.obj .\WinRel/hash.obj .\WinRel/strcache.obj .\WinRel/ar.obj .\WinRel/function.obj .\WinRel/vpath.obj .\WinRel/implicit.obj .\WinRel/dirent.obj .\WinRel/glob.obj .\WinRel/fnmatch.obj .\WinRel/pathstuff.obj
|
||||
echo %GUILELIBS% kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib w32\subproc\winrel\subproc.lib >>link.rel
|
||||
link.exe /NOLOGO /SUBSYSTEM:console /INCREMENTAL:no /PDB:.\WinRel/%make%.pdb /OUT:.\WinRel/%make%.exe @link.rel
|
||||
if not exist .\WinRel/%make%.exe echo "WinRel build failed"
|
||||
if exist .\WinRel/%make%.exe echo "WinRel build succeeded!"
|
||||
set make=
|
||||
GoTo BuildEnd
|
||||
:GCCBuild
|
||||
echo on
|
||||
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c variable.c
|
||||
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c rule.c
|
||||
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c remote-stub.c
|
||||
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c commands.c
|
||||
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c file.c
|
||||
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c getloadavg.c
|
||||
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c default.c
|
||||
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c signame.c
|
||||
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c expand.c
|
||||
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c dir.c
|
||||
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H %GUILECFLAGS% -c main.c
|
||||
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c getopt1.c
|
||||
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c job.c
|
||||
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c output.c
|
||||
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c read.c
|
||||
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c version.c
|
||||
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c getopt.c
|
||||
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c arscan.c
|
||||
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c remake.c
|
||||
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c hash.c
|
||||
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c strcache.c
|
||||
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c misc.c
|
||||
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c ar.c
|
||||
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c function.c
|
||||
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c vpath.c
|
||||
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c implicit.c
|
||||
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c loadapi.c
|
||||
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c load.c
|
||||
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c ./glob/glob.c -o glob.o
|
||||
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c ./glob/fnmatch.c -o fnmatch.o
|
||||
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c ./w32/pathstuff.c -o pathstuff.o
|
||||
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c ./w32/compat/posixfcn.c -o posixfcn.o
|
||||
cl.exe /nologo /MT /W4 /EHsc %OPTS% /I %OUTDIR% /I . /I glob /I w32/include /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR%OUTDIR% /Fp%OUTDIR%\%MAKE%.pch /Fo%OUTDIR%\%1.obj /Fd%OUTDIR%\%MAKE%.pdb %EXTRAS% /c %1.c
|
||||
@echo off
|
||||
set GUILEOBJ=
|
||||
if "%GUILESRC%" == "" GoTo LinkGCC
|
||||
set GUILEOBJ=guile.o
|
||||
echo %OUTDIR%\%1.obj >>%OUTDIR%\link.sc
|
||||
goto :EOF
|
||||
|
||||
:GccCompile
|
||||
:: GCC Compile
|
||||
echo on
|
||||
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% %GUILECFLAGS% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c guile.c
|
||||
:LinkGCC
|
||||
gcc -mthreads -Wall -std=gnu99 -gdwarf-2 -g3 %OPTS% -I%OUTDIR% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H %EXTRAS% -o %OUTDIR%\%1.o -c %1.c
|
||||
@echo off
|
||||
Rem The version NN of libgnumake-NN.dll.a should be bumped whenever
|
||||
Rem the API changes in binary-incompatible manner.
|
||||
@echo on
|
||||
gcc -mthreads -gdwarf-2 -g3 -o gnumake.exe variable.o rule.o remote-stub.o commands.o file.o getloadavg.o default.o signame.o expand.o dir.o main.o getopt1.o %GUILEOBJ% job.o output.o read.o version.o getopt.o arscan.o remake.o misc.o hash.o strcache.o ar.o function.o vpath.o implicit.o loadapi.o load.o glob.o fnmatch.o pathstuff.o posixfcn.o w32_misc.o sub_proc.o w32err.o %GUILELIBS% -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -luuid -lodbc32 -lodbccp32 -Wl,--out-implib=libgnumake-1.dll.a
|
||||
@GoTo BuildEnd
|
||||
goto :EOF
|
||||
|
||||
:Link
|
||||
echo Linking %OUTDIR%/%MAKE%.exe
|
||||
if "%COMPILER%" == "gcc" goto GccLink
|
||||
|
||||
:: MSVC Link
|
||||
echo %GUILELIBS% kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib >>%OUTDIR%\link.sc
|
||||
echo on
|
||||
link.exe /NOLOGO /SUBSYSTEM:console /PDB:%OUTDIR%\%MAKE%.pdb %LINKOPTS% /OUT:%OUTDIR%\%MAKE%.exe @%OUTDIR%\link.sc
|
||||
@echo off
|
||||
goto :EOF
|
||||
|
||||
:GccLink
|
||||
:: GCC Link
|
||||
echo on
|
||||
gcc -mthreads -gdwarf-2 -g3 -o %OUTDIR%\%MAKE%.exe %OUTDIR%\variable.o %OUTDIR%\rule.o %OUTDIR%\remote-stub.o %OUTDIR%\commands.o %OUTDIR%\file.o %OUTDIR%\getloadavg.o %OUTDIR%\default.o %OUTDIR%\signame.o %OUTDIR%\expand.o %OUTDIR%\dir.o %OUTDIR%\main.o %OUTDIR%\getopt1.o %OUTDIR%\guile.o %OUTDIR%\job.o %OUTDIR%\output.o %OUTDIR%\read.o %OUTDIR%\version.o %OUTDIR%\getopt.o %OUTDIR%\arscan.o %OUTDIR%\remake.o %OUTDIR%\misc.o %OUTDIR%\hash.o %OUTDIR%\strcache.o %OUTDIR%\ar.o %OUTDIR%\function.o %OUTDIR%\vpath.o %OUTDIR%\implicit.o %OUTDIR%\loadapi.o %OUTDIR%\load.o %OUTDIR%\glob\glob.o %OUTDIR%\glob\fnmatch.o %OUTDIR%\w32\pathstuff.o %OUTDIR%\w32\compat\posixfcn.o %OUTDIR%\w32\w32os.o %OUTDIR%\w32\subproc\misc.o %OUTDIR%\w32\subproc\sub_proc.o %OUTDIR%\w32\subproc\w32err.o %GUILELIBS% -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -luuid -lodbc32 -lodbccp32 -Wl,--out-implib=%OUTDIR%\libgnumake-1.dll.a
|
||||
@echo off
|
||||
goto :EOF
|
||||
|
||||
:ConfigSCM
|
||||
echo Generating config from SCM templates
|
||||
sed -n "s/^AC_INIT(\[GNU make\],\[\([^]]\+\)\].*/s,%%VERSION%%,\1,g/p" configure.ac > %OUTDIR%\config.h.W32.sed
|
||||
echo s,%%PACKAGE%%,make,g >> %OUTDIR%\config.h.W32.sed
|
||||
sed -f %OUTDIR%\config.h.W32.sed config.h.W32.template > config.h.W32
|
||||
echo static const char *const GUILE_module_defn = ^" \> gmk-default.h
|
||||
sed -e "s/;.*//" -e "/^[ \t]*$/d" -e "s/\"/\\\\\"/g" -e "s/$/ \\\/" gmk-default.scm >> gmk-default.h
|
||||
echo ^";>> gmk-default.h
|
||||
goto :EOF
|
||||
|
||||
:ChkGuile
|
||||
if not "%OS%" == "Windows_NT" goto NoGuile
|
||||
pkg-config --help > %OUTDIR%\guile.tmp 2> NUL
|
||||
if ERRORLEVEL 1 goto NoPkgCfg
|
||||
|
||||
echo Checking for Guile 2.0
|
||||
if not "%COMPILER%" == "gcc" set PKGMSC=--msvc-syntax
|
||||
pkg-config --cflags --short-errors "guile-2.0" > %OUTDIR%\guile.tmp
|
||||
if not ERRORLEVEL 1 set /P GUILECFLAGS= < %OUTDIR%\guile.tmp
|
||||
|
||||
pkg-config --libs --static --short-errors %PKGMSC% "guile-2.0" > %OUTDIR%\guile.tmp
|
||||
if not ERRORLEVEL 1 set /P GUILELIBS= < %OUTDIR%\guile.tmp
|
||||
|
||||
if not "%GUILECFLAGS%" == "" goto GuileDone
|
||||
|
||||
echo Checking for Guile 1.8
|
||||
pkg-config --cflags --short-errors "guile-1.8" > %OUTDIR%\guile.tmp
|
||||
if not ERRORLEVEL 1 set /P GUILECFLAGS= < %OUTDIR%\guile.tmp
|
||||
|
||||
pkg-config --libs --static --short-errors %PKGMSC% "guile-1.8" > %OUTDIR%\guile.tmp
|
||||
if not ERRORLEVEL 1 set /P GUILELIBS= < %OUTDIR%\guile.tmp
|
||||
|
||||
if not "%GUILECFLAGS%" == "" goto GuileDone
|
||||
|
||||
echo No Guile found, building without Guile
|
||||
goto GuileDone
|
||||
|
||||
:NoPkgCfg
|
||||
echo pkg-config not found, building without Guile
|
||||
|
||||
:GuileDone
|
||||
if "%GUILECFLAGS%" == "" goto :EOF
|
||||
|
||||
echo Guile found, building with Guile
|
||||
set "GUILECFLAGS=%GUILECFLAGS% -DHAVE_GUILE"
|
||||
goto :EOF
|
||||
|
||||
:Usage
|
||||
echo Usage: %0 [options] [gcc]
|
||||
echo Options:
|
||||
@@ -308,14 +233,18 @@ echo. --debug For GCC only, make a debug build
|
||||
echo. (MSVC build always makes both debug and release)
|
||||
echo. --without-guile Do not compile Guile support even if found
|
||||
echo. --help Display these instructions and exit
|
||||
:BuildEnd
|
||||
@echo off
|
||||
set GUILEOBJ=
|
||||
set GUILESRC=
|
||||
set GUILELIBS=
|
||||
set GUILECFLAGS=
|
||||
set PKGMSC=
|
||||
set OPT=
|
||||
goto :EOF
|
||||
|
||||
:Reset
|
||||
set COMPILER=
|
||||
set DEBUG=
|
||||
set GUILE=
|
||||
set GUILECFLAGS=
|
||||
set GUILELIBS=
|
||||
set LINKOPTS=
|
||||
set MAKE=
|
||||
set NOGUILE=
|
||||
echo on
|
||||
set OPTS=
|
||||
set OUTDIR=
|
||||
set PKGMSC=
|
||||
goto :EOF
|
||||
|
||||
35
commands.c
35
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,7 +449,7 @@ execute_file_commands (struct file *file)
|
||||
the commands are nothing but whitespace. */
|
||||
|
||||
for (p = file->cmds->commands; *p != '\0'; ++p)
|
||||
if (!isspace ((unsigned char)*p) && *p != '-' && *p != '@')
|
||||
if (!ISSPACE (*p) && *p != '-' && *p != '@' && *p != '+')
|
||||
break;
|
||||
if (*p == '\0')
|
||||
{
|
||||
@@ -587,7 +583,7 @@ fatal_error_signal (int sig)
|
||||
if (sig == SIGQUIT)
|
||||
/* We don't want to send ourselves SIGQUIT, because it will
|
||||
cause a core dump. Just exit instead. */
|
||||
exit (EXIT_FAILURE);
|
||||
exit (MAKE_TROUBLE);
|
||||
#endif
|
||||
|
||||
#ifdef WINDOWS32
|
||||
@@ -627,11 +623,13 @@ delete_target (struct file *file, const char *on_behalf_of)
|
||||
if (ar_member_date (file->name) != file_date)
|
||||
{
|
||||
if (on_behalf_of)
|
||||
error (NILF, _("*** [%s] Archive member '%s' may be bogus; not deleted"),
|
||||
on_behalf_of, file->name);
|
||||
OSS (error, NILF,
|
||||
_("*** [%s] Archive member '%s' may be bogus; not deleted"),
|
||||
on_behalf_of, file->name);
|
||||
else
|
||||
error (NILF, _("*** Archive member '%s' may be bogus; not deleted"),
|
||||
file->name);
|
||||
OS (error, NILF,
|
||||
_("*** Archive member '%s' may be bogus; not deleted"),
|
||||
file->name);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -643,9 +641,10 @@ delete_target (struct file *file, const char *on_behalf_of)
|
||||
&& FILE_TIMESTAMP_STAT_MODTIME (file->name, st) != file->last_mtime)
|
||||
{
|
||||
if (on_behalf_of)
|
||||
error (NILF, _("*** [%s] Deleting file '%s'"), on_behalf_of, file->name);
|
||||
OSS (error, NILF,
|
||||
_("*** [%s] Deleting file '%s'"), on_behalf_of, file->name);
|
||||
else
|
||||
error (NILF, _("*** Deleting file '%s'"), file->name);
|
||||
OS (error, NILF, _("*** Deleting file '%s'"), file->name);
|
||||
if (unlink (file->name) < 0
|
||||
&& errno != ENOENT) /* It disappeared; so what. */
|
||||
perror_with_name ("unlink: ", file->name);
|
||||
|
||||
@@ -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%"
|
||||
|
||||
95
configure.ac
95
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.91],[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 &&
|
||||
@@ -428,7 +432,6 @@ AS_CASE([$host],
|
||||
[AM_CONDITIONAL([WINDOWSENV], [true])
|
||||
w32_target_env=yes
|
||||
AC_DEFINE([WINDOWS32], [1], [Use platform specific coding])
|
||||
AC_DEFINE([OUTPUT_SYNC], [1], [Support synchronized output])
|
||||
AC_DEFINE([HAVE_DOS_PATHS], [1], [Use platform specific coding])
|
||||
])
|
||||
|
||||
@@ -499,7 +502,7 @@ AS_IF([test "x$make_cv_load" = xno && test "x$user_load" = xyes],
|
||||
|
||||
# Specify what files are to be created.
|
||||
AC_CONFIG_FILES([Makefile glob/Makefile po/Makefile.in config/Makefile \
|
||||
doc/Makefile w32/Makefile])
|
||||
doc/Makefile w32/Makefile tests/config-flags.pm])
|
||||
|
||||
# OK, do it!
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
172
default.c
172
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,8 +680,8 @@ set_default_suffixes (void)
|
||||
else
|
||||
{
|
||||
struct dep *d;
|
||||
char *p = default_suffixes;
|
||||
suffix_file->deps = enter_prereqs (PARSE_SIMPLE_SEQ (&p, struct dep),
|
||||
const char *p = default_suffixes;
|
||||
suffix_file->deps = enter_prereqs (PARSE_SIMPLE_SEQ ((char **)&p, struct dep),
|
||||
NULL);
|
||||
for (d = suffix_file->deps; d; d = d->next)
|
||||
d->file->builtin = 1;
|
||||
@@ -564,7 +698,7 @@ set_default_suffixes (void)
|
||||
void
|
||||
install_default_suffix_rules (void)
|
||||
{
|
||||
char **s;
|
||||
const char **s;
|
||||
|
||||
if (no_builtin_rules_flag)
|
||||
return;
|
||||
@@ -576,7 +710,7 @@ install_default_suffix_rules (void)
|
||||
assert (f->cmds == 0);
|
||||
f->cmds = xmalloc (sizeof (struct commands));
|
||||
f->cmds->fileinfo.filenm = 0;
|
||||
f->cmds->commands = s[1];
|
||||
f->cmds->commands = xstrdup (s[1]);
|
||||
f->cmds->command_lines = 0;
|
||||
f->cmds->recipe_prefix = RECIPEPREFIX_DEFAULT;
|
||||
f->builtin = 1;
|
||||
|
||||
99
dep.h
99
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,34 +37,37 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
#define RM_NOFLAG 0
|
||||
|
||||
/* Structure representing one dependency of a file.
|
||||
Each struct file's 'deps' points to a chain of these,
|
||||
chained through the 'next'. 'stem' is the stem for this
|
||||
dep line of static pattern rule or NULL.
|
||||
Each struct file's 'deps' points to a chain of these, through 'next'.
|
||||
'stem' is the stem for this dep line of static pattern rule or NULL. */
|
||||
|
||||
Note that the first two words of this match a struct nameseq. */
|
||||
#define DEP(_t) \
|
||||
NAMESEQ (_t); \
|
||||
struct file *file; \
|
||||
const char *stem; \
|
||||
unsigned short flags : 8; \
|
||||
unsigned short changed : 1; \
|
||||
unsigned short ignore_mtime : 1; \
|
||||
unsigned short staticpattern : 1; \
|
||||
unsigned short need_2nd_expansion : 1
|
||||
|
||||
struct dep
|
||||
{
|
||||
struct dep *next;
|
||||
const char *name;
|
||||
const char *stem;
|
||||
struct file *file;
|
||||
unsigned int changed : 8;
|
||||
unsigned int ignore_mtime : 1;
|
||||
unsigned int staticpattern : 1;
|
||||
unsigned int need_2nd_expansion : 1;
|
||||
unsigned int dontcare : 1;
|
||||
DEP (struct dep);
|
||||
};
|
||||
|
||||
/* Structure representing one goal.
|
||||
The goals to be built constitute a chain of these, chained through 'next'.
|
||||
'stem' is not used, but it's simpler to include and ignore it. */
|
||||
|
||||
/* Structure used in chains of names, for parsing and globbing. */
|
||||
|
||||
struct nameseq
|
||||
struct goaldep
|
||||
{
|
||||
struct nameseq *next;
|
||||
const char *name;
|
||||
DEP (struct goaldep);
|
||||
unsigned short error;
|
||||
floc floc;
|
||||
};
|
||||
|
||||
/* Options for parsing lists of filenames. */
|
||||
|
||||
#define PARSEFS_NONE 0x0000
|
||||
#define PARSEFS_NOSTRIP 0x0001
|
||||
#define PARSEFS_NOAR 0x0002
|
||||
@@ -78,15 +93,39 @@ char *tilde_expand (const char *name);
|
||||
struct nameseq *ar_glob (const char *arname, const char *member_pattern, unsigned int size);
|
||||
#endif
|
||||
|
||||
#define dep_name(d) ((d)->name == 0 ? (d)->file->name : (d)->name)
|
||||
#define dep_name(d) ((d)->name ? (d)->name : (d)->file->name)
|
||||
|
||||
#define alloc_dep() (xcalloc (sizeof (struct dep)))
|
||||
#define free_ns(_n) free (_n)
|
||||
#define free_dep(_d) free_ns (_d)
|
||||
#define alloc_seq_elt(_t) xcalloc (sizeof (_t))
|
||||
void free_ns_chain (struct nameseq *n);
|
||||
|
||||
#if defined(MAKE_MAINTAINER_MODE) && defined(__GNUC__)
|
||||
/* Use inline to get real type-checking. */
|
||||
#define SI static inline
|
||||
SI struct nameseq *alloc_ns() { return alloc_seq_elt (struct nameseq); }
|
||||
SI struct dep *alloc_dep() { return alloc_seq_elt (struct dep); }
|
||||
SI struct goaldep *alloc_goaldep() { return alloc_seq_elt (struct goaldep); }
|
||||
|
||||
SI void free_ns(struct nameseq *n) { free (n); }
|
||||
SI void free_dep(struct dep *d) { free_ns ((struct nameseq *)d); }
|
||||
SI void free_goaldep(struct goaldep *g) { free_dep ((struct dep *)g); }
|
||||
|
||||
SI void free_dep_chain(struct dep *d) { free_ns_chain((struct nameseq *)d); }
|
||||
SI void free_goal_chain(struct goaldep *g) { free_dep_chain((struct dep *)g); }
|
||||
#else
|
||||
# define alloc_ns() alloc_seq_elt (struct nameseq)
|
||||
# define alloc_dep() alloc_seq_elt (struct dep)
|
||||
# define alloc_goaldep() alloc_seq_elt (struct goaldep)
|
||||
|
||||
# define free_ns(_n) free (_n)
|
||||
# define free_dep(_d) free_ns (_d)
|
||||
# define free_goaldep(_g) free_dep (_g)
|
||||
|
||||
# define free_dep_chain(_d) free_ns_chain ((struct nameseq *)(_d))
|
||||
# define free_goal_chain(_g) free_ns_chain ((struct nameseq *)(_g))
|
||||
#endif
|
||||
|
||||
struct dep *copy_dep_chain (const struct dep *d);
|
||||
void free_dep_chain (struct dep *d);
|
||||
void free_ns_chain (struct nameseq *n);
|
||||
struct dep *read_all_makefiles (const char **makefiles);
|
||||
void eval_buffer (char *buffer, const gmk_floc *floc);
|
||||
enum update_status update_goal_chain (struct dep *goals);
|
||||
|
||||
struct goaldep *read_all_makefiles (const char **makefiles);
|
||||
void eval_buffer (char *buffer, const floc *floc);
|
||||
enum update_status update_goal_chain (struct goaldep *goals);
|
||||
|
||||
239
dir.c
239
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,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "makeint.h"
|
||||
#include "hash.h"
|
||||
#include "filedef.h"
|
||||
#include "dep.h"
|
||||
|
||||
#ifdef HAVE_DIRENT_H
|
||||
@@ -141,6 +142,32 @@ downcase (const char *filename)
|
||||
|
||||
#ifdef VMS
|
||||
|
||||
static char *
|
||||
downcase_inplace(char *filename)
|
||||
{
|
||||
char *name;
|
||||
name = filename;
|
||||
while (*name != '\0')
|
||||
{
|
||||
*name = tolower ((unsigned char)*name);
|
||||
++name;
|
||||
}
|
||||
return filename;
|
||||
}
|
||||
|
||||
#ifndef _USE_STD_STAT
|
||||
/* VMS 8.2 fixed the VMS stat output to have unique st_dev and st_ino
|
||||
when _USE_STD_STAT is used on the compile line.
|
||||
|
||||
Prior to _USE_STD_STAT support, the st_dev is a pointer to thread
|
||||
static memory containing the device of the last filename looked up.
|
||||
|
||||
Todo: find out if the ino_t still needs to be faked on a directory.
|
||||
*/
|
||||
|
||||
/* Define this if the older VMS_INO_T is needed */
|
||||
#define VMS_INO_T 1
|
||||
|
||||
static int
|
||||
vms_hash (const char *name)
|
||||
{
|
||||
@@ -199,6 +226,10 @@ vmsstat_dir (const char *name, struct stat *st)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
# define stat(__path, __sbuf) vmsstat_dir (__path, __sbuf)
|
||||
|
||||
#endif /* _USE_STD_STAT */
|
||||
#endif /* VMS */
|
||||
|
||||
/* Hash table of directories. */
|
||||
@@ -217,14 +248,14 @@ struct directory_contents
|
||||
* qualified name of the directory. Beware though, this is also
|
||||
* unreliable. I'm open to suggestion on a better way to emulate inode. */
|
||||
char *path_key;
|
||||
int ctime;
|
||||
int mtime; /* controls check for stale directory cache */
|
||||
int fs_flags; /* FS_FAT, FS_NTFS, ... */
|
||||
time_t ctime;
|
||||
time_t mtime; /* controls check for stale directory cache */
|
||||
int fs_flags; /* FS_FAT, FS_NTFS, ... */
|
||||
# define FS_FAT 0x1
|
||||
# define FS_NTFS 0x2
|
||||
# define FS_UNKNOWN 0x4
|
||||
#else
|
||||
# ifdef VMS
|
||||
# ifdef VMS_INO_T
|
||||
ino_t ino[3];
|
||||
# else
|
||||
ino_t ino;
|
||||
@@ -245,7 +276,7 @@ directory_contents_hash_1 (const void *key_0)
|
||||
ISTRING_HASH_1 (key->path_key, hash);
|
||||
hash ^= ((unsigned int) key->dev << 4) ^ (unsigned int) key->ctime;
|
||||
#else
|
||||
# ifdef VMS
|
||||
# ifdef VMS_INO_T
|
||||
hash = (((unsigned int) key->dev << 4)
|
||||
^ ((unsigned int) key->ino[0]
|
||||
+ (unsigned int) key->ino[1]
|
||||
@@ -268,7 +299,7 @@ directory_contents_hash_2 (const void *key_0)
|
||||
ISTRING_HASH_2 (key->path_key, hash);
|
||||
hash ^= ((unsigned int) key->dev << 4) ^ (unsigned int) ~key->ctime;
|
||||
#else
|
||||
# ifdef VMS
|
||||
# ifdef VMS_INO_T
|
||||
hash = (((unsigned int) key->dev << 4)
|
||||
^ ~((unsigned int) key->ino[0]
|
||||
+ (unsigned int) key->ino[1]
|
||||
@@ -307,7 +338,7 @@ directory_contents_hash_cmp (const void *xv, const void *yv)
|
||||
if (result)
|
||||
return result;
|
||||
#else
|
||||
# ifdef VMS
|
||||
# ifdef VMS_INO_T
|
||||
result = MAKECMP(x->ino[0], y->ino[0]);
|
||||
if (result)
|
||||
return result;
|
||||
@@ -374,7 +405,7 @@ static unsigned int open_directories = 0;
|
||||
struct dirfile
|
||||
{
|
||||
const char *name; /* Name of the file. */
|
||||
short length;
|
||||
size_t length;
|
||||
short impossible; /* This file is impossible. */
|
||||
};
|
||||
|
||||
@@ -418,13 +449,6 @@ find_directory (const char *name)
|
||||
struct directory **dir_slot;
|
||||
struct directory dir_key;
|
||||
|
||||
#ifdef VMS
|
||||
if ((*name == '.') && (*(name+1) == 0))
|
||||
name = "[]";
|
||||
else
|
||||
name = vmsify (name,1);
|
||||
#endif
|
||||
|
||||
dir_key.name = name;
|
||||
dir_slot = (struct directory **) hash_find_slot (&directories, &dir_key);
|
||||
dir = *dir_slot;
|
||||
@@ -438,7 +462,12 @@ find_directory (const char *name)
|
||||
|
||||
dir = xmalloc (sizeof (struct directory));
|
||||
#if defined(HAVE_CASE_INSENSITIVE_FS) && defined(VMS)
|
||||
dir->name = strcache_add_len (downcase (name), p - name);
|
||||
/* Todo: Why is this only needed on VMS? */
|
||||
{
|
||||
char *lname = downcase_inplace (xstrdup (name));
|
||||
dir->name = strcache_add_len (lname, p - name);
|
||||
free (lname);
|
||||
}
|
||||
#else
|
||||
dir->name = strcache_add_len (name, p - name);
|
||||
#endif
|
||||
@@ -446,9 +475,7 @@ find_directory (const char *name)
|
||||
/* The directory is not in the name hash table.
|
||||
Find its device and inode numbers, and look it up by them. */
|
||||
|
||||
#ifdef VMS
|
||||
r = vmsstat_dir (name, &st);
|
||||
#elif defined(WINDOWS32)
|
||||
#if defined(WINDOWS32)
|
||||
{
|
||||
char tem[MAXPATHLEN], *tstart, *tend;
|
||||
|
||||
@@ -491,7 +518,7 @@ find_directory (const char *name)
|
||||
dc_key.path_key = w32_path = w32ify (name, 1);
|
||||
dc_key.ctime = st.st_ctime;
|
||||
#else
|
||||
# ifdef VMS
|
||||
# ifdef VMS_INO_T
|
||||
dc_key.ino[0] = st.st_ino[0];
|
||||
dc_key.ino[1] = st.st_ino[1];
|
||||
dc_key.ino[2] = st.st_ino[2];
|
||||
@@ -536,7 +563,7 @@ find_directory (const char *name)
|
||||
else
|
||||
dc->fs_flags = FS_UNKNOWN;
|
||||
#else
|
||||
# ifdef VMS
|
||||
# ifdef VMS_INO_T
|
||||
dc->ino[0] = st.st_ino[0];
|
||||
dc->ino[1] = st.st_ino[1];
|
||||
dc->ino[2] = st.st_ino[2];
|
||||
@@ -601,11 +628,6 @@ dir_contents_file_exists_p (struct directory_contents *dir,
|
||||
if (filename != 0)
|
||||
_fnlwr (filename); /* lower case for FAT drives */
|
||||
#endif
|
||||
|
||||
#ifdef VMS
|
||||
filename = vmsify (filename,0);
|
||||
#endif
|
||||
|
||||
if (filename != 0)
|
||||
{
|
||||
struct dirfile dirfile_key;
|
||||
@@ -673,12 +695,14 @@ dir_contents_file_exists_p (struct directory_contents *dir,
|
||||
if (d == 0)
|
||||
{
|
||||
if (errno)
|
||||
fatal (NILF, "INTERNAL: readdir: %s\n", strerror (errno));
|
||||
pfatal_with_name ("INTERNAL: readdir");
|
||||
break;
|
||||
}
|
||||
|
||||
#if defined(VMS) && defined(HAVE_DIRENT_H)
|
||||
/* In VMS we get file versions too, which have to be stripped off */
|
||||
/* In VMS we get file versions too, which have to be stripped off.
|
||||
Some versions of VMS return versions on Unix files even when
|
||||
the feature option to strip them is set. */
|
||||
{
|
||||
char *p = strrchr (d->d_name, ';');
|
||||
if (p)
|
||||
@@ -702,7 +726,8 @@ dir_contents_file_exists_p (struct directory_contents *dir,
|
||||
{
|
||||
df = xmalloc (sizeof (struct dirfile));
|
||||
#if defined(HAVE_CASE_INSENSITIVE_FS) && defined(VMS)
|
||||
df->name = strcache_add_len (downcase (d->d_name), len);
|
||||
/* TODO: Why is this only needed on VMS? */
|
||||
df->name = strcache_add_len (downcase_inplace (d->d_name), len);
|
||||
#else
|
||||
df->name = strcache_add_len (d->d_name, len);
|
||||
#endif
|
||||
@@ -733,6 +758,15 @@ dir_contents_file_exists_p (struct directory_contents *dir,
|
||||
int
|
||||
dir_file_exists_p (const char *dirname, const char *filename)
|
||||
{
|
||||
#ifdef VMS
|
||||
if ((filename != NULL) && (dirname != NULL))
|
||||
{
|
||||
int want_vmsify;
|
||||
want_vmsify = (strpbrk (dirname, ":<[") != NULL);
|
||||
if (want_vmsify)
|
||||
filename = vmsify (filename, 0);
|
||||
}
|
||||
#endif
|
||||
return dir_contents_file_exists_p (find_directory (dirname)->contents,
|
||||
filename);
|
||||
}
|
||||
@@ -751,14 +785,24 @@ file_exists_p (const char *name)
|
||||
return ar_member_date (name) != (time_t) -1;
|
||||
#endif
|
||||
|
||||
#ifdef VMS
|
||||
dirend = strrchr (name, ']');
|
||||
if (dirend == 0)
|
||||
dirend = strrchr (name, ':');
|
||||
if (dirend == 0)
|
||||
return dir_file_exists_p ("[]", name);
|
||||
#else /* !VMS */
|
||||
dirend = strrchr (name, '/');
|
||||
#ifdef VMS
|
||||
if (dirend == 0)
|
||||
{
|
||||
dirend = strrchr (name, ']');
|
||||
dirend == NULL ? dirend : dirend++;
|
||||
}
|
||||
if (dirend == 0)
|
||||
{
|
||||
dirend = strrchr (name, '>');
|
||||
dirend == NULL ? dirend : dirend++;
|
||||
}
|
||||
if (dirend == 0)
|
||||
{
|
||||
dirend = strrchr (name, ':');
|
||||
dirend == NULL ? dirend : dirend++;
|
||||
}
|
||||
#endif /* VMS */
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
/* Forward and backslashes might be mixed. We need the rightmost one. */
|
||||
{
|
||||
@@ -773,10 +817,9 @@ file_exists_p (const char *name)
|
||||
if (dirend == 0)
|
||||
#ifndef _AMIGA
|
||||
return dir_file_exists_p (".", name);
|
||||
#else /* !VMS && !AMIGA */
|
||||
#else /* !AMIGA */
|
||||
return dir_file_exists_p ("", name);
|
||||
#endif /* AMIGA */
|
||||
#endif /* VMS */
|
||||
|
||||
slash = dirend;
|
||||
if (dirend == name)
|
||||
@@ -795,7 +838,13 @@ file_exists_p (const char *name)
|
||||
p[dirend - name] = '\0';
|
||||
dirname = p;
|
||||
}
|
||||
return dir_file_exists_p (dirname, slash + 1);
|
||||
#ifdef VMS
|
||||
if (*slash == '/')
|
||||
slash++;
|
||||
#else
|
||||
slash++;
|
||||
#endif
|
||||
return dir_file_exists_p (dirname, slash);
|
||||
}
|
||||
|
||||
/* Mark FILENAME as 'impossible' for 'file_impossible_p'.
|
||||
@@ -810,16 +859,25 @@ file_impossible (const char *filename)
|
||||
struct directory *dir;
|
||||
struct dirfile *new;
|
||||
|
||||
#ifdef VMS
|
||||
dirend = strrchr (p, ']');
|
||||
if (dirend == 0)
|
||||
dirend = strrchr (p, ':');
|
||||
dirend++;
|
||||
if (dirend == (char *)1)
|
||||
dir = find_directory ("[]");
|
||||
#else
|
||||
dirend = strrchr (p, '/');
|
||||
# ifdef HAVE_DOS_PATHS
|
||||
#ifdef VMS
|
||||
if (dirend == NULL)
|
||||
{
|
||||
dirend = strrchr (p, ']');
|
||||
dirend == NULL ? dirend : dirend++;
|
||||
}
|
||||
if (dirend == NULL)
|
||||
{
|
||||
dirend = strrchr (p, '>');
|
||||
dirend == NULL ? dirend : dirend++;
|
||||
}
|
||||
if (dirend == NULL)
|
||||
{
|
||||
dirend = strrchr (p, ':');
|
||||
dirend == NULL ? dirend : dirend++;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
/* Forward and backslashes might be mixed. We need the rightmost one. */
|
||||
{
|
||||
const char *bslash = strrchr (p, '\\');
|
||||
@@ -829,14 +887,13 @@ file_impossible (const char *filename)
|
||||
if (!dirend && p[0] && p[1] == ':')
|
||||
dirend = p + 1;
|
||||
}
|
||||
# endif /* HAVE_DOS_PATHS */
|
||||
#endif /* HAVE_DOS_PATHS */
|
||||
if (dirend == 0)
|
||||
# ifdef _AMIGA
|
||||
#ifdef _AMIGA
|
||||
dir = find_directory ("");
|
||||
# else /* !VMS && !AMIGA */
|
||||
#else /* !AMIGA */
|
||||
dir = find_directory (".");
|
||||
# endif /* AMIGA */
|
||||
#endif /* VMS */
|
||||
#endif /* AMIGA */
|
||||
else
|
||||
{
|
||||
const char *dirname;
|
||||
@@ -858,7 +915,14 @@ file_impossible (const char *filename)
|
||||
dirname = cp;
|
||||
}
|
||||
dir = find_directory (dirname);
|
||||
#ifdef VMS
|
||||
if (*slash == '/')
|
||||
filename = p = slash + 1;
|
||||
else
|
||||
filename = p = slash;
|
||||
#else
|
||||
filename = p = slash + 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (dir->contents == 0)
|
||||
@@ -877,6 +941,7 @@ file_impossible (const char *filename)
|
||||
new = xmalloc (sizeof (struct dirfile));
|
||||
new->length = strlen (filename);
|
||||
#if defined(HAVE_CASE_INSENSITIVE_FS) && defined(VMS)
|
||||
/* todo: Why is this only needed on VMS? */
|
||||
new->name = strcache_add_len (downcase (filename), new->length);
|
||||
#else
|
||||
new->name = strcache_add_len (filename, new->length);
|
||||
@@ -894,13 +959,22 @@ file_impossible_p (const char *filename)
|
||||
struct directory_contents *dir;
|
||||
struct dirfile *dirfile;
|
||||
struct dirfile dirfile_key;
|
||||
|
||||
#ifdef VMS
|
||||
dirend = strrchr (filename, ']');
|
||||
if (dirend == 0)
|
||||
dir = find_directory ("[]")->contents;
|
||||
#else
|
||||
int want_vmsify = 0;
|
||||
#endif
|
||||
|
||||
dirend = strrchr (filename, '/');
|
||||
#ifdef VMS
|
||||
if (dirend == NULL)
|
||||
{
|
||||
want_vmsify = (strpbrk (filename, "]>:^") != NULL);
|
||||
dirend = strrchr (filename, ']');
|
||||
}
|
||||
if (dirend == NULL && want_vmsify)
|
||||
dirend = strrchr (filename, '>');
|
||||
if (dirend == NULL && want_vmsify)
|
||||
dirend = strrchr (filename, ':');
|
||||
#endif
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
/* Forward and backslashes might be mixed. We need the rightmost one. */
|
||||
{
|
||||
@@ -915,10 +989,9 @@ file_impossible_p (const char *filename)
|
||||
if (dirend == 0)
|
||||
#ifdef _AMIGA
|
||||
dir = find_directory ("")->contents;
|
||||
#else /* !VMS && !AMIGA */
|
||||
#else /* !AMIGA */
|
||||
dir = find_directory (".")->contents;
|
||||
#endif /* AMIGA */
|
||||
#endif /* VMS */
|
||||
else
|
||||
{
|
||||
const char *dirname;
|
||||
@@ -940,7 +1013,14 @@ file_impossible_p (const char *filename)
|
||||
dirname = cp;
|
||||
}
|
||||
dir = find_directory (dirname)->contents;
|
||||
#ifdef VMS
|
||||
if (*slash == '/')
|
||||
filename = slash + 1;
|
||||
else
|
||||
filename = slash;
|
||||
#else
|
||||
filename = slash + 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (dir == 0 || dir->dirfiles.ht_vec == 0)
|
||||
@@ -954,7 +1034,8 @@ file_impossible_p (const char *filename)
|
||||
filename = downcase (filename);
|
||||
#endif
|
||||
#ifdef VMS
|
||||
filename = vmsify (filename, 1);
|
||||
if (want_vmsify)
|
||||
filename = vmsify (filename, 1);
|
||||
#endif
|
||||
|
||||
dirfile_key.name = filename;
|
||||
@@ -1001,10 +1082,11 @@ print_dir_data_base (void)
|
||||
else if (dir->contents->dirfiles.ht_vec == 0)
|
||||
{
|
||||
#ifdef WINDOWS32
|
||||
printf (_("# %s (key %s, mtime %d): could not be opened.\n"),
|
||||
dir->name, dir->contents->path_key,dir->contents->mtime);
|
||||
printf (_("# %s (key %s, mtime %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],
|
||||
@@ -1037,10 +1119,11 @@ print_dir_data_base (void)
|
||||
}
|
||||
}
|
||||
#ifdef WINDOWS32
|
||||
printf (_("# %s (key %s, mtime %d): "),
|
||||
dir->name, dir->contents->path_key, dir->contents->mtime);
|
||||
printf (_("# %s (key %s, mtime %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],
|
||||
@@ -1086,8 +1169,6 @@ print_dir_data_base (void)
|
||||
|
||||
/* Hooks for globbing. */
|
||||
|
||||
#include <glob.h>
|
||||
|
||||
/* Structure describing state of iterating through a directory hash table. */
|
||||
|
||||
struct dirstream
|
||||
@@ -1171,13 +1252,6 @@ read_dirstream (__ptr_t stream)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
ansi_free (void *p)
|
||||
{
|
||||
if (p)
|
||||
free (p);
|
||||
}
|
||||
|
||||
/* On 64 bit ReliantUNIX (5.44 and above) in LFS mode, stat() is actually a
|
||||
* macro for stat64(). If stat is a macro, make a local wrapper function to
|
||||
* invoke it.
|
||||
@@ -1185,9 +1259,16 @@ ansi_free (void *p)
|
||||
* On MS-Windows, stat() "succeeds" for foo/bar/. where foo/bar is a
|
||||
* regular file; fix that here.
|
||||
*/
|
||||
#if !defined(stat) && !defined(WINDOWS32)
|
||||
#if !defined(stat) && !defined(WINDOWS32) || defined(VMS)
|
||||
# ifndef VMS
|
||||
# ifndef HAVE_SYS_STAT_H
|
||||
int stat (const char *path, struct stat *sbuf);
|
||||
# endif
|
||||
# else
|
||||
/* We are done with the fake stat. Go back to the real stat */
|
||||
# ifdef stat
|
||||
# undef stat
|
||||
# endif
|
||||
# endif
|
||||
# define local_stat stat
|
||||
#else
|
||||
@@ -1223,7 +1304,7 @@ dir_setup_glob (glob_t *gl)
|
||||
{
|
||||
gl->gl_opendir = open_dirstream;
|
||||
gl->gl_readdir = read_dirstream;
|
||||
gl->gl_closedir = ansi_free;
|
||||
gl->gl_closedir = free;
|
||||
gl->gl_stat = local_stat;
|
||||
/* We don't bother setting gl_lstat, since glob never calls it.
|
||||
The slot is only there for compatibility with 4.4 BSD. */
|
||||
|
||||
2
doc/.gitignore
vendored
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
|
||||
|
||||
515
doc/make.texi
515
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
|
||||
@@ -4716,9 +4721,9 @@ doesn't count against the total jobs (otherwise we could get @samp{N}
|
||||
sub-@code{make}s running and have no slots left over for any real work!)
|
||||
|
||||
If your operating system doesn't support the above communication, then
|
||||
@samp{-j 1} is always put into @code{MAKEFLAGS} instead of the value you
|
||||
specified. This is because if the @w{@samp{-j}} option were passed down
|
||||
to sub-@code{make}s, you would get many more jobs running in parallel
|
||||
no @samp{-j} is added to @code{MAKEFLAGS}, so that sub-@code{make}s
|
||||
run in non-parallel mode. If the @w{@samp{-j}} option were passed down
|
||||
to sub-@code{make}s you would get many more jobs running in parallel
|
||||
than you asked for. If you give @samp{-j} with no numeric argument,
|
||||
meaning to run as many jobs as possible in parallel, this is passed
|
||||
down, since multiple infinities are no more than one.@refill
|
||||
@@ -4808,10 +4813,17 @@ to GNU @code{make}, and hence do not want to add GNU
|
||||
@code{make}-specific flags to the @code{MAKEFLAGS} variable, you can
|
||||
add them to the @code{GNUMAKEFLAGS} variable instead. This variable
|
||||
is parsed just before @code{MAKEFLAGS}, in the same way as
|
||||
@code{MAKEFLAGS}. Note, however, that when @code{make} constructs
|
||||
@code{MAKEFLAGS} to pass to a recursive @code{make} it will include
|
||||
all flags. GNU @code{make} never sets the @code{GNUMAKEFLAGS}
|
||||
variable itself.
|
||||
@code{MAKEFLAGS}. When @code{make} constructs @code{MAKEFLAGS} to
|
||||
pass to a recursive @code{make} it will include all flags, even those
|
||||
taken from @code{GNUMAKEFLAGS}. As a result, after parsing
|
||||
@code{GNUMAKEFLAGS} GNU @code{make} sets this variable to the empty
|
||||
string to avoid duplicating flags during recursion.
|
||||
|
||||
It's best to use @code{GNUMAKEFLAGS} only with flags which won't
|
||||
materially change the behavior of your makefiles. If your makefiles
|
||||
require GNU make anyway then simply use @code{MAKEFLAGS}. Flags such
|
||||
as @samp{--no-print-directory} or @samp{--output-sync} may be
|
||||
appropriate for @code{GNUMAKEFLAGS}.
|
||||
|
||||
@node -w Option, , Options/Recursion, Recursion
|
||||
@subsection The @samp{--print-directory} Option
|
||||
@@ -4970,27 +4982,24 @@ beginning with a recipe prefix character to define an empty recipe,
|
||||
but this would be confusing because such a line looks empty.
|
||||
|
||||
@findex .DEFAULT@r{, and empty recipes}
|
||||
You may be wondering why you would want to define a recipe that
|
||||
does nothing. The only reason this is useful is to prevent a target
|
||||
from getting implicit recipes (from implicit rules or the
|
||||
@code{.DEFAULT} special target; @pxref{Implicit Rules} and
|
||||
@pxref{Last Resort, ,Defining Last-Resort Default Rules}).@refill
|
||||
You may be wondering why you would want to define a recipe that does
|
||||
nothing. One reason this is useful is to prevent a target from
|
||||
getting implicit recipes (from implicit rules or the @code{.DEFAULT}
|
||||
special target; @pxref{Implicit Rules} and @pxref{Last Resort,
|
||||
,Defining Last-Resort Default Rules}).@refill
|
||||
|
||||
@c !!! another reason is for canonical stamp files:
|
||||
@ignore
|
||||
@example
|
||||
foo: stamp-foo ;
|
||||
stamp-foo: foo.in
|
||||
create foo frm foo.in
|
||||
touch $@
|
||||
@end example
|
||||
@end ignore
|
||||
Empty recipes can also be used to avoid errors for targets that will
|
||||
be created as a side-effect of another recipe: if the target does not
|
||||
exist the empty recipe ensures that @code{make} won't complain that it
|
||||
doesn't know how to build the target, and @code{make} will assume the
|
||||
target is out of date.
|
||||
|
||||
You may be inclined to define empty recipes for targets that are
|
||||
not actual files, but only exist so that their prerequisites can be
|
||||
You may be inclined to define empty recipes for targets that are not
|
||||
actual files, but only exist so that their prerequisites can be
|
||||
remade. However, this is not the best way to do that, because the
|
||||
prerequisites may not be remade properly if the target file actually does exist.
|
||||
@xref{Phony Targets, ,Phony Targets}, for a better way to do this.
|
||||
prerequisites may not be remade properly if the target file actually
|
||||
does exist. @xref{Phony Targets, ,Phony Targets}, for a better way to
|
||||
do this.
|
||||
|
||||
@node Using Variables, Conditionals, Recipes, Top
|
||||
@chapter How to Use Variables
|
||||
@@ -5616,7 +5625,7 @@ Several variables have constant initial values.
|
||||
@cindex !=
|
||||
|
||||
To set a variable from the makefile, write a line starting with the
|
||||
variable name followed by @samp{=} @samp{:=}, or @samp{::=}. Whatever
|
||||
variable name followed by @samp{=}, @samp{:=}, or @samp{::=}. Whatever
|
||||
follows the @samp{=}, @samp{:=}, or @samp{::=} on the line becomes the
|
||||
value. For example,
|
||||
|
||||
@@ -5669,7 +5678,7 @@ endif
|
||||
@end example
|
||||
|
||||
The shell assignment operator @samp{!=} can be used to execute a
|
||||
program and set a variable to its output. This operator first
|
||||
shell script and set a variable to its output. This operator first
|
||||
evaluates the right-hand side, then passes that result to the shell
|
||||
for execution. If the result of the execution ends in a newline, that
|
||||
one newline is removed; all other newlines are replaced by spaces.
|
||||
@@ -5694,6 +5703,9 @@ hash := $(shell printf '\043')
|
||||
var := $(shell find . -name "*.c")
|
||||
@end example
|
||||
|
||||
As with the @code{shell} function, the exit status of the just-invoked
|
||||
shell script is stored in the @code{.SHELLSTATUS} variable.
|
||||
|
||||
|
||||
@node Appending, Override Directive, Setting, Using Variables
|
||||
@section Appending More Text to Variables
|
||||
@@ -5802,7 +5814,7 @@ CFLAGS += -pg # enable profiling
|
||||
@noindent
|
||||
The first line defines the @code{CFLAGS} variable with a reference to another
|
||||
variable, @code{includes}. (@code{CFLAGS} is used by the rules for C
|
||||
compilation; @pxref{Catalogue of Rules, ,Catalogue of Implicit Rules}.)
|
||||
compilation; @pxref{Catalogue of Rules, ,Catalogue of Built-In Rules}.)
|
||||
Using @samp{=} for the definition makes @code{CFLAGS} a recursively-expanded
|
||||
variable, meaning @w{@samp{$(includes) -O}} is @emph{not} expanded when
|
||||
@code{make} processes the definition of @code{CFLAGS}. Thus, @code{includes}
|
||||
@@ -6321,6 +6333,28 @@ will contain the number of times this instance has restarted. Note
|
||||
this is not the same as recursion (counted by the @code{MAKELEVEL}
|
||||
variable). You should not set, modify, or export this variable.
|
||||
|
||||
@vindex MAKE_TERMOUT @r{(whether stdout is a terminal)}
|
||||
@vindex MAKE_TERMERR @r{(whether stderr is a terminal)}
|
||||
@item MAKE_TERMOUT
|
||||
@itemx MAKE_TERMERR
|
||||
When @code{make} starts it will check whether stdout and stderr will
|
||||
show their output on a terminal. If so, it will set
|
||||
@code{MAKE_TERMOUT} and @code{MAKE_TERMERR}, respectively, to the name
|
||||
of the terminal device (or @code{true} if this cannot be determined).
|
||||
If set these variables will be marked for export. These variables
|
||||
will not be changed by @code{make} and they will not be modified if
|
||||
already set.
|
||||
|
||||
These values can be used (particularly in combination with output
|
||||
synchronization (@pxref{Parallel Output, ,Output During Parallel
|
||||
Execution}) to determine whether @code{make} itself is writing to a
|
||||
terminal; they can be tested to decide whether to force recipe
|
||||
commands to generate colorized output for example.
|
||||
|
||||
If you invoke a sub-@code{make} and redirect its stdout or stderr it
|
||||
is your responsibility to reset or unexport these variables as well,
|
||||
if your makefiles rely on them.
|
||||
|
||||
@vindex .RECIPEPREFIX @r{(change the recipe prefix character)}
|
||||
@item .RECIPEPREFIX
|
||||
The first character of the value of this variable is used as the
|
||||
@@ -6614,12 +6648,12 @@ effective; otherwise, the @var{text-if-false}, if any, is effective.
|
||||
|
||||
@item ifdef @var{variable-name}
|
||||
The @code{ifdef} form takes the @emph{name} of a variable as its
|
||||
argument, not a reference to a variable. The value of that variable
|
||||
has a non-empty value, the @var{text-if-true} is effective; otherwise,
|
||||
the @var{text-if-false}, if any, is effective. Variables that have
|
||||
never been defined have an empty value. The text @var{variable-name}
|
||||
is expanded, so it could be a variable or function that expands
|
||||
to the name of a variable. For example:
|
||||
argument, not a reference to a variable. If the value of that
|
||||
variable has a non-empty value, the @var{text-if-true} is effective;
|
||||
otherwise, the @var{text-if-false}, if any, is effective. Variables
|
||||
that have never been defined have an empty value. The text
|
||||
@var{variable-name} is expanded, so it could be a variable or function
|
||||
that expands to the name of a variable. For example:
|
||||
|
||||
@example
|
||||
bar = true
|
||||
@@ -7498,34 +7532,46 @@ no?), but it is more likely to be a mistake.
|
||||
@findex file
|
||||
@cindex writing to a file
|
||||
@cindex file, writing to
|
||||
@cindex reading from a file
|
||||
@cindex file, reading from
|
||||
|
||||
The @code{file} function allows the makefile to write to a file. Two
|
||||
modes of writing are supported: overwrite, where the text is written
|
||||
to the beginning of the file and any existing content is lost, and
|
||||
append, where the text is written to the end of the file, preserving
|
||||
the existing content. In all cases the file is created if it does not
|
||||
exist.
|
||||
The @code{file} function allows the makefile to write to or read from
|
||||
a file. Two modes of writing are supported: overwrite, where the text
|
||||
is written to the beginning of the file and any existing content is
|
||||
lost, and append, where the text is written to the end of the file,
|
||||
preserving the existing content. In both cases the file is created if
|
||||
it does not exist. It is a fatal error if the file cannot be opened
|
||||
for writing, or if the write operation fails. The @code{file}
|
||||
function expands to the empty string when writing to a file.
|
||||
|
||||
When reading from a file, the @code{file} function expands to the
|
||||
verbatim contents of the file, except that the final newline (if there
|
||||
is one) will be stripped. Attempting to read from a non-existent file
|
||||
expands to the empty string.
|
||||
|
||||
The syntax of the @code{file} function is:
|
||||
|
||||
@example
|
||||
$(file @var{op} @var{filename},@var{text})
|
||||
$(file @var{op} @var{filename}[,@var{text}])
|
||||
@end example
|
||||
|
||||
The operator @var{op} can be either @code{>} which indicates overwrite
|
||||
mode, or @code{>>} which indicates append mode. The @var{filename}
|
||||
indicates the file to be written to. There may optionally be
|
||||
When the @code{file} function is evaluated all its arguments are
|
||||
expanded first, then the file indicated by @var{filename} will be
|
||||
opened in the mode described by @var{op}.
|
||||
|
||||
The operator @var{op} can be @code{>} to indicate the file will be
|
||||
overwritten with new content, @code{>>} to indicate the current
|
||||
contents of the file will be appended to, or @code{<} to indicate the
|
||||
contents of the file will be read in. The @var{filename} specifies
|
||||
the file to be written to or read from. There may optionally be
|
||||
whitespace between the operator and the file name.
|
||||
|
||||
When the @code{file} function is expanded all its arguments are
|
||||
expanded first, then the file indicated by @var{filename} will be
|
||||
opened in the mode described by @var{op}. Finally @var{text} will be
|
||||
written to the file. If @var{text} does not already end in a newline,
|
||||
a final newline will be written. The result of evaluating the
|
||||
@code{file} function is always the empty string.
|
||||
When reading files, it is an error to provide a @var{text} value.
|
||||
|
||||
It is a fatal error if the file cannot be opened for writing, or if
|
||||
the write operation fails.
|
||||
When writing files, @var{text} will be written to the file. If
|
||||
@var{text} does not already end in a newline a final newline will be
|
||||
written (even if @var{text} is the empty string). If the @var{text}
|
||||
argument is not given at all, nothing will be written.
|
||||
|
||||
For example, the @code{file} function can be useful if your build
|
||||
system has a limited command line size and your recipe runs a command
|
||||
@@ -7549,7 +7595,7 @@ input file, you might write your recipe like this:
|
||||
@example
|
||||
@group
|
||||
program: $(OBJECTS)
|
||||
$(file >$@@.in,) $(foreach O,$^,$(file >>$@@.in,$O))
|
||||
$(file >$@@.in) $(foreach O,$^,$(file >>$@@.in,$O))
|
||||
$(CMD) $(CMDFLAGS) @@$@@.in
|
||||
@@rm $@@.in
|
||||
@end group
|
||||
@@ -8001,6 +8047,10 @@ implications of using the @code{shell} function within recursively
|
||||
expanded variables vs.@: simply expanded variables (@pxref{Flavors, ,The
|
||||
Two Flavors of Variables}).
|
||||
|
||||
@vindex .SHELLSTATUS
|
||||
After the @code{shell} function or @samp{!=} assignment operator is
|
||||
used, its exit status is placed in the @code{.SHELLSTATUS} variable.
|
||||
|
||||
Here are some examples of the use of the @code{shell} function:
|
||||
|
||||
@example
|
||||
@@ -8927,7 +8977,7 @@ retained for compatibility.
|
||||
@menu
|
||||
* Using Implicit:: How to use an existing implicit rule
|
||||
to get the recipes for updating a file.
|
||||
* Catalogue of Rules:: A list of built-in implicit rules.
|
||||
* Catalogue of Rules:: A list of built-in rules.
|
||||
* Implicit Variables:: How to change what predefined rules do.
|
||||
* Chained Rules:: How to use a chain of implicit rules.
|
||||
* Pattern Rules:: How to define new implicit rules.
|
||||
@@ -8979,7 +9029,7 @@ compiler; and so on.
|
||||
Of course, when you write the makefile, you know which implicit rule you
|
||||
want @code{make} to use, and you know it will choose that one because you
|
||||
know which possible prerequisite files are supposed to exist.
|
||||
@xref{Catalogue of Rules, ,Catalogue of Implicit Rules},
|
||||
@xref{Catalogue of Rules, ,Catalogue of Built-In Rules},
|
||||
for a catalogue of all the predefined implicit rules.
|
||||
|
||||
Above, we said an implicit rule applies if the required prerequisites ``exist
|
||||
@@ -9009,7 +9059,7 @@ make an object file, a @file{.o} file, from a Pascal source file, a
|
||||
@file{.p} file. For example, if @file{foo.c} also exists, the implicit
|
||||
rule to make an object file from a C source file is used instead,
|
||||
because it appears before the Pascal rule in the list of predefined
|
||||
implicit rules (@pxref{Catalogue of Rules, , Catalogue of Implicit
|
||||
implicit rules (@pxref{Catalogue of Rules, , Catalogue of Built-In
|
||||
Rules}).
|
||||
|
||||
If you do not want an implicit rule to be used for a target that has no
|
||||
@@ -9017,7 +9067,7 @@ recipe, you can give that target an empty recipe by writing a semicolon
|
||||
(@pxref{Empty Recipes, ,Defining Empty Recipes}).
|
||||
|
||||
@node Catalogue of Rules, Implicit Variables, Using Implicit, Implicit Rules
|
||||
@section Catalogue of Implicit Rules
|
||||
@section Catalogue of Built-In Rules
|
||||
@cindex implicit rule, predefined
|
||||
@cindex rule, implicit, predefined
|
||||
|
||||
@@ -10667,7 +10717,7 @@ in the normal way (@pxref{Suffix Rules}). Thus a double-suffix rule
|
||||
@w{@samp{.@var{x}.a}} produces two pattern rules: @samp{@w{(%.o):}
|
||||
@w{%.@var{x}}} and @samp{@w{%.a}: @w{%.@var{x}}}.@refill
|
||||
|
||||
@node Extending make, Features, Archives, Top
|
||||
@node Extending make, Integrating make, Archives, Top
|
||||
@chapter Extending GNU @code{make}
|
||||
@cindex make extensions
|
||||
|
||||
@@ -10910,7 +10960,8 @@ The @code{load} directive and extension capability is considered a
|
||||
``technology preview'' in this release of GNU make. We encourage you
|
||||
to experiment with this feature and we appreciate any feedback on it.
|
||||
However we cannot guarantee to maintain backward-compatibility in the
|
||||
next release.
|
||||
next release. Consider using GNU Guile instead for extending GNU make
|
||||
(@pxref{Guile Function, ,The @code{guile} Function}).
|
||||
@end quotation
|
||||
@end cartouche
|
||||
|
||||
@@ -10978,7 +11029,9 @@ same directive.
|
||||
The initializing function will be provided the file name and line
|
||||
number of the invocation of the @code{load} operation. It should
|
||||
return a value of type @code{int}, which must be @code{0} on failure
|
||||
and non-@code{0} on success.
|
||||
and non-@code{0} on success. If the return value is @code{-1}, then
|
||||
GNU make will @emph{not} attempt to rebuild the object file
|
||||
(@pxref{Remaking Loaded Objects, ,How Loaded Objects Are Remade}).
|
||||
|
||||
For example:
|
||||
|
||||
@@ -11105,16 +11158,14 @@ arguments are as follows:
|
||||
@table @code
|
||||
@item name
|
||||
The function name. This is what the makefile should use to invoke the
|
||||
function. The name must be between 1 and 255 characters long.
|
||||
function. The name must be between 1 and 255 characters long and it
|
||||
may only contain alphanumeric, period (@samp{.}), dash (@samp{-}), and
|
||||
underscore (@samp{_}) characters. It may not begin with a period.
|
||||
|
||||
@item func_ptr
|
||||
A pointer to a function that @code{make} will invoke when it expands
|
||||
the function in a makefile. This function must be defined by the
|
||||
loaded object. GNU @code{make} will call it with three arguments:
|
||||
@code{name} (the same name as above), @code{argc} (the number of
|
||||
arguments to the function), and @code{argv} (the list of arguments to
|
||||
the function). The last argument (that is, @code{argv[argc]} will be
|
||||
null (@code{0}).
|
||||
loaded object.
|
||||
|
||||
@item min_args
|
||||
The minimum number of arguments the function will accept. Must be
|
||||
@@ -11130,12 +11181,30 @@ arguments. If the value is 0, then any number of arguments is
|
||||
accepted. If the value is greater than 0, then it must be greater
|
||||
than or equal to @code{min_args}.
|
||||
|
||||
@item expand_args
|
||||
If this value is 0, then @code{make} will not expand the arguments to
|
||||
the function before passing them to @code{func_ptr}. If the value is
|
||||
non-0, then the arguments will be expanded first.
|
||||
@item flags
|
||||
Flags that specify how this function will operate; the desired flags
|
||||
should be OR'd together. If the @code{GMK_FUNC_NOEXPAND} flag is
|
||||
given then the function arguments will not be expanded before the
|
||||
function is called; otherwise they will be expanded first.
|
||||
@end table
|
||||
|
||||
@subsubheading Registered Function Interface
|
||||
@findex gmk_func_ptr
|
||||
|
||||
A function registered with @code{make} must match the
|
||||
@code{gmk_func_ptr} type. It will be invoked with three parameters:
|
||||
@code{name} (the name of the function), @code{argc} (the number of
|
||||
arguments to the function), and @code{argv} (an array of pointers to
|
||||
arguments to the function). The last pointer (that is,
|
||||
@code{argv[argc]}) will be null (@code{0}).
|
||||
|
||||
The return value of the function is the result of expanding the
|
||||
function. If the function expands to nothing the return value may be
|
||||
null. Otherwise, it must be a pointer to a string created with
|
||||
@code{gmk_alloc}. Once the function returns, @code{make} owns this
|
||||
string and will free it when appropriate; it cannot be accessed by the
|
||||
loaded object.
|
||||
|
||||
@subsubheading GNU @code{make} Facilities
|
||||
|
||||
There are some facilities exported by GNU @code{make} for use by
|
||||
@@ -11174,6 +11243,12 @@ should never pass memory that you've allocated directly to any
|
||||
memory returned to you by any @code{make} function. Instead, use the
|
||||
@code{gmk_alloc} and @code{gmk_free} functions.
|
||||
|
||||
In particular, the string returned to @code{make} by a function
|
||||
registered using @code{gmk_add_function} @emph{must} be allocated
|
||||
using @code{gmk_alloc}, and the string returned from the @code{make}
|
||||
@code{gmk_expand} function @emph{must} be freed (when no longer
|
||||
needed) using @code{gmk_free}.
|
||||
|
||||
@table @code
|
||||
@item gmk_alloc
|
||||
@findex gmk_alloc
|
||||
@@ -11283,7 +11358,225 @@ cc -shared -fPIC -o mk_temp.so mk_temp.c
|
||||
Temporary filename: tmpfile.A7JEwd
|
||||
@end example
|
||||
|
||||
@node Features, Missing, Extending make, Top
|
||||
@node Integrating make, Features, Extending make, Top
|
||||
@chapter Integrating GNU @code{make}
|
||||
@cindex make integration
|
||||
|
||||
GNU @code{make} is often one component in a larger system of tools,
|
||||
including integrated development environments, compiler toolchains,
|
||||
and others. The role of @code{make} is to start commands and
|
||||
determine whether they succeeded or not: no special integration is
|
||||
needed to accomplish that. However, sometimes it is convenient to
|
||||
bind @code{make} more tightly with other parts of the system, both
|
||||
higher-level (tools that invoke @code{make}) and lower-level (tools
|
||||
that @code{make} invokes).
|
||||
|
||||
@menu
|
||||
* Job Slots:: Share job slots with GNU @code{make}.
|
||||
* Terminal Output:: Control output to terminals.
|
||||
@end menu
|
||||
|
||||
@node Job Slots, Terminal Output, Integrating make, Integrating make
|
||||
@section Sharing Job Slots with GNU @code{make}
|
||||
@cindex job slots, sharing
|
||||
@cindex tools, sharing job slots
|
||||
|
||||
GNU @code{make} has the ability to run multiple recipes in parallel
|
||||
(@pxref{Parallel, ,Parallel Execution}) and to cap the total number of
|
||||
parallel jobs even across recursive invocations of @code{make}
|
||||
(@pxref{Options/Recursion, ,Communicating Options to a
|
||||
Sub-@code{make}}). Tools that @code{make} invokes which are also able
|
||||
to run multiple operations in parallel, either using multiple threads
|
||||
or multiple processes, can be enhanced to participate in GNU
|
||||
@code{make}'s job management facility to ensure that the total number
|
||||
of active threads/processes running on the system does not exceed the
|
||||
maximum number of slots provided to GNU @code{make}. @refill
|
||||
|
||||
@cindex jobserver
|
||||
GNU @code{make} uses a method called the ``jobserver'' to control the
|
||||
number of active jobs across recursive invocations. The actual
|
||||
implementation of the jobserver varies across different operating
|
||||
systems, but some fundamental aspects are always true.
|
||||
|
||||
First, only command lines that @code{make} understands to be recursive
|
||||
invocations of @code{make} (@pxref{MAKE Variable, ,How the @code{MAKE}
|
||||
Variable Works}) will have access to the jobserver. When writing
|
||||
makefiles you must be sure to mark the command as recursive (most
|
||||
commonly by prefixing the command line with the @code{+} indicator
|
||||
(@pxref{Recursion, ,Recursive Use of @code{make}}).
|
||||
|
||||
Second, @code{make} will provide information necessary for accessing
|
||||
the jobserver through the environment to its children, in the
|
||||
@code{MAKEFLAGS} environment variable. Tools which want to
|
||||
participate in the jobserver protocol will need to parse this
|
||||
environment variable, as described in subsequent sections.
|
||||
|
||||
Third, every command @code{make} starts has one implicit job slot
|
||||
reserved for it before it starts. Any tool which wants to participate
|
||||
in the jobserver protocol should assume it can always run one job
|
||||
without having to contact the jobserver at all.
|
||||
|
||||
Finally, it's critical that tools that participate in the jobserver
|
||||
protocol return the exact number of slots they obtained from the
|
||||
jobserver back to the jobserver before they exit, even under error
|
||||
conditions. Remember that the implicit job slot should @strong{not}
|
||||
be returned to the jobserver! Returning too few slots means that
|
||||
those slots will be lost for the rest of the build process; returning
|
||||
too many slots means that extra slots will be available. The
|
||||
top-level @code{make} command will print an error message at the end
|
||||
of the build if it detects an incorrect number of slots available in
|
||||
the jobserver.
|
||||
|
||||
As an example, suppose you are implementing a linker which provides
|
||||
for multithreaded operation. You would like to enhance the linker so
|
||||
that if it is invoked by GNU @code{make} it can participate in the
|
||||
jobserver protocol to control how many threads are used during link.
|
||||
First you will need to modify the linker to determine if the
|
||||
@code{MAKEFLAGS} environment variable is set. Next you will need to
|
||||
parse the value of that variable to determine if the jobserver is
|
||||
available, and how to access it. If it is available then you can
|
||||
access it to obtain job slots controlling how much parallelism your
|
||||
tool can use. Once done your tool must return those job slots back to
|
||||
the jobserver.
|
||||
|
||||
@menu
|
||||
* POSIX Jobserver:: Using the jobserver on POSIX systems.
|
||||
* Windows Jobserver:: Using the jobserver on Windows systems.
|
||||
@end menu
|
||||
|
||||
@node POSIX Jobserver, Windows Jobserver, Job Slots, Job Slots
|
||||
@subsection POSIX Jobserver Interaction
|
||||
@cindex jobserver on POSIX
|
||||
|
||||
On POSIX systems the jobserver is implemented as a simple UNIX pipe.
|
||||
The pipe will be pre-loaded with one single-character token for each
|
||||
available job. To obtain an extra slot you must read a single
|
||||
character from the jobserver pipe; to release a slot you must write a
|
||||
single character back into the jobserver pipe.
|
||||
|
||||
To access the pipe you must parse the @code{MAKEFLAGS} variable and
|
||||
look for the argument string @code{--jobserver-auth=R,W} where
|
||||
@samp{R} and @samp{W} are non-negative integers representing file
|
||||
descriptors: @samp{R} is the read file descriptor and @samp{W} is the
|
||||
write file descriptor.
|
||||
|
||||
It's important that when you release the job slot, you write back the
|
||||
same character you read from the pipe for that slot. Don't assume
|
||||
that all tokens are the same character; different characters may have
|
||||
different meanings to GNU @code{make}. The order is not important,
|
||||
since @code{make} has no idea in what order jobs will complete anyway.
|
||||
|
||||
There are various error conditions you must consider to ensure your
|
||||
implementation is robust:
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
Usually you will have a command-line argument controlling the parallel
|
||||
operation of your tool. Consider whether your tool should detect
|
||||
situations where both the jobserver and the command-line argument are
|
||||
specified, and how it should react.
|
||||
|
||||
@item
|
||||
If your tool determines that the @code{--jobserver-auth} option is
|
||||
available in @code{MAKEFLAGS} but that the file descriptors specified
|
||||
are closed, this means that the calling @code{make} process did not
|
||||
think that your tool was a recursive @code{make} invocation (e.g., the
|
||||
command line was not prefixed with a @code{+} character). You should
|
||||
notify your users of this situation.
|
||||
|
||||
@item
|
||||
Your tool should also examine the first word of the @code{MAKEFLAGS}
|
||||
variable and look for the character @code{n}. If this character is
|
||||
present then @code{make} was invoked with the @samp{-n} option and
|
||||
your tool should stop without performing any operations.
|
||||
|
||||
@item
|
||||
Your tool should be sure to write back the tokens it read, even under
|
||||
error conditions. This includes not only errors in your tool but also
|
||||
outside influences such as interrupts (@code{SIGINT}), etc. You may
|
||||
want to install signal handlers to manage this write-back.
|
||||
@end itemize
|
||||
|
||||
@node Windows Jobserver, , POSIX Jobserver, Job Slots
|
||||
@subsection Windows Jobserver Interaction
|
||||
@cindex jobserver on Windows
|
||||
|
||||
On Windows systems the jobserver is implemented as a named semaphore.
|
||||
The semaphore will be set with an initial count equal to the number of
|
||||
available slots; to obtain a slot you must wait on the semaphore (with
|
||||
or without a timeout). To release a slot, release the semaphore.
|
||||
|
||||
To access the semaphore you must parse the @code{MAKEFLAGS} variable and
|
||||
look for the argument string @code{--jobserver-auth=NAME} where
|
||||
@samp{NAME} is the name of the named semaphore. Use this name with
|
||||
@code{OpenSemaphore} to create a handle to the semaphore.
|
||||
|
||||
There are various error conditions you must consider to ensure your
|
||||
implementation is robust:
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
Usually you will have a command-line argument controlling the parallel
|
||||
operation of your tool. Consider whether your tool should detect
|
||||
situations where both the jobserver and the command-line argument are
|
||||
specified, and how it should react.
|
||||
|
||||
@item
|
||||
Your tool should be sure to release the semaphore for the tokens it
|
||||
read, even under error conditions. This includes not only errors in
|
||||
your tool but also outside influences such as interrupts
|
||||
(@code{SIGINT}), etc. You may want to install signal handlers to
|
||||
manage this write-back.
|
||||
@end itemize
|
||||
|
||||
@node Terminal Output, , Job Slots, Integrating make
|
||||
@section Synchronized Terminal Output
|
||||
@cindex parallel output to terminal
|
||||
@cindex terminal, output to
|
||||
|
||||
Normally GNU @code{make} will invoke all commands with access to the
|
||||
same standard and error outputs that @code{make} itself was started
|
||||
with. A number of tools will detect whether the output is a terminal
|
||||
or not-a-terminal, and use this information to change the output
|
||||
style. For example if the output goes to a terminal the tool may add
|
||||
control characters that set color, or even change the location of the
|
||||
cursor. If the output is not going to a terminal then these special
|
||||
control characters are not emitted so that they don't corrupt log
|
||||
files, etc.
|
||||
|
||||
The @code{--output-sync} (@pxref{Parallel Output, ,Output During
|
||||
Parallel Output}) option will defeat the terminal detection. When
|
||||
output synchronization is enabled GNU @code{make} arranges for all
|
||||
command output to be written to a file, so that its output can be
|
||||
written as a block without interference from other commands. This
|
||||
means that all tools invoked by @code{make} will believe that their
|
||||
output is not going to be displayed on a terminal, even when it will
|
||||
be (because @code{make} will display it there after the command is
|
||||
completed).
|
||||
|
||||
In order to facilitate tools which would like to determine whether or
|
||||
not their output will be displayed on a terminal, GNU @code{make} will
|
||||
set the @code{MAKE_TERMOUT} and @code{MAKE_TERMERR} environment
|
||||
variables before invoking any commands. Tools which would like to
|
||||
determine whether standard or error output (respectively) will be
|
||||
displayed on a terminal can check these environment variables to
|
||||
determine if they exist and contain a non-empty value. If so the tool
|
||||
can assume that the output will (eventually) be displayed on a
|
||||
terminal. If the variables are not set or have an empty value, then
|
||||
the tool should fall back to its normal methods of detecting whether
|
||||
output is going to a terminal or not.
|
||||
|
||||
The content of the variables can be parsed to determine the type of
|
||||
terminal which will be used to display the output.
|
||||
|
||||
Similarly, environments which invoke @code{make} and would like to
|
||||
capture the output and eventually display it on a terminal (or some
|
||||
display which can interpret terminal control characters) can set these
|
||||
variables before invoking @code{make}. GNU @code{make} will not
|
||||
modify these environment variables if they already exist when it
|
||||
starts.
|
||||
|
||||
@node Features, Missing, Integrating make, Top
|
||||
@chapter Features of GNU @code{make}
|
||||
@cindex features of GNU @code{make}
|
||||
@cindex portability
|
||||
@@ -11540,7 +11833,7 @@ functionality in that it will check out SCCS files for makefiles.
|
||||
|
||||
@item
|
||||
Various new built-in implicit rules.
|
||||
@xref{Catalogue of Rules, ,Catalogue of Implicit Rules}.
|
||||
@xref{Catalogue of Rules, ,Catalogue of Built-In Rules}.
|
||||
|
||||
@item
|
||||
Load dynamic objects which can modify the behavior of @code{make}.
|
||||
@@ -11663,7 +11956,7 @@ special treatment.
|
||||
|
||||
This appendix summarizes the directives, text manipulation functions,
|
||||
and special variables which GNU @code{make} understands.
|
||||
@xref{Special Targets}, @ref{Catalogue of Rules, ,Catalogue of Implicit Rules},
|
||||
@xref{Special Targets}, @ref{Catalogue of Rules, ,Catalogue of Built-In Rules},
|
||||
and @ref{Options Summary, ,Summary of Options},
|
||||
for other summaries.
|
||||
|
||||
@@ -12039,9 +12332,9 @@ variable has no effect on the operation of @code{make}.@*
|
||||
|
||||
@item CURDIR
|
||||
|
||||
Set to the pathname of the current working directory (after all
|
||||
@code{-C} options are processed, if any). Setting this variable has no
|
||||
effect on the operation of @code{make}.@*
|
||||
Set to the absolute pathname of the current working directory (after
|
||||
all @code{-C} options are processed, if any). Setting this variable
|
||||
has no effect on the operation of @code{make}.@*
|
||||
@xref{Recursion, ,Recursive Use of @code{make}}.
|
||||
|
||||
@item SUFFIXES
|
||||
|
||||
@@ -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
|
||||
|
||||
33
expand.c
33
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)
|
||||
{
|
||||
@@ -377,16 +379,12 @@ variable_expand_string (char *line, const char *string, long length)
|
||||
Look up the value of the variable. */
|
||||
o = reference_variable (o, beg, end - beg);
|
||||
|
||||
if (abeg)
|
||||
free (abeg);
|
||||
}
|
||||
break;
|
||||
|
||||
case '\0':
|
||||
break;
|
||||
|
||||
default:
|
||||
if (isblank ((unsigned char)p[-1]))
|
||||
if (ISSPACE (p[-1]))
|
||||
break;
|
||||
|
||||
/* A $ followed by a random char is a variable reference:
|
||||
@@ -447,8 +445,7 @@ expand_argument (const char *str, const char *end)
|
||||
|
||||
r = allocated_variable_expand (tmp);
|
||||
|
||||
if (alloc)
|
||||
free (alloc);
|
||||
free (alloc);
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -461,7 +458,7 @@ variable_expand_for_file (const char *line, struct file *file)
|
||||
{
|
||||
char *result;
|
||||
struct variable_set_list *savev;
|
||||
const gmk_floc *savef;
|
||||
const floc *savef;
|
||||
|
||||
if (file == 0)
|
||||
return variable_expand (line);
|
||||
|
||||
66
file.c
66
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)
|
||||
@@ -261,22 +268,25 @@ rehash_file (struct file *from_file, const char *to_hname)
|
||||
to_file->cmds = from_file->cmds;
|
||||
else if (from_file->cmds != to_file->cmds)
|
||||
{
|
||||
size_t l = strlen (from_file->name);
|
||||
/* We have two sets of commands. We will go with the
|
||||
one given in the rule explicitly mentioning this name,
|
||||
but give a message to let the user know what's going on. */
|
||||
if (to_file->cmds->fileinfo.filenm != 0)
|
||||
error (&from_file->cmds->fileinfo,
|
||||
l + strlen (to_file->cmds->fileinfo.filenm) + INTSTR_LENGTH,
|
||||
_("Recipe was specified for file '%s' at %s:%lu,"),
|
||||
from_file->name, to_file->cmds->fileinfo.filenm,
|
||||
to_file->cmds->fileinfo.lineno);
|
||||
else
|
||||
error (&from_file->cmds->fileinfo,
|
||||
error (&from_file->cmds->fileinfo, l,
|
||||
_("Recipe for file '%s' was found by implicit rule search,"),
|
||||
from_file->name);
|
||||
error (&from_file->cmds->fileinfo,
|
||||
l += strlen (to_hname);
|
||||
error (&from_file->cmds->fileinfo, l,
|
||||
_("but '%s' is now considered the same file as '%s'."),
|
||||
from_file->name, to_hname);
|
||||
error (&from_file->cmds->fileinfo,
|
||||
error (&from_file->cmds->fileinfo, l,
|
||||
_("Recipe for '%s' will be ignored in favor of the one for '%s'."),
|
||||
to_hname, from_file->name);
|
||||
}
|
||||
@@ -297,13 +307,14 @@ rehash_file (struct file *from_file, const char *to_hname)
|
||||
merge_variable_set_lists (&to_file->variables, from_file->variables);
|
||||
|
||||
if (to_file->double_colon && from_file->is_target && !from_file->double_colon)
|
||||
fatal (NILF, _("can't rename single-colon '%s' to double-colon '%s'"),
|
||||
from_file->name, to_hname);
|
||||
OSS (fatal, NILF, _("can't rename single-colon '%s' to double-colon '%s'"),
|
||||
from_file->name, to_hname);
|
||||
if (!to_file->double_colon && from_file->double_colon)
|
||||
{
|
||||
if (to_file->is_target)
|
||||
fatal (NILF, _("can't rename double-colon '%s' to single-colon '%s'"),
|
||||
from_file->name, to_hname);
|
||||
OSS (fatal, NILF,
|
||||
_("can't rename double-colon '%s' to single-colon '%s'"),
|
||||
from_file->name, to_hname);
|
||||
else
|
||||
to_file->double_colon = from_file->double_colon;
|
||||
}
|
||||
@@ -393,7 +404,8 @@ remove_intermediates (int sig)
|
||||
if (!f->dontcare)
|
||||
{
|
||||
if (sig)
|
||||
error (NILF, _("*** Deleting intermediate file '%s'"), f->name);
|
||||
OS (error, NILF,
|
||||
_("*** Deleting intermediate file '%s'"), f->name);
|
||||
else
|
||||
{
|
||||
if (! doneany)
|
||||
@@ -803,10 +815,11 @@ file_timestamp_cons (const char *fname, time_t stamp, long int ns)
|
||||
&& product <= ts && ts <= ORDINARY_MTIME_MAX))
|
||||
{
|
||||
char buf[FILE_TIMESTAMP_PRINT_LEN_BOUND + 1];
|
||||
const char *f = fname ? fname : _("Current time");
|
||||
ts = s <= OLD_MTIME ? ORDINARY_MTIME_MIN : ORDINARY_MTIME_MAX;
|
||||
file_timestamp_sprintf (buf, ts);
|
||||
error (NILF, _("%s: Timestamp out of range; substituting %s"),
|
||||
fname ? fname : _("Current time"), buf);
|
||||
OSS (error, NILF,
|
||||
_("%s: Timestamp out of range; substituting %s"), f, buf);
|
||||
}
|
||||
|
||||
return ts;
|
||||
@@ -1046,9 +1059,10 @@ print_file_data_base (void)
|
||||
/* Verify the integrity of the data base of files. */
|
||||
|
||||
#define VERIFY_CACHED(_p,_n) \
|
||||
do{\
|
||||
if (_p->_n && _p->_n[0] && !strcache_iscached (_p->_n)) \
|
||||
error (NULL, _("%s: Field '%s' not cached: %s"), _p->name, # _n, _p->_n); \
|
||||
do{ \
|
||||
if (_p->_n && _p->_n[0] && !strcache_iscached (_p->_n)) \
|
||||
error (NULL, strlen (_p->name) + CSTRLEN (# _n) + strlen (_p->_n), \
|
||||
_("%s: Field '%s' not cached: %s"), _p->name, # _n, _p->_n); \
|
||||
}while(0)
|
||||
|
||||
static void
|
||||
|
||||
13
filedef.h
13
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,6 +58,8 @@ 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. */
|
||||
enum update_status /* Status of the last attempt to update. */
|
||||
{
|
||||
@@ -96,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);
|
||||
@@ -117,9 +117,12 @@ void rehash_file (struct file *file, const char *name);
|
||||
void set_command_state (struct file *file, enum cmd_state state);
|
||||
void notice_finished_file (struct file *file);
|
||||
void init_hash_files (void);
|
||||
void verify_file_data_base (void);
|
||||
char *build_target_list (char *old_list);
|
||||
void print_prereqs (const struct dep *deps);
|
||||
void print_file_data_base (void);
|
||||
int try_implicit_rule (struct file *file, unsigned int depth);
|
||||
int stemlen_compare (const void *v1, const void *v2);
|
||||
|
||||
#if FILE_TIMESTAMP_HI_RES
|
||||
# define FILE_TIMESTAMP_STAT_MODTIME(fname, st) \
|
||||
@@ -143,7 +146,7 @@ void print_file_data_base (void);
|
||||
& ((1 << FILE_TIMESTAMP_LO_BITS) - 1)))
|
||||
|
||||
/* Upper bound on length of string "YYYY-MM-DD HH:MM:SS.NNNNNNNNN"
|
||||
representing a file timestamp. The upper bound is not necessarily 19,
|
||||
representing a file timestamp. The upper bound is not necessarily 29,
|
||||
since the year might be less than -999 or greater than 9999.
|
||||
|
||||
Subtract one for the sign bit if in case file timestamps can be negative;
|
||||
|
||||
518
function.c
518
function.c
@@ -1,5 +1,5 @@
|
||||
/* Builtin function expansion for GNU Make.
|
||||
Copyright (C) 1988-2013 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988-2016 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
@@ -31,7 +31,7 @@ struct function_table_entry
|
||||
{
|
||||
union {
|
||||
char *(*func_ptr) (char *output, char **argv, const char *fname);
|
||||
char *(*alloc_func_ptr) (const char *fname, int argc, char **argv);
|
||||
gmk_func_ptr alloc_func_ptr;
|
||||
} fptr;
|
||||
const char *name;
|
||||
unsigned char len;
|
||||
@@ -115,8 +115,8 @@ subst_expand (char *o, const char *text, const char *subst, const char *replace,
|
||||
/* If we're substituting only by fully matched words,
|
||||
or only at the ends of words, check that this case qualifies. */
|
||||
if (by_word
|
||||
&& ((p > text && !isblank ((unsigned char)p[-1]))
|
||||
|| ! STOP_SET (p[slen], MAP_BLANK|MAP_NUL)))
|
||||
&& ((p > text && !ISSPACE (p[-1]))
|
||||
|| ! STOP_SET (p[slen], MAP_SPACE|MAP_NUL)))
|
||||
/* Struck out. Output the rest of the string that is
|
||||
no longer to be replaced. */
|
||||
o = variable_buffer_output (o, subst, slen);
|
||||
@@ -269,19 +269,19 @@ patsubst_expand (char *o, const char *text, char *pattern, char *replace)
|
||||
static const struct function_table_entry *
|
||||
lookup_function (const char *s)
|
||||
{
|
||||
struct function_table_entry function_table_entry_key;
|
||||
const char *e = s;
|
||||
|
||||
while (*e && ( (*e >= 'a' && *e <= 'z') || *e == '-'))
|
||||
while (STOP_SET (*e, MAP_USERFUNC))
|
||||
e++;
|
||||
if (*e == '\0' || isblank ((unsigned char) *e))
|
||||
{
|
||||
struct function_table_entry function_table_entry_key;
|
||||
function_table_entry_key.name = s;
|
||||
function_table_entry_key.len = e - s;
|
||||
|
||||
return hash_find_item (&function_table, &function_table_entry_key);
|
||||
}
|
||||
return 0;
|
||||
if (e == s || !STOP_SET(*e, MAP_NUL|MAP_SPACE))
|
||||
return NULL;
|
||||
|
||||
function_table_entry_key.name = s;
|
||||
function_table_entry_key.len = e - s;
|
||||
|
||||
return hash_find_item (&function_table, &function_table_entry_key);
|
||||
}
|
||||
|
||||
|
||||
@@ -519,8 +519,25 @@ func_notdir_suffix (char *o, char **argv, const char *funcname)
|
||||
|
||||
int is_suffix = funcname[0] == 's';
|
||||
int is_notdir = !is_suffix;
|
||||
int stop = MAP_PATHSEP | (is_suffix ? MAP_DOT : 0);
|
||||
int stop = MAP_DIRSEP | (is_suffix ? MAP_DOT : 0);
|
||||
#ifdef VMS
|
||||
/* For VMS list_iterator points to a comma separated list. To use the common
|
||||
[find_]next_token, create a local copy and replace the commas with
|
||||
spaces. Obviously, there is a problem if there is a ',' in the VMS filename
|
||||
(can only happen on ODS5), the same problem as with spaces in filenames,
|
||||
which seems to be present in make on all platforms. */
|
||||
char *vms_list_iterator = alloca(strlen(list_iterator) + 1);
|
||||
int i;
|
||||
for (i = 0; list_iterator[i]; i++)
|
||||
if (list_iterator[i] == ',')
|
||||
vms_list_iterator[i] = ' ';
|
||||
else
|
||||
vms_list_iterator[i] = list_iterator[i];
|
||||
vms_list_iterator[i] = list_iterator[i];
|
||||
while ((p2 = find_next_token((const char**) &vms_list_iterator, &len)) != 0)
|
||||
#else
|
||||
while ((p2 = find_next_token (&list_iterator, &len)) != 0)
|
||||
#endif
|
||||
{
|
||||
const char *p = p2 + len - 1;
|
||||
|
||||
@@ -548,7 +565,13 @@ func_notdir_suffix (char *o, char **argv, const char *funcname)
|
||||
|
||||
if (is_notdir || p >= p2)
|
||||
{
|
||||
#ifdef VMS
|
||||
if (vms_comma_separator)
|
||||
o = variable_buffer_output (o, ",", 1);
|
||||
else
|
||||
#endif
|
||||
o = variable_buffer_output (o, " ", 1);
|
||||
|
||||
doneany = 1;
|
||||
}
|
||||
}
|
||||
@@ -572,8 +595,21 @@ func_basename_dir (char *o, char **argv, const char *funcname)
|
||||
|
||||
int is_basename = funcname[0] == 'b';
|
||||
int is_dir = !is_basename;
|
||||
int stop = MAP_PATHSEP | (is_basename ? MAP_DOT : 0) | MAP_NUL;
|
||||
int stop = MAP_DIRSEP | (is_basename ? MAP_DOT : 0) | MAP_NUL;
|
||||
#ifdef VMS
|
||||
/* As in func_notdir_suffix ... */
|
||||
char *vms_p3 = alloca (strlen(p3) + 1);
|
||||
int i;
|
||||
for (i = 0; p3[i]; i++)
|
||||
if (p3[i] == ',')
|
||||
vms_p3[i] = ' ';
|
||||
else
|
||||
vms_p3[i] = p3[i];
|
||||
vms_p3[i] = p3[i];
|
||||
while ((p2 = find_next_token((const char**) &vms_p3, &len)) != 0)
|
||||
#else
|
||||
while ((p2 = find_next_token (&p3, &len)) != 0)
|
||||
#endif
|
||||
{
|
||||
const char *p = p2 + len - 1;
|
||||
while (p >= p2 && ! STOP_SET (*p, stop))
|
||||
@@ -590,7 +626,13 @@ func_basename_dir (char *o, char **argv, const char *funcname)
|
||||
#endif
|
||||
else if (is_dir)
|
||||
#ifdef VMS
|
||||
o = variable_buffer_output (o, "[]", 2);
|
||||
{
|
||||
extern int vms_report_unix_paths;
|
||||
if (vms_report_unix_paths)
|
||||
o = variable_buffer_output (o, "./", 2);
|
||||
else
|
||||
o = variable_buffer_output (o, "[]", 2);
|
||||
}
|
||||
#else
|
||||
#ifndef _AMIGA
|
||||
o = variable_buffer_output (o, "./", 2);
|
||||
@@ -602,7 +644,13 @@ func_basename_dir (char *o, char **argv, const char *funcname)
|
||||
/* The entire name is the basename. */
|
||||
o = variable_buffer_output (o, p2, len);
|
||||
|
||||
o = variable_buffer_output (o, " ", 1);
|
||||
#ifdef VMS
|
||||
if (vms_comma_separator)
|
||||
o = variable_buffer_output (o, ",", 1);
|
||||
else
|
||||
#endif
|
||||
o = variable_buffer_output (o, " ", 1);
|
||||
|
||||
doneany = 1;
|
||||
}
|
||||
|
||||
@@ -707,9 +755,9 @@ func_words (char *o, char **argv, const char *funcname UNUSED)
|
||||
char *
|
||||
strip_whitespace (const char **begpp, const char **endpp)
|
||||
{
|
||||
while (*begpp <= *endpp && isspace ((unsigned char)**begpp))
|
||||
while (*begpp <= *endpp && ISSPACE (**begpp))
|
||||
(*begpp) ++;
|
||||
while (*endpp >= *begpp && isspace ((unsigned char)**endpp))
|
||||
while (*endpp >= *begpp && ISSPACE (**endpp))
|
||||
(*endpp) --;
|
||||
return (char *)*begpp;
|
||||
}
|
||||
@@ -726,7 +774,7 @@ check_numeric (const char *s, const char *msg)
|
||||
break;
|
||||
|
||||
if (s <= end || end - beg < 0)
|
||||
fatal (*expanding_var, "%s: '%s'", msg, beg);
|
||||
OSS (fatal, *expanding_var, "%s: '%s'", msg, beg);
|
||||
}
|
||||
|
||||
|
||||
@@ -743,8 +791,8 @@ func_word (char *o, char **argv, const char *funcname UNUSED)
|
||||
i = atoi (argv[0]);
|
||||
|
||||
if (i == 0)
|
||||
fatal (*expanding_var,
|
||||
_("first argument to 'word' function must be greater than 0"));
|
||||
O (fatal, *expanding_var,
|
||||
_("first argument to 'word' function must be greater than 0"));
|
||||
|
||||
end_p = argv[1];
|
||||
while ((p = find_next_token (&end_p, 0)) != 0)
|
||||
@@ -770,8 +818,8 @@ func_wordlist (char *o, char **argv, const char *funcname UNUSED)
|
||||
|
||||
start = atoi (argv[0]);
|
||||
if (start < 1)
|
||||
fatal (*expanding_var,
|
||||
"invalid first argument to 'wordlist' function: '%d'", start);
|
||||
ON (fatal, *expanding_var,
|
||||
"invalid first argument to 'wordlist' function: '%d'", start);
|
||||
|
||||
count = atoi (argv[1]) - start + 1;
|
||||
|
||||
@@ -822,8 +870,12 @@ func_foreach (char *o, char **argv, const char *funcname UNUSED)
|
||||
unsigned int len;
|
||||
struct variable *var;
|
||||
|
||||
/* Clean up the variable name by removing whitespace. */
|
||||
char *vp = next_token (varname);
|
||||
end_of_token (vp)[0] = '\0';
|
||||
|
||||
push_new_variable_scope ();
|
||||
var = define_variable (varname, strlen (varname), "", o_automatic, 0);
|
||||
var = define_variable (vp, strlen (vp), "", o_automatic, 0);
|
||||
|
||||
/* loop through LIST, put the value in VAR and expand BODY */
|
||||
while ((p = find_next_token (&list_iterator, &len)) != 0)
|
||||
@@ -1033,10 +1085,9 @@ func_strip (char *o, char **argv, const char *funcname UNUSED)
|
||||
int i=0;
|
||||
const char *word_start;
|
||||
|
||||
while (isspace ((unsigned char)*p))
|
||||
++p;
|
||||
NEXT_TOKEN (p);
|
||||
word_start = p;
|
||||
for (i=0; *p != '\0' && !isspace ((unsigned char)*p); ++p, ++i)
|
||||
for (i=0; *p != '\0' && !ISSPACE (*p); ++p, ++i)
|
||||
{}
|
||||
if (!i)
|
||||
break;
|
||||
@@ -1082,10 +1133,10 @@ func_error (char *o, char **argv, const char *funcname)
|
||||
switch (*funcname)
|
||||
{
|
||||
case 'e':
|
||||
fatal (reading_file, "%s", msg);
|
||||
OS (fatal, reading_file, "%s", msg);
|
||||
|
||||
case 'w':
|
||||
error (reading_file, "%s", msg);
|
||||
OS (error, reading_file, "%s", msg);
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
@@ -1094,7 +1145,7 @@ func_error (char *o, char **argv, const char *funcname)
|
||||
break;
|
||||
|
||||
default:
|
||||
fatal (*expanding_var, "Internal error: func_error: '%s'", funcname);
|
||||
OS (fatal, *expanding_var, "Internal error: func_error: '%s'", funcname);
|
||||
}
|
||||
|
||||
/* The warning function expands to the empty string. */
|
||||
@@ -1402,10 +1453,23 @@ fold_newlines (char *buffer, unsigned int *length, int trim_newlines)
|
||||
*length = last_nonnl - buffer;
|
||||
}
|
||||
|
||||
pid_t shell_function_pid = 0;
|
||||
static int shell_function_completed;
|
||||
|
||||
void
|
||||
shell_completed (int exit_code, int exit_sig)
|
||||
{
|
||||
char buf[256];
|
||||
|
||||
int shell_function_pid = 0, shell_function_completed;
|
||||
shell_function_pid = 0;
|
||||
if (exit_sig == 0 && exit_code == 127)
|
||||
shell_function_completed = -1;
|
||||
else
|
||||
shell_function_completed = 1;
|
||||
|
||||
sprintf (buf, "%d", exit_code);
|
||||
define_variable_cname (".SHELLSTATUS", buf, o_override, 0);
|
||||
}
|
||||
|
||||
#ifdef WINDOWS32
|
||||
/*untested*/
|
||||
@@ -1416,7 +1480,7 @@ int shell_function_pid = 0, shell_function_completed;
|
||||
|
||||
|
||||
int
|
||||
windows32_openpipe (int *pipedes, pid_t *pid_p, char **command_argv, char **envp)
|
||||
windows32_openpipe (int *pipedes, int errfd, pid_t *pid_p, char **command_argv, char **envp)
|
||||
{
|
||||
SECURITY_ATTRIBUTES saAttr;
|
||||
HANDLE hIn = INVALID_HANDLE_VALUE;
|
||||
@@ -1457,11 +1521,12 @@ windows32_openpipe (int *pipedes, pid_t *pid_p, char **command_argv, char **envp
|
||||
}
|
||||
if (hIn == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
error (NILF, _("windows32_openpipe: DuplicateHandle(In) failed (e=%ld)\n"), e);
|
||||
ON (error, NILF,
|
||||
_("windows32_openpipe: DuplicateHandle(In) failed (e=%ld)\n"), e);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
tmpErr = GetStdHandle (STD_ERROR_HANDLE);
|
||||
tmpErr = (HANDLE)_get_osfhandle (errfd);
|
||||
if (DuplicateHandle (GetCurrentProcess (), tmpErr,
|
||||
GetCurrentProcess (), &hErr,
|
||||
0, TRUE, DUPLICATE_SAME_ACCESS) == FALSE)
|
||||
@@ -1480,14 +1545,15 @@ windows32_openpipe (int *pipedes, pid_t *pid_p, char **command_argv, char **envp
|
||||
}
|
||||
if (hErr == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
error (NILF, _("windows32_openpipe: DuplicateHandle(Err) failed (e=%ld)\n"), e);
|
||||
ON (error, NILF,
|
||||
_("windows32_openpipe: DuplicateHandle(Err) failed (e=%ld)\n"), e);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (! CreatePipe (&hChildOutRd, &hChildOutWr, &saAttr, 0))
|
||||
{
|
||||
error (NILF, _("CreatePipe() failed (e=%ld)\n"), GetLastError());
|
||||
ON (error, NILF, _("CreatePipe() failed (e=%ld)\n"), GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1495,7 +1561,7 @@ windows32_openpipe (int *pipedes, pid_t *pid_p, char **command_argv, char **envp
|
||||
|
||||
if (!hProcess)
|
||||
{
|
||||
error (NILF, _("windows32_openpipe(): process_init_fd() failed\n"));
|
||||
O (error, NILF, _("windows32_openpipe(): process_init_fd() failed\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1552,8 +1618,7 @@ msdos_openpipe (int* pipedes, int *pidp, char *text)
|
||||
extern int dos_command_running, dos_status;
|
||||
|
||||
/* Make sure not to bother processing an empty line. */
|
||||
while (isblank ((unsigned char)*text))
|
||||
++text;
|
||||
NEXT_TOKEN (text);
|
||||
if (*text == '\0')
|
||||
return 0;
|
||||
|
||||
@@ -1583,14 +1648,15 @@ msdos_openpipe (int* pipedes, int *pidp, char *text)
|
||||
errno = EINTR;
|
||||
else if (errno == 0)
|
||||
errno = ENOMEM;
|
||||
shell_function_completed = -1;
|
||||
if (fpipe)
|
||||
pclose (fpipe);
|
||||
shell_completed (127, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
pipedes[0] = fileno (fpipe);
|
||||
*pidp = 42; /* Yes, the Meaning of Life, the Universe, and Everything! */
|
||||
errno = e;
|
||||
shell_function_completed = 1;
|
||||
}
|
||||
return fpipe;
|
||||
}
|
||||
@@ -1608,7 +1674,7 @@ char *
|
||||
func_shell_base (char *o, char **argv, int trim_newlines)
|
||||
{
|
||||
fprintf (stderr, "This platform does not support shell\n");
|
||||
die (EXIT_FAILURE);
|
||||
die (MAKE_TROUBLE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1620,7 +1686,7 @@ char *
|
||||
func_shell_base (char *o, char **argv, int trim_newlines)
|
||||
{
|
||||
char *batch_filename = NULL;
|
||||
|
||||
int errfd;
|
||||
#ifdef __MSDOS__
|
||||
FILE *fpipe;
|
||||
#endif
|
||||
@@ -1636,9 +1702,9 @@ func_shell_base (char *o, char **argv, int trim_newlines)
|
||||
are used to run the commands, because we normally refrain from
|
||||
creating batch files under -n. */
|
||||
int j_p_f = just_print_flag;
|
||||
|
||||
just_print_flag = 0;
|
||||
#endif
|
||||
|
||||
/* Construct the argument list. */
|
||||
command_argv = construct_command_argv (argv[0], NULL, NULL, 0,
|
||||
&batch_filename);
|
||||
@@ -1649,18 +1715,18 @@ func_shell_base (char *o, char **argv, int trim_newlines)
|
||||
#endif
|
||||
return o;
|
||||
}
|
||||
#endif
|
||||
#endif /* !__MSDOS__ */
|
||||
|
||||
/* Using a target environment for 'shell' loses in cases like:
|
||||
export var = $(shell echo foobie)
|
||||
because target_environment hits a loop trying to expand $(var)
|
||||
to put it in the environment. This is even more confusing when
|
||||
var was not explicitly exported, but just appeared in the
|
||||
calling environment.
|
||||
export var = $(shell echo foobie)
|
||||
bad := $(var)
|
||||
because target_environment hits a loop trying to expand $(var) to put it
|
||||
in the environment. This is even more confusing when 'var' was not
|
||||
explicitly exported, but just appeared in the calling environment.
|
||||
|
||||
See Savannah bug #10593.
|
||||
|
||||
envp = target_environment (NILF);
|
||||
envp = target_environment (NULL);
|
||||
*/
|
||||
|
||||
envp = environ;
|
||||
@@ -1669,7 +1735,8 @@ func_shell_base (char *o, char **argv, int trim_newlines)
|
||||
if (reading_file && reading_file->filenm)
|
||||
{
|
||||
char *p = alloca (strlen (reading_file->filenm)+11+4);
|
||||
sprintf (p, "%s:%lu: ", reading_file->filenm, reading_file->lineno);
|
||||
sprintf (p, "%s:%lu: ", reading_file->filenm,
|
||||
reading_file->lineno + reading_file->offset);
|
||||
error_prefix = p;
|
||||
}
|
||||
else
|
||||
@@ -1678,6 +1745,9 @@ func_shell_base (char *o, char **argv, int trim_newlines)
|
||||
/* Set up the output in case the shell writes something. */
|
||||
output_start ();
|
||||
|
||||
errfd = (output_context && output_context->err >= 0
|
||||
? output_context->err : FD_STDERR);
|
||||
|
||||
#if defined(__MSDOS__)
|
||||
fpipe = msdos_openpipe (pipedes, &pid, argv[0]);
|
||||
if (pipedes[0] < 0)
|
||||
@@ -1685,19 +1755,20 @@ func_shell_base (char *o, char **argv, int trim_newlines)
|
||||
perror_with_name (error_prefix, "pipe");
|
||||
return o;
|
||||
}
|
||||
|
||||
#elif defined(WINDOWS32)
|
||||
windows32_openpipe (pipedes, &pid, command_argv, envp);
|
||||
windows32_openpipe (pipedes, errfd, &pid, command_argv, envp);
|
||||
/* Restore the value of just_print_flag. */
|
||||
just_print_flag = j_p_f;
|
||||
|
||||
if (pipedes[0] < 0)
|
||||
{
|
||||
/* Open of the pipe failed, mark as failed execution. */
|
||||
shell_function_completed = -1;
|
||||
shell_completed (127, 0);
|
||||
perror_with_name (error_prefix, "pipe");
|
||||
return o;
|
||||
}
|
||||
else
|
||||
|
||||
#else
|
||||
if (pipe (pipedes) < 0)
|
||||
{
|
||||
@@ -1705,115 +1776,113 @@ func_shell_base (char *o, char **argv, int trim_newlines)
|
||||
return o;
|
||||
}
|
||||
|
||||
# ifdef __EMX__
|
||||
/* close some handles that are unnecessary for the child process */
|
||||
/* Close handles that are unnecessary for the child process. */
|
||||
CLOSE_ON_EXEC(pipedes[1]);
|
||||
CLOSE_ON_EXEC(pipedes[0]);
|
||||
/* Never use fork()/exec() here! Use spawn() instead in exec_command() */
|
||||
pid = child_execute_job (0, pipedes[1], command_argv, envp);
|
||||
if (pid < 0)
|
||||
perror_with_name (error_prefix, "spawn");
|
||||
# else /* ! __EMX__ */
|
||||
pid = fork ();
|
||||
if (pid < 0)
|
||||
perror_with_name (error_prefix, "fork");
|
||||
else if (pid == 0)
|
||||
{
|
||||
#ifdef SET_STACK_SIZE
|
||||
/* Reset limits, if necessary. */
|
||||
if (stack_limit.rlim_cur)
|
||||
setrlimit (RLIMIT_STACK, &stack_limit);
|
||||
#endif
|
||||
child_execute_job (0, pipedes[1], command_argv, envp);
|
||||
}
|
||||
else
|
||||
# endif
|
||||
#endif
|
||||
{
|
||||
/* We are the parent. */
|
||||
char *buffer;
|
||||
unsigned int maxlen, i;
|
||||
int cc;
|
||||
|
||||
/* Record the PID for reap_children. */
|
||||
shell_function_pid = pid;
|
||||
{
|
||||
struct output out;
|
||||
out.syncout = 1;
|
||||
out.out = pipedes[1];
|
||||
out.err = errfd;
|
||||
|
||||
pid = child_execute_job (&out, 1, command_argv, envp);
|
||||
}
|
||||
|
||||
if (pid < 0)
|
||||
{
|
||||
perror_with_name (error_prefix, "fork");
|
||||
return o;
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
char *buffer;
|
||||
unsigned int maxlen, i;
|
||||
int cc;
|
||||
|
||||
/* Record the PID for reap_children. */
|
||||
shell_function_pid = pid;
|
||||
#ifndef __MSDOS__
|
||||
shell_function_completed = 0;
|
||||
shell_function_completed = 0;
|
||||
|
||||
/* Free the storage only the child needed. */
|
||||
free (command_argv[0]);
|
||||
free (command_argv);
|
||||
/* Free the storage only the child needed. */
|
||||
free (command_argv[0]);
|
||||
free (command_argv);
|
||||
|
||||
/* Close the write side of the pipe. We test for -1, since
|
||||
pipedes[1] is -1 on MS-Windows, and some versions of MS
|
||||
libraries barf when 'close' is called with -1. */
|
||||
if (pipedes[1] >= 0)
|
||||
close (pipedes[1]);
|
||||
/* Close the write side of the pipe. We test for -1, since
|
||||
pipedes[1] is -1 on MS-Windows, and some versions of MS
|
||||
libraries barf when 'close' is called with -1. */
|
||||
if (pipedes[1] >= 0)
|
||||
close (pipedes[1]);
|
||||
#endif
|
||||
|
||||
/* Set up and read from the pipe. */
|
||||
/* Set up and read from the pipe. */
|
||||
|
||||
maxlen = 200;
|
||||
buffer = xmalloc (maxlen + 1);
|
||||
maxlen = 200;
|
||||
buffer = xmalloc (maxlen + 1);
|
||||
|
||||
/* Read from the pipe until it gets EOF. */
|
||||
for (i = 0; ; i += cc)
|
||||
{
|
||||
if (i == maxlen)
|
||||
{
|
||||
maxlen += 512;
|
||||
buffer = xrealloc (buffer, maxlen + 1);
|
||||
}
|
||||
/* Read from the pipe until it gets EOF. */
|
||||
for (i = 0; ; i += cc)
|
||||
{
|
||||
if (i == maxlen)
|
||||
{
|
||||
maxlen += 512;
|
||||
buffer = xrealloc (buffer, maxlen + 1);
|
||||
}
|
||||
|
||||
EINTRLOOP (cc, read (pipedes[0], &buffer[i], maxlen - i));
|
||||
if (cc <= 0)
|
||||
break;
|
||||
}
|
||||
buffer[i] = '\0';
|
||||
EINTRLOOP (cc, read (pipedes[0], &buffer[i], maxlen - i));
|
||||
if (cc <= 0)
|
||||
break;
|
||||
}
|
||||
buffer[i] = '\0';
|
||||
|
||||
/* Close the read side of the pipe. */
|
||||
/* Close the read side of the pipe. */
|
||||
#ifdef __MSDOS__
|
||||
if (fpipe)
|
||||
(void) pclose (fpipe);
|
||||
if (fpipe)
|
||||
{
|
||||
int st = pclose (fpipe);
|
||||
shell_completed (st, 0);
|
||||
}
|
||||
#else
|
||||
(void) close (pipedes[0]);
|
||||
(void) close (pipedes[0]);
|
||||
#endif
|
||||
|
||||
/* Loop until child_handler or reap_children() sets
|
||||
shell_function_completed to the status of our child shell. */
|
||||
while (shell_function_completed == 0)
|
||||
reap_children (1, 0);
|
||||
/* Loop until child_handler or reap_children() sets
|
||||
shell_function_completed to the status of our child shell. */
|
||||
while (shell_function_completed == 0)
|
||||
reap_children (1, 0);
|
||||
|
||||
if (batch_filename)
|
||||
{
|
||||
DB (DB_VERBOSE, (_("Cleaning up temporary batch file %s\n"),
|
||||
batch_filename));
|
||||
remove (batch_filename);
|
||||
free (batch_filename);
|
||||
}
|
||||
shell_function_pid = 0;
|
||||
if (batch_filename)
|
||||
{
|
||||
DB (DB_VERBOSE, (_("Cleaning up temporary batch file %s\n"),
|
||||
batch_filename));
|
||||
remove (batch_filename);
|
||||
free (batch_filename);
|
||||
}
|
||||
shell_function_pid = 0;
|
||||
|
||||
/* The child_handler function will set shell_function_completed
|
||||
to 1 when the child dies normally, or to -1 if it
|
||||
dies with status 127, which is most likely an exec fail. */
|
||||
/* shell_completed() will set shell_function_completed to 1 when the
|
||||
child dies normally, or to -1 if it dies with status 127, which is
|
||||
most likely an exec fail. */
|
||||
|
||||
if (shell_function_completed == -1)
|
||||
{
|
||||
/* This likely means that the execvp failed, so we should just
|
||||
write the error message in the pipe from the child. */
|
||||
fputs (buffer, stderr);
|
||||
fflush (stderr);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The child finished normally. Replace all newlines in its output
|
||||
with spaces, and put that in the variable output buffer. */
|
||||
fold_newlines (buffer, &i, trim_newlines);
|
||||
o = variable_buffer_output (o, buffer, i);
|
||||
}
|
||||
if (shell_function_completed == -1)
|
||||
{
|
||||
/* This likely means that the execvp failed, so we should just
|
||||
write the error message in the pipe from the child. */
|
||||
fputs (buffer, stderr);
|
||||
fflush (stderr);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The child finished normally. Replace all newlines in its output
|
||||
with spaces, and put that in the variable output buffer. */
|
||||
fold_newlines (buffer, &i, trim_newlines);
|
||||
o = variable_buffer_output (o, buffer, i);
|
||||
}
|
||||
|
||||
free (buffer);
|
||||
}
|
||||
free (buffer);
|
||||
}
|
||||
|
||||
return o;
|
||||
}
|
||||
@@ -1907,7 +1976,7 @@ func_shell_base (char *o, char **argv, int trim_newlines)
|
||||
}
|
||||
#endif /* _AMIGA */
|
||||
|
||||
char *
|
||||
static char *
|
||||
func_shell (char *o, char **argv, const char *funcname UNUSED)
|
||||
{
|
||||
return func_shell_base (o, argv, 1);
|
||||
@@ -1936,8 +2005,7 @@ func_not (char *o, char **argv, char *funcname UNUSED)
|
||||
{
|
||||
const char *s = argv[0];
|
||||
int result = 0;
|
||||
while (isspace ((unsigned char)*s))
|
||||
s++;
|
||||
NEXT_TOKEN (s);
|
||||
result = ! (*s);
|
||||
o = variable_buffer_output (o, result ? "1" : "", result);
|
||||
return o;
|
||||
@@ -1946,8 +2014,12 @@ func_not (char *o, char **argv, char *funcname UNUSED)
|
||||
|
||||
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
#define IS_ABSOLUTE(n) (n[0] && n[1] == ':')
|
||||
#define ROOT_LEN 3
|
||||
# ifdef __CYGWIN__
|
||||
# define IS_ABSOLUTE(n) ((n[0] && n[1] == ':') || STOP_SET (n[0], MAP_DIRSEP))
|
||||
# else
|
||||
# define IS_ABSOLUTE(n) (n[0] && n[1] == ':')
|
||||
# endif
|
||||
# define ROOT_LEN 3
|
||||
#else
|
||||
#define IS_ABSOLUTE(n) (n[0] == '/')
|
||||
#define ROOT_LEN 1
|
||||
@@ -1977,9 +2049,9 @@ abspath (const char *name, char *apath)
|
||||
strcpy (apath, starting_directory);
|
||||
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
if (STOP_SET (name[0], MAP_PATHSEP))
|
||||
if (STOP_SET (name[0], MAP_DIRSEP))
|
||||
{
|
||||
if (STOP_SET (name[1], MAP_PATHSEP))
|
||||
if (STOP_SET (name[1], MAP_DIRSEP))
|
||||
{
|
||||
/* A UNC. Don't prepend a drive letter. */
|
||||
apath[0] = name[0];
|
||||
@@ -1998,13 +2070,17 @@ abspath (const char *name, char *apath)
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(__CYGWIN__) && defined(HAVE_DOS_PATHS)
|
||||
if (STOP_SET (name[0], MAP_DIRSEP))
|
||||
root_len = 1;
|
||||
#endif
|
||||
strncpy (apath, name, root_len);
|
||||
apath[root_len] = '\0';
|
||||
dest = apath + root_len;
|
||||
/* Get past the root, since we already copied it. */
|
||||
name += root_len;
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
if (! STOP_SET (apath[2], MAP_PATHSEP))
|
||||
if (! STOP_SET (apath[root_len - 1], MAP_DIRSEP))
|
||||
{
|
||||
/* Convert d:foo into d:./foo and increase root_len. */
|
||||
apath[2] = '.';
|
||||
@@ -2015,7 +2091,7 @@ abspath (const char *name, char *apath)
|
||||
name--;
|
||||
}
|
||||
else
|
||||
apath[2] = '/'; /* make sure it's a forward slash */
|
||||
apath[root_len - 1] = '/'; /* make sure it's a forward slash */
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -2024,11 +2100,11 @@ abspath (const char *name, char *apath)
|
||||
unsigned long len;
|
||||
|
||||
/* Skip sequence of multiple path-separators. */
|
||||
while (STOP_SET (*start, MAP_PATHSEP))
|
||||
while (STOP_SET (*start, MAP_DIRSEP))
|
||||
++start;
|
||||
|
||||
/* Find end of path component. */
|
||||
for (end = start; ! STOP_SET (*end, MAP_PATHSEP|MAP_NUL); ++end)
|
||||
for (end = start; ! STOP_SET (*end, MAP_DIRSEP|MAP_NUL); ++end)
|
||||
;
|
||||
|
||||
len = end - start;
|
||||
@@ -2041,12 +2117,12 @@ abspath (const char *name, char *apath)
|
||||
{
|
||||
/* Back up to previous component, ignore if at root already. */
|
||||
if (dest > apath + root_len)
|
||||
for (--dest; ! STOP_SET (dest[-1], MAP_PATHSEP); --dest)
|
||||
for (--dest; ! STOP_SET (dest[-1], MAP_DIRSEP); --dest)
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (! STOP_SET (dest[-1], MAP_PATHSEP))
|
||||
if (! STOP_SET (dest[-1], MAP_DIRSEP))
|
||||
*dest++ = '/';
|
||||
|
||||
if (dest + len >= apath_limit)
|
||||
@@ -2059,7 +2135,7 @@ abspath (const char *name, char *apath)
|
||||
}
|
||||
|
||||
/* Unless it is root strip trailing separator. */
|
||||
if (dest > apath + root_len && STOP_SET (dest[-1], MAP_PATHSEP))
|
||||
if (dest > apath + root_len && STOP_SET (dest[-1], MAP_DIRSEP))
|
||||
--dest;
|
||||
|
||||
*dest = '\0';
|
||||
@@ -2133,24 +2209,70 @@ func_file (char *o, char **argv, const char *funcname UNUSED)
|
||||
mode = "a";
|
||||
++fn;
|
||||
}
|
||||
fn = next_token (fn);
|
||||
NEXT_TOKEN (fn);
|
||||
|
||||
fp = fopen (fn, mode);
|
||||
if (fn[0] == '\0')
|
||||
O (fatal, *expanding_var, _("file: missing filename"));
|
||||
|
||||
ENULLLOOP (fp, fopen (fn, mode));
|
||||
if (fp == NULL)
|
||||
fatal (reading_file, _("open: %s: %s"), fn, strerror (errno));
|
||||
else
|
||||
OSS (fatal, reading_file, _("open: %s: %s"), fn, strerror (errno));
|
||||
|
||||
if (argv[1])
|
||||
{
|
||||
int l = strlen (argv[1]);
|
||||
int nl = (l == 0 || argv[1][l-1] != '\n');
|
||||
int nl = l == 0 || argv[1][l-1] != '\n';
|
||||
|
||||
if (fputs (argv[1], fp) == EOF || (nl && fputc ('\n', fp) == EOF))
|
||||
fatal (reading_file, _("write: %s: %s"), fn, strerror (errno));
|
||||
|
||||
fclose (fp);
|
||||
OSS (fatal, reading_file, _("write: %s: %s"), fn, strerror (errno));
|
||||
}
|
||||
if (fclose (fp))
|
||||
OSS (fatal, reading_file, _("close: %s: %s"), fn, strerror (errno));
|
||||
}
|
||||
else if (fn[0] == '<')
|
||||
{
|
||||
char *preo = o;
|
||||
FILE *fp;
|
||||
|
||||
++fn;
|
||||
NEXT_TOKEN (fn);
|
||||
if (fn[0] == '\0')
|
||||
O (fatal, *expanding_var, _("file: missing filename"));
|
||||
|
||||
if (argv[1])
|
||||
O (fatal, *expanding_var, _("file: too many arguments"));
|
||||
|
||||
ENULLLOOP (fp, fopen (fn, "r"));
|
||||
if (fp == NULL)
|
||||
{
|
||||
if (errno == ENOENT)
|
||||
return o;
|
||||
OSS (fatal, reading_file, _("open: %s: %s"), fn, strerror (errno));
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
char buf[1024];
|
||||
size_t l = fread (buf, 1, sizeof (buf), fp);
|
||||
if (l > 0)
|
||||
o = variable_buffer_output (o, buf, l);
|
||||
|
||||
if (ferror (fp))
|
||||
if (errno != EINTR)
|
||||
OSS (fatal, reading_file, _("read: %s: %s"), fn, strerror (errno));
|
||||
if (feof (fp))
|
||||
break;
|
||||
}
|
||||
if (fclose (fp))
|
||||
OSS (fatal, reading_file, _("close: %s: %s"), fn, strerror (errno));
|
||||
|
||||
/* Remove trailing newline. */
|
||||
if (o > preo && o[-1] == '\n')
|
||||
if (--o > preo && o[-1] == '\r')
|
||||
--o;
|
||||
}
|
||||
else
|
||||
fatal (reading_file, _("Invalid file operation: %s"), fn);
|
||||
OS (fatal, *expanding_var, _("file: invalid file operation: %s"), fn);
|
||||
|
||||
return o;
|
||||
}
|
||||
@@ -2264,7 +2386,7 @@ expand_builtin_function (char *o, int argc, char **argv,
|
||||
char *p;
|
||||
|
||||
if (argc < (int)entry_p->minimum_args)
|
||||
fatal (*expanding_var,
|
||||
fatal (*expanding_var, strlen (entry_p->name),
|
||||
_("insufficient number of arguments (%d) to function '%s'"),
|
||||
argc, entry_p->name);
|
||||
|
||||
@@ -2276,8 +2398,8 @@ expand_builtin_function (char *o, int argc, char **argv,
|
||||
return o;
|
||||
|
||||
if (!entry_p->fptr.func_ptr)
|
||||
fatal (*expanding_var,
|
||||
_("unimplemented on this platform: function '%s'"), entry_p->name);
|
||||
OS (fatal, *expanding_var,
|
||||
_("unimplemented on this platform: function '%s'"), entry_p->name);
|
||||
|
||||
if (!entry_p->alloc_fn)
|
||||
return entry_p->fptr.func_ptr (o, argv, entry_p->name);
|
||||
@@ -2323,7 +2445,8 @@ handle_function (char **op, const char **stringp)
|
||||
/* We found a builtin function. Find the beginning of its arguments (skip
|
||||
whitespace after the name). */
|
||||
|
||||
beg = next_token (beg + entry_p->len);
|
||||
beg += entry_p->len;
|
||||
NEXT_TOKEN (beg);
|
||||
|
||||
/* Find the end of the function invocation, counting nested use of
|
||||
whichever kind of parens we use. Since we're looking, count commas
|
||||
@@ -2339,7 +2462,7 @@ handle_function (char **op, const char **stringp)
|
||||
break;
|
||||
|
||||
if (count >= 0)
|
||||
fatal (*expanding_var,
|
||||
fatal (*expanding_var, strlen (entry_p->name),
|
||||
_("unterminated call to function '%s': missing '%c'"),
|
||||
entry_p->name, closeparen);
|
||||
|
||||
@@ -2407,7 +2530,7 @@ handle_function (char **op, const char **stringp)
|
||||
if (entry_p->expand_args)
|
||||
for (argvp=argv; *argvp != 0; ++argvp)
|
||||
free (*argvp);
|
||||
else if (abeg)
|
||||
else
|
||||
free (abeg);
|
||||
|
||||
return 1;
|
||||
@@ -2423,7 +2546,6 @@ func_call (char *o, char **argv, const char *funcname UNUSED)
|
||||
{
|
||||
static int max_args = 0;
|
||||
char *fname;
|
||||
char *cp;
|
||||
char *body;
|
||||
int flen;
|
||||
int i;
|
||||
@@ -2431,16 +2553,9 @@ func_call (char *o, char **argv, const char *funcname UNUSED)
|
||||
const struct function_table_entry *entry_p;
|
||||
struct variable *v;
|
||||
|
||||
/* There is no way to define a variable with a space in the name, so strip
|
||||
leading and trailing whitespace as a favor to the user. */
|
||||
fname = argv[0];
|
||||
while (*fname != '\0' && isspace ((unsigned char)*fname))
|
||||
++fname;
|
||||
|
||||
cp = fname + strlen (fname) - 1;
|
||||
while (cp > fname && isspace ((unsigned char)*cp))
|
||||
--cp;
|
||||
cp[1] = '\0';
|
||||
/* Clean up the name of the variable to be invoked. */
|
||||
fname = next_token (argv[0]);
|
||||
end_of_token (fname)[0] = '\0';
|
||||
|
||||
/* Calling nothing is a no-op */
|
||||
if (*fname == '\0')
|
||||
@@ -2519,28 +2634,37 @@ func_call (char *o, char **argv, const char *funcname UNUSED)
|
||||
}
|
||||
|
||||
void
|
||||
define_new_function (const gmk_floc *flocp,
|
||||
const char *name, int min, int max, int expand,
|
||||
char *(*func)(const char *, int, char **))
|
||||
define_new_function (const floc *flocp, const char *name,
|
||||
unsigned int min, unsigned int max, unsigned int flags,
|
||||
gmk_func_ptr func)
|
||||
{
|
||||
const char *e = name;
|
||||
struct function_table_entry *ent;
|
||||
size_t len = strlen (name);
|
||||
size_t len;
|
||||
|
||||
while (STOP_SET (*e, MAP_USERFUNC))
|
||||
e++;
|
||||
len = e - name;
|
||||
|
||||
if (len == 0)
|
||||
O (fatal, flocp, _("Empty function name"));
|
||||
if (*name == '.' || *e != '\0')
|
||||
OS (fatal, flocp, _("Invalid function name: %s"), name);
|
||||
if (len > 255)
|
||||
fatal (flocp, _("Function name too long: %s\n"), name);
|
||||
if (min < 0 || min > 255)
|
||||
fatal (flocp, _("Invalid minimum argument count (%d) for function %s\n"),
|
||||
min, name);
|
||||
if (max < 0 || max > 255 || (max && max < min))
|
||||
fatal (flocp, _("Invalid maximum argument count (%d) for function %s\n"),
|
||||
max, name);
|
||||
OS (fatal, flocp, _("Function name too long: %s"), name);
|
||||
if (min > 255)
|
||||
ONS (fatal, flocp,
|
||||
_("Invalid minimum argument count (%u) for function %s"), min, name);
|
||||
if (max > 255 || (max && max < min))
|
||||
ONS (fatal, flocp,
|
||||
_("Invalid maximum argument count (%u) for function %s"), max, name);
|
||||
|
||||
ent = xmalloc (sizeof (struct function_table_entry));
|
||||
ent->name = name;
|
||||
ent->len = len;
|
||||
ent->minimum_args = min;
|
||||
ent->maximum_args = max;
|
||||
ent->expand_args = expand ? 1 : 0;
|
||||
ent->expand_args = ANY_SET(flags, GMK_FUNC_NOEXPAND) ? 0 : 1;
|
||||
ent->alloc_fn = 1;
|
||||
ent->fptr.alloc_func_ptr = func;
|
||||
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
50
guile.c
50
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
|
||||
@@ -15,14 +15,28 @@ You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "makeint.h"
|
||||
|
||||
#ifdef HAVE_GUILE
|
||||
|
||||
#include "gnumake.h"
|
||||
|
||||
#include "debug.h"
|
||||
#include "filedef.h"
|
||||
#include "dep.h"
|
||||
#include "variable.h"
|
||||
|
||||
#include <libguile.h>
|
||||
|
||||
/* Pre-2.0 versions of Guile don't have a typedef for gsubr function types. */
|
||||
#if SCM_MAJOR_VERSION < 2
|
||||
# define GSUBR_TYPE SCM (*) ()
|
||||
/* Guile 1.x doesn't really support i18n. */
|
||||
# define EVAL_STRING(_s) scm_c_eval_string (_s)
|
||||
#else
|
||||
# define GSUBR_TYPE scm_t_subr
|
||||
# define EVAL_STRING(_s) scm_eval_string (scm_from_utf8_string (_s))
|
||||
#endif
|
||||
|
||||
static SCM make_mod = SCM_EOL;
|
||||
static SCM obj_to_str = SCM_EOL;
|
||||
|
||||
@@ -71,10 +85,10 @@ guile_define_module (void *data UNUSED)
|
||||
#include "gmk-default.h"
|
||||
|
||||
/* Register a subr for GNU make's eval capability. */
|
||||
scm_c_define_gsubr ("gmk-expand", 1, 0, 0, guile_expand_wrapper);
|
||||
scm_c_define_gsubr ("gmk-expand", 1, 0, 0, (GSUBR_TYPE) guile_expand_wrapper);
|
||||
|
||||
/* Register a subr for GNU make's eval capability. */
|
||||
scm_c_define_gsubr ("gmk-eval", 1, 0, 0, guile_eval_wrapper);
|
||||
scm_c_define_gsubr ("gmk-eval", 1, 0, 0, (GSUBR_TYPE) guile_eval_wrapper);
|
||||
|
||||
/* Define the rest of the module. */
|
||||
scm_c_eval_string (GUILE_module_defn);
|
||||
@@ -99,13 +113,22 @@ guile_init (void *arg UNUSED)
|
||||
static void *
|
||||
internal_guile_eval (void *arg)
|
||||
{
|
||||
return cvt_scm_to_str (scm_c_eval_string (arg));
|
||||
return cvt_scm_to_str (EVAL_STRING (arg));
|
||||
}
|
||||
|
||||
/* This is the function registered with make */
|
||||
static char *
|
||||
func_guile (const char *funcname UNUSED, int argc UNUSED, char **argv)
|
||||
func_guile (const char *funcname UNUSED, unsigned int argc UNUSED, char **argv)
|
||||
{
|
||||
static int init = 0;
|
||||
|
||||
if (! init)
|
||||
{
|
||||
/* Initialize the Guile interpreter. */
|
||||
scm_with_guile (guile_init, NULL);
|
||||
init = 1;
|
||||
}
|
||||
|
||||
if (argv[0] && argv[0][0] != '\0')
|
||||
return scm_with_guile (internal_guile_eval, argv[0]);
|
||||
|
||||
@@ -117,13 +140,20 @@ func_guile (const char *funcname UNUSED, int argc UNUSED, char **argv)
|
||||
/* We could send the flocp to define_new_function(), but since guile is
|
||||
"kind of" built-in, that didn't seem so useful. */
|
||||
int
|
||||
guile_gmake_setup (const gmk_floc *flocp UNUSED)
|
||||
guile_gmake_setup (const floc *flocp UNUSED)
|
||||
{
|
||||
/* Initialize the Guile interpreter. */
|
||||
scm_with_guile (guile_init, NULL);
|
||||
|
||||
/* Create a make function "guile". */
|
||||
gmk_add_function ("guile", func_guile, 0, 1, 1);
|
||||
gmk_add_function ("guile", func_guile, 0, 1, GMK_FUNC_DEFAULT);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int
|
||||
guile_gmake_setup (const floc *flocp UNUSED)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
2
hash.c
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 */
|
||||
|
||||
72
implicit.c
72
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++);
|
||||
@@ -266,12 +265,15 @@ pattern_search (struct file *file, int archive,
|
||||
/* Set LASTSLASH to point at the last slash in FILENAME
|
||||
but not counting any slash at the end. (foo/bar/ counts as
|
||||
bar/ in directory foo/, not empty in directory foo/bar/.) */
|
||||
#ifdef VMS
|
||||
lastslash = strrchr (filename, ']');
|
||||
if (lastslash == 0)
|
||||
lastslash = strrchr (filename, ':');
|
||||
#else
|
||||
lastslash = strrchr (filename, '/');
|
||||
#ifdef VMS
|
||||
if (lastslash == NULL)
|
||||
lastslash = strrchr (filename, ']');
|
||||
if (lastslash == NULL)
|
||||
lastslash = strrchr (filename, '>');
|
||||
if (lastslash == NULL)
|
||||
lastslash = strrchr (filename, ':');
|
||||
#endif
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
/* Handle backslashes (possibly mixed with forward slashes)
|
||||
and the case of "d:file". */
|
||||
@@ -282,7 +284,6 @@ pattern_search (struct file *file, int archive,
|
||||
if (lastslash == 0 && filename[0] && filename[1] == ':')
|
||||
lastslash = filename + 1;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
if (lastslash != 0 && lastslash[1] == '\0')
|
||||
lastslash = 0;
|
||||
@@ -315,7 +316,7 @@ pattern_search (struct file *file, int archive,
|
||||
{
|
||||
const char *target = rule->targets[ti];
|
||||
const char *suffix = rule->suffixes[ti];
|
||||
int check_lastslash;
|
||||
char check_lastslash;
|
||||
|
||||
/* Rules that can match any filename and are not terminal
|
||||
are ignored if we're recursing, so that they cannot be
|
||||
@@ -339,10 +340,10 @@ pattern_search (struct file *file, int archive,
|
||||
if (lastslash)
|
||||
{
|
||||
#ifdef VMS
|
||||
check_lastslash = (strchr (target, ']') == 0
|
||||
&& strchr (target, ':') == 0);
|
||||
check_lastslash = strpbrk (target, "/]>:") == NULL;
|
||||
#else
|
||||
check_lastslash = strchr (target, '/') == 0;
|
||||
#endif
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
/* Didn't find it yet: check for DOS-type directories. */
|
||||
if (check_lastslash)
|
||||
@@ -350,7 +351,6 @@ pattern_search (struct file *file, int archive,
|
||||
char *b = strchr (target, '\\');
|
||||
check_lastslash = !(b || (target[0] && target[1] == ':'));
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
if (check_lastslash)
|
||||
@@ -437,7 +437,7 @@ pattern_search (struct file *file, int archive,
|
||||
for (ri = 0; ri < nrules; ri++)
|
||||
{
|
||||
struct dep *dep;
|
||||
int check_lastslash;
|
||||
char check_lastslash;
|
||||
unsigned int failed = 0;
|
||||
int file_variables_set = 0;
|
||||
unsigned int deps_found = 0;
|
||||
@@ -574,6 +574,7 @@ pattern_search (struct file *file, int archive,
|
||||
{
|
||||
int add_dir = 0;
|
||||
unsigned int len;
|
||||
struct dep **dptr;
|
||||
|
||||
nptr = get_next_word (nptr, &len);
|
||||
if (nptr == 0)
|
||||
@@ -616,6 +617,9 @@ pattern_search (struct file *file, int archive,
|
||||
add_dir = 1;
|
||||
}
|
||||
|
||||
/* Set up for the next word. */
|
||||
nptr += len;
|
||||
|
||||
/* Initialize and set file variables if we haven't already
|
||||
done so. */
|
||||
if (!file_vars_initialized)
|
||||
@@ -634,20 +638,33 @@ pattern_search (struct file *file, int archive,
|
||||
|
||||
/* Perform the 2nd expansion. */
|
||||
p = variable_expand_for_file (depname, file);
|
||||
dptr = &dl;
|
||||
|
||||
/* Parse the expanded string. */
|
||||
dl = PARSE_FILE_SEQ (&p, struct dep, order_only ? MAP_NUL : MAP_PIPE,
|
||||
add_dir ? dir : NULL, PARSEFS_NONE);
|
||||
|
||||
for (d = dl; d != NULL; d = d->next)
|
||||
/* Parse the results into a deps list. */
|
||||
do
|
||||
{
|
||||
++deps_found;
|
||||
if (order_only)
|
||||
d->ignore_mtime = 1;
|
||||
}
|
||||
/* Parse the expanded string. */
|
||||
struct dep *dp = PARSE_FILE_SEQ (&p, struct dep,
|
||||
order_only ? MAP_NUL : MAP_PIPE,
|
||||
add_dir ? dir : NULL, PARSEFS_NONE);
|
||||
*dptr = dp;
|
||||
|
||||
/* Set up for the next word. */
|
||||
nptr += len;
|
||||
for (d = dp; d != NULL; d = d->next)
|
||||
{
|
||||
++deps_found;
|
||||
if (order_only)
|
||||
d->ignore_mtime = 1;
|
||||
dptr = &d->next;
|
||||
}
|
||||
|
||||
/* If we stopped due to an order-only token, note it. */
|
||||
if (*p == '|')
|
||||
{
|
||||
order_only = 1;
|
||||
++p;
|
||||
}
|
||||
}
|
||||
while (*p != '\0');
|
||||
}
|
||||
|
||||
/* If there are more than max_pattern_deps prerequisites (due to
|
||||
@@ -846,9 +863,10 @@ pattern_search (struct file *file, int archive,
|
||||
|
||||
/* We don't want to delete an intermediate file that happened
|
||||
to be a prerequisite of some (other) target. Mark it as
|
||||
precious. */
|
||||
secondary. We don't want it to be precious as that disables
|
||||
DELETE_ON_ERROR etc. */
|
||||
if (f != 0)
|
||||
f->precious = 1;
|
||||
f->secondary = 1;
|
||||
else
|
||||
f = enter_file (imf->name);
|
||||
|
||||
|
||||
32
job.h
32
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
|
||||
@@ -24,7 +24,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* How to set close-on-exec for a file descriptor. */
|
||||
|
||||
#if !defined F_SETFD
|
||||
#if !defined(F_SETFD) || !defined(F_GETFD)
|
||||
# ifdef WINDOWS32
|
||||
# define CLOSE_ON_EXEC(_d) process_noinherit(_d)
|
||||
# else
|
||||
@@ -37,7 +37,11 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
# define CLOSE_ON_EXEC(_d) (void) fcntl ((_d), F_SETFD, FD_CLOEXEC)
|
||||
#endif
|
||||
|
||||
#ifdef OUTPUT_SYNC
|
||||
#ifdef NO_OUTPUT_SYNC
|
||||
# define RECORD_SYNC_MUTEX(m) \
|
||||
O (error, NILF, \
|
||||
_("-O[TYPE] (--output-sync[=TYPE]) is not configured for this build."));
|
||||
#else
|
||||
# ifdef WINDOWS32
|
||||
/* For emulations in w32/compat/posixfcn.c. */
|
||||
# define F_GETFD 1
|
||||
@@ -69,7 +73,6 @@ int same_stream (FILE *f1, FILE *f2);
|
||||
# define RECORD_SYNC_MUTEX(m) record_sync_mutex(m)
|
||||
void record_sync_mutex (const char *str);
|
||||
void prepare_mutex_handle_string (intptr_t hdl);
|
||||
|
||||
# else /* !WINDOWS32 */
|
||||
|
||||
typedef int sync_handle_t; /* file descriptor */
|
||||
@@ -77,11 +80,7 @@ typedef int sync_handle_t; /* file descriptor */
|
||||
# define RECORD_SYNC_MUTEX(m) (void)(m)
|
||||
|
||||
# endif
|
||||
#else /* !OUTPUT_SYNC */
|
||||
#define RECORD_SYNC_MUTEX(m) \
|
||||
error (NILF, \
|
||||
_("-O[TYPE] (--output-sync[=TYPE]) is not configured for this build."));
|
||||
#endif /* OUTPUT_SYNC */
|
||||
#endif /* !NO_OUTPUT_SYNC */
|
||||
|
||||
/* Structure describing a running or dead child process. */
|
||||
|
||||
@@ -100,6 +99,7 @@ struct child
|
||||
char *comname; /* Temporary command file name */
|
||||
int efn; /* Completion event flag number */
|
||||
int cstatus; /* Completion status */
|
||||
int vms_launch_status; /* non-zero if lib$spawn, etc failed */
|
||||
#endif
|
||||
|
||||
unsigned int command_line; /* Index into command_lines. */
|
||||
@@ -109,11 +109,14 @@ struct child
|
||||
unsigned int noerror:1; /* Nonzero if commands contained a '-'. */
|
||||
unsigned int good_stdin:1; /* Nonzero if this child has a good stdin. */
|
||||
unsigned int deleted:1; /* Nonzero if targets have been deleted. */
|
||||
unsigned int recursive:1; /* Nonzero for recursive command ('+' etc.) */
|
||||
unsigned int dontcare:1; /* Saved dontcare flag. */
|
||||
};
|
||||
|
||||
extern struct child *children;
|
||||
|
||||
/* A signal handler for SIGCHLD, if needed. */
|
||||
RETSIGTYPE child_handler (int sig);
|
||||
int is_bourne_compatible_shell(const char *path);
|
||||
void new_job (struct file *file);
|
||||
void reap_children (int block, int err);
|
||||
@@ -121,13 +124,16 @@ void start_waiting_jobs (void);
|
||||
|
||||
char **construct_command_argv (char *line, char **restp, struct file *file,
|
||||
int cmd_flags, char** batch_file);
|
||||
|
||||
#ifdef VMS
|
||||
int child_execute_job (char *argv, struct child *child);
|
||||
#elif defined(__EMX__)
|
||||
int child_execute_job (int stdin_fd, int stdout_fd, char **argv, char **envp);
|
||||
int child_execute_job (struct child *child, char *argv);
|
||||
#else
|
||||
void child_execute_job (int stdin_fd, int stdout_fd, char **argv, char **envp);
|
||||
# define FD_STDIN (fileno (stdin))
|
||||
# define FD_STDOUT (fileno (stdout))
|
||||
# define FD_STDERR (fileno (stderr))
|
||||
int child_execute_job (struct output *out, int good_stdin, char **argv, char **envp);
|
||||
#endif
|
||||
|
||||
#ifdef _AMIGA
|
||||
void exec_command (char **argv) __attribute__ ((noreturn));
|
||||
#elif defined(__EMX__)
|
||||
|
||||
69
load.c
69
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,18 +249,19 @@ unload_file (const char *name)
|
||||
#else
|
||||
|
||||
int
|
||||
load_file (const gmk_floc *flocp, const char **ldname, int noerror)
|
||||
load_file (const floc *flocp, const char **ldname UNUSED, int noerror)
|
||||
{
|
||||
if (! noerror)
|
||||
fatal (flocp, _("The 'load' operation is not supported on this platform."));
|
||||
O (fatal, flocp,
|
||||
_("The 'load' operation is not supported on this platform."));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
unload_file (const char *name)
|
||||
unload_file (const char *name UNUSED)
|
||||
{
|
||||
fatal (NILF, "INTERNAL: Cannot unload when load is not supported!");
|
||||
O (fatal, NILF, "INTERNAL: Cannot unload when load is not supported!");
|
||||
}
|
||||
|
||||
#endif /* MAKE_LOAD */
|
||||
|
||||
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
|
||||
|
||||
4
make.1
4
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
|
||||
@@ -363,7 +363,7 @@ This manual page contributed by Dennis Morse of Stanford University.
|
||||
Further updates contributed by Mike Frysinger. It has been reworked by Roland
|
||||
McGrath. Maintained by Paul Smith.
|
||||
.SH "COPYRIGHT"
|
||||
Copyright \(co 1992-1993, 1996-2013 Free Software Foundation, Inc.
|
||||
Copyright \(co 1992-1993, 1996-2016 Free Software Foundation, Inc.
|
||||
This file is part of
|
||||
.IR "GNU make" .
|
||||
.LP
|
||||
|
||||
@@ -154,11 +154,11 @@
|
||||
<File
|
||||
RelativePath=".\getopt1.c">
|
||||
</File>
|
||||
<!--
|
||||
|
||||
<File
|
||||
RelativePath=".\guile.c">
|
||||
</File>
|
||||
-->
|
||||
|
||||
<File
|
||||
RelativePath=".\hash.c">
|
||||
</File>
|
||||
@@ -171,6 +171,9 @@
|
||||
<File
|
||||
RelativePath=".\job.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\load.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\output.c">
|
||||
</File>
|
||||
@@ -210,6 +213,9 @@
|
||||
<File
|
||||
RelativePath=".\w32\compat\dirent.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\w32\compat\posixfcn.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\w32\subproc\misc.c">
|
||||
<FileConfiguration
|
||||
@@ -228,6 +234,9 @@
|
||||
<File
|
||||
RelativePath=".\w32\pathstuff.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\w32\w32os.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\w32\subproc\sub_proc.c">
|
||||
</File>
|
||||
|
||||
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 load main misc read remake remote-stub rule " + -
|
||||
"signame variable version vmsfunctions vmsify vpath " + -
|
||||
"[.glob]glob [.glob]fnmatch getopt1 getopt strcache"
|
||||
"guile hash implicit job load main misc read remake " + -
|
||||
"remote-stub rule output signame variable version " + -
|
||||
"vmsfunctions vmsify vpath vms_progname vms_exit " + -
|
||||
"vms_export_symbol [.glob]glob [.glob]fnmatch getopt1 " + -
|
||||
"getopt strcache"
|
||||
$!
|
||||
$ copy config.h-vms config.h
|
||||
$ n=0
|
||||
$ open/write optf make.opt
|
||||
@@ -77,18 +85,14 @@ $ loop:
|
||||
$ cfile = f$elem(n," ",filelist)
|
||||
$ if cfile .eqs. " " then goto linkit
|
||||
$ write sys$output "Compiling ''cfile'..."
|
||||
$ call compileit 'cfile' 'p1'
|
||||
$ call compileit 'cfile'
|
||||
$ n = n + 1
|
||||
$ goto loop
|
||||
$ linkit:
|
||||
$ close optf
|
||||
$ if p1 .nes. "" then goto link_using_library
|
||||
$ link/exe=make make.opt/opt'lopt
|
||||
$ goto cleanup
|
||||
$
|
||||
$ link_using_library:
|
||||
$ link/exe=make make.opt/opt,sys$library:vaxcrtl/lib'lopt
|
||||
$
|
||||
$ cleanup:
|
||||
$ if f$trnlnm("SYS").nes."" then $ deassign sys
|
||||
$ if f$trnlnm("OPTF").nes."" then $ close optf
|
||||
@@ -128,17 +132,24 @@ $!-----------------------------------------------------------------------------
|
||||
$!
|
||||
$ compileit : subroutine
|
||||
$ ploc = f$locate("]",p1)
|
||||
$ filnam = p1
|
||||
$ if ploc .lt. f$length(p1) then filnam=f$extract(ploc+1,100,p1)
|
||||
$ write optf "''filnam'"
|
||||
$ cc'ccopt'/include=([],[.glob]) -
|
||||
/define=("allocated_variable_expand_for_file=alloc_var_expand_for_file","unlink=remove","HAVE_CONFIG_H","VMS") -
|
||||
$! filnam = p1
|
||||
$ if ploc .lt. f$length(p1)
|
||||
$ then
|
||||
$ objdir = f$extract(0, ploc+1, p1)
|
||||
$ write optf p1
|
||||
$ else
|
||||
$ objdir := []
|
||||
$ write optf objdir+p1
|
||||
$ endif
|
||||
$ cc'ccopt'/nested=none/include=([],[.glob])/obj='objdir' -
|
||||
/define=("allocated_variable_expand_for_file=alloc_var_expand_for_file",-
|
||||
"unlink=remove","HAVE_CONFIG_H","VMS") -
|
||||
'p1'
|
||||
$ exit
|
||||
$ endsubroutine : compileit
|
||||
$!
|
||||
$!-----------------------------------------------------------------------------
|
||||
$!Copyright (C) 1996-2013 Free Software Foundation, Inc.
|
||||
$!Copyright (C) 1996-2016 Free Software Foundation, Inc.
|
||||
$!This file is part of GNU Make.
|
||||
$!
|
||||
$!GNU Make is free software; you can redistribute it and/or modify it under
|
||||
|
||||
101
makefile.vms
101
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
|
||||
@@ -32,9 +32,12 @@ CP = copy
|
||||
#
|
||||
|
||||
ifeq ($(CC),cc)
|
||||
CFLAGS = $(defines) /include=([],[.glob])/prefix=(all,except=(glob,globfree))/standard=relaxed/warn=(disable=questcompare)
|
||||
cinclude = /nested=none/include=([],[.glob])
|
||||
cprefix = /prefix=(all,except=(glob,globfree))
|
||||
cwarn = /standard=relaxed/warn=(disable=questcompare)
|
||||
CFLAGS = $(defines) $(cinclude)$(cprefix)$(cwarn)
|
||||
else
|
||||
CFLAGS = $(defines) /include=([],[.glob])
|
||||
CFLAGS = $(defines) $(cinclude)
|
||||
endif
|
||||
#LDFLAGS = /deb
|
||||
LDFLAGS =
|
||||
@@ -88,18 +91,19 @@ mandir = []
|
||||
# Number to put on the man page filename.
|
||||
manext = 1
|
||||
|
||||
#guile = ,guile.obj
|
||||
guile = ,guile.obj
|
||||
|
||||
objs = commands.obj,job.obj,output.obj,dir.obj,file.obj,misc.obj,hash.obj,\
|
||||
load.obj,main.obj,read.obj,remake.obj,rule.obj,implicit.obj,\
|
||||
default.obj,variable.obj,expand.obj,function.obj,strcache.obj,\
|
||||
vpath.obj,version.obj\
|
||||
$(ARCHIVES)$(ALLOCA)$(extras)$(getopt)$(glob)$(guile)
|
||||
vpath.obj,version.obj,vms_progname.obj,vms_exit.obj,\
|
||||
vms_export_symbol.obj$(guile)$(ARCHIVES)$(extras)$(getopt)$(glob)
|
||||
|
||||
srcs = commands.c job.c output.c dir.c file.c misc.c guile.c hash.c \
|
||||
load.c main.c read.c remake.c rule.c implicit.c \
|
||||
default.c variable.c expand.c function.c strcache.c \
|
||||
vpath.c version.c vmsfunctions.c vmsify.c $(ARCHIVES_SRC) $(ALLOCASRC) \
|
||||
vpath.c version.c vmsfunctions.c vmsify.c vms_progname.c vms_exit.c \
|
||||
vms_export_symbol.c $(ARCHIVES_SRC) $(ALLOCASRC) \
|
||||
commands.h dep.h filedef.h job.h output.h makeint.h rule.h variable.h
|
||||
|
||||
|
||||
@@ -118,40 +122,59 @@ clean:
|
||||
-$(RM) make.exe;,*.obj;
|
||||
-$(RM) [.glob]*.obj;
|
||||
|
||||
# Automatically generated dependencies.
|
||||
# makeint.h: config.h gnumake.h gettext.h
|
||||
# filedef.h: hash.h
|
||||
ar.obj: ar.c makeint.h filedef.h dep.h [.glob]fnmatch.h
|
||||
arscan.obj: arscan.c makeint.h
|
||||
commands.obj: commands.c makeint.h dep.h commands.h filedef.h variable.h job.h
|
||||
default.obj: default.c makeint.h rule.h dep.h job.h filedef.h commands.h variable.h
|
||||
dir.obj: dir.c makeint.h hash.h [.glob]glob.h
|
||||
expand.obj: expand.c makeint.h commands.h filedef.h job.h rule.h variable.h
|
||||
file.obj: file.c makeint.h commands.h dep.h filedef.h variable.h job.h debug.h
|
||||
function.obj: function.c makeint.h variable.h dep.h commands.h filedef.h debug.h job.h
|
||||
getopt.obj: getopt.c getopt.h config.h gettext.h
|
||||
getopt1.obj: getopt1.c getopt.h config.h
|
||||
guile.obj: guile.c makeint.h debug.h dep.h gmk-default.h
|
||||
hash.obj: hash.c makeint.h hash.h
|
||||
implicit.obj: implicit.c makeint.h rule.h dep.h filedef.h debug.h variable.h job.h commands.h
|
||||
job.obj: job.c vmsjobs.c makeint.h commands.h job.h filedef.h variable.h debug.h
|
||||
output.obj: output.c vmsjobs.c makeint.h output.h filedef.h debug.h
|
||||
load.obj: load.c makeint.h debug.h filedef.h variable.h
|
||||
main.obj: main.c makeint.h commands.h dep.h filedef.h variable.h job.h rule.h debug.h getopt.h
|
||||
misc.obj: misc.c makeint.h dep.h debug.h
|
||||
read.obj: read.c makeint.h commands.h dep.h filedef.h variable.h [.glob]glob.h debug.h rule.h job.h
|
||||
remake.obj: remake.c makeint.h commands.h job.h dep.h filedef.h variable.h debug.h
|
||||
remote-stub.obj: remote-stub.c makeint.h filedef.h job.h commands.h
|
||||
rule.obj: rule.c makeint.h commands.h dep.h filedef.h variable.h rule.h job.h
|
||||
signame.obj: signame.c makeint.h
|
||||
strcache.obj: strcache.c makeint.h hash.h
|
||||
variable.obj: variable.c makeint.h commands.h variable.h dep.h filedef.h job.h rule.h
|
||||
ar.obj: ar.c makeint.h config.h gnumake.h gettext.h filedef.h hash.h dep.h \
|
||||
[.glob]fnmatch.h
|
||||
arscan.obj: arscan.c makeint.h config.h gnumake.h gettext.h
|
||||
commands.obj: commands.c makeint.h config.h gnumake.h gettext.h filedef.h \
|
||||
hash.h dep.h variable.h job.h output.h commands.h
|
||||
default.obj: default.c makeint.h config.h gnumake.h gettext.h filedef.h \
|
||||
hash.h variable.h rule.h dep.h job.h output.h commands.h
|
||||
dir.obj: dir.c makeint.h config.h gnumake.h gettext.h hash.h filedef.h \
|
||||
dep.h [.glob]glob.h
|
||||
expand.obj: expand.c makeint.h config.h gnumake.h gettext.h filedef.h \
|
||||
hash.h job.h output.h commands.h variable.h rule.h
|
||||
file.obj: file.c makeint.h config.h gnumake.h gettext.h filedef.h hash.h \
|
||||
dep.h job.h output.h commands.h variable.h debug.h
|
||||
[.glob]fnmatch.obj: [.glob]fnmatch.c config.h [.glob]fnmatch.h
|
||||
function.obj: function.c makeint.h config.h gnumake.h gettext.h filedef.h \
|
||||
hash.h variable.h dep.h job.h output.h commands.h debug.h
|
||||
getopt.obj: getopt.c config.h gettext.h getopt.h
|
||||
getopt1.obj: getopt1.c config.h getopt.h
|
||||
[.glob]glob.obj: [.glob]glob.c config.h [.glob]fnmatch.h [.glob]glob.h
|
||||
guile.obj: guile.c makeint.h config.h gnumake.h gettext.h
|
||||
hash.obj: hash.c makeint.h config.h gnumake.h gettext.h hash.h
|
||||
implicit.obj: implicit.c makeint.h config.h gnumake.h gettext.h filedef.h \
|
||||
hash.h rule.h dep.h debug.h variable.h job.h output.h commands.h
|
||||
job.obj: job.c makeint.h config.h gnumake.h gettext.h job.h output.h debug.h \
|
||||
filedef.h hash.h commands.h variable.h debug.h vmsjobs.c
|
||||
load.obj: load.c makeint.h config.h gnumake.h gettext.h
|
||||
main.obj: main.c makeint.h config.h gnumake.h gettext.h filedef.h hash.h \
|
||||
dep.h variable.h job.h output.h commands.h rule.h debug.h getopt.h
|
||||
misc.obj: misc.c makeint.h config.h gnumake.h gettext.h filedef.h hash.h \
|
||||
dep.h debug.h
|
||||
output.obj: output.c makeint.h config.h gnumake.h gettext.h job.h output.h
|
||||
read.obj: read.c makeint.h config.h gnumake.h gettext.h [.glob]glob.h \
|
||||
filedef.h hash.h dep.h job.h output.h commands.h variable.h rule.h \
|
||||
debug.h
|
||||
remake.obj: remake.c makeint.h config.h gnumake.h gettext.h filedef.h \
|
||||
hash.h job.h output.h commands.h dep.h variable.h debug.h
|
||||
remote-stub.obj: remote-stub.c makeint.h config.h gnumake.h gettext.h \
|
||||
filedef.h hash.h job.h output.h commands.h
|
||||
rule.obj: rule.c makeint.h config.h gnumake.h gettext.h filedef.h hash.h \
|
||||
dep.h job.h output.h commands.h variable.h rule.h
|
||||
signame.obj: signame.c makeint.h config.h gnumake.h gettext.h
|
||||
strcache.obj: strcache.c makeint.h config.h gnumake.h gettext.h hash.h
|
||||
variable.obj: variable.c makeint.h config.h gnumake.h gettext.h filedef.h \
|
||||
hash.h dep.h job.h output.h commands.h variable.h rule.h
|
||||
version.obj: version.c config.h
|
||||
vmsfunctions.obj: vmsfunctions.c makeint.h vmsdir.h debug.h job.h
|
||||
vmsfunctions.obj: vmsfunctions.c makeint.h config.h gnumake.h gettext.h \
|
||||
debug.h job.h output.h vmsdir.h
|
||||
vmsify.obj: vmsify.c
|
||||
vpath.obj: vpath.c makeint.h filedef.h variable.h
|
||||
[.glob]fnmatch.obj: [.glob]fnmatch.c [.glob]fnmatch.h config.h
|
||||
[.glob]glob.obj: [.glob]glob.c [.glob]glob.h [.glob]fnmatch.h config.h
|
||||
vpath.obj: vpath.c makeint.h config.h gnumake.h gettext.h filedef.h hash.h \
|
||||
variable.h
|
||||
vms_progname.obj: vms_progname.c
|
||||
vms_exit.obj: vms_exit.c
|
||||
vms_export_symbol.obj: vms_export_symbol.c
|
||||
|
||||
config.h: config.h-vms
|
||||
$(CP) $< $@
|
||||
|
||||
248
makeint.h
248
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
|
||||
@@ -204,6 +210,13 @@ unsigned int get_path_max (void);
|
||||
# include <perror.h>
|
||||
/* Needed to use alloca on VMS. */
|
||||
# include <builtins.h>
|
||||
|
||||
extern int vms_use_mcr_command;
|
||||
extern int vms_always_use_cmd_file;
|
||||
extern int vms_gnv_shell;
|
||||
extern int vms_comma_separator;
|
||||
extern int vms_legacy_behavior;
|
||||
extern int vms_unix_simulation;
|
||||
#endif
|
||||
|
||||
#ifndef __attribute__
|
||||
@@ -328,21 +341,6 @@ char *strsignal (int signum);
|
||||
#define N_(msgid) gettext_noop (msgid)
|
||||
#define S_(msg1,msg2,num) ngettext (msg1,msg2,num)
|
||||
|
||||
/* Handle other OSs.
|
||||
To overcome an issue parsing paths in a DOS/Windows environment when
|
||||
built in a unix based environment, override the PATH_SEPARATOR_CHAR
|
||||
definition unless being built for Cygwin. */
|
||||
#if defined(HAVE_DOS_PATHS) && !defined(__CYGWIN__)
|
||||
# undef PATH_SEPARATOR_CHAR
|
||||
# define PATH_SEPARATOR_CHAR ';'
|
||||
#elif !defined(PATH_SEPARATOR_CHAR)
|
||||
# if defined (VMS)
|
||||
# define PATH_SEPARATOR_CHAR ','
|
||||
# else
|
||||
# define PATH_SEPARATOR_CHAR ':'
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* This is needed for getcwd() and chdir(), on some W32 systems. */
|
||||
#if defined(HAVE_DIRECT_H)
|
||||
# include <direct.h>
|
||||
@@ -353,8 +351,8 @@ char *strsignal (int signum);
|
||||
# include <malloc.h>
|
||||
# define pipe(_p) _pipe((_p), 512, O_BINARY)
|
||||
# define kill(_pid,_sig) w32_kill((_pid),(_sig))
|
||||
/* MSVC doesn't have ftruncate. */
|
||||
# ifdef _MSC_VER
|
||||
/* MSVC and Watcom C don't have ftruncate. */
|
||||
# if defined(_MSC_VER) || defined(__WATCOMC__)
|
||||
# define ftruncate(_fd,_len) _chsize(_fd,_len)
|
||||
# endif
|
||||
/* MinGW64 doesn't have _S_ISDIR. */
|
||||
@@ -378,7 +376,7 @@ extern int unixy_shell;
|
||||
# endif
|
||||
|
||||
/* Include only the minimal stuff from windows.h. */
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
#endif /* WINDOWS32 */
|
||||
|
||||
#define ANY_SET(_v,_m) (((_v)&(_m)) != 0)
|
||||
@@ -386,7 +384,7 @@ extern int unixy_shell;
|
||||
|
||||
#define MAP_NUL 0x0001
|
||||
#define MAP_BLANK 0x0002
|
||||
#define MAP_SPACE 0x0004
|
||||
#define MAP_NEWLINE 0x0004
|
||||
#define MAP_COMMENT 0x0008
|
||||
#define MAP_SEMI 0x0010
|
||||
#define MAP_EQUALS 0x0020
|
||||
@@ -396,10 +394,12 @@ extern int unixy_shell;
|
||||
#define MAP_DOT 0x0200
|
||||
#define MAP_COMMA 0x0400
|
||||
|
||||
/* These are the valid characters for a user-defined function. */
|
||||
#define MAP_USERFUNC 0x2000
|
||||
/* This means not only a '$', but skip the variable reference. */
|
||||
#define MAP_VARIABLE 0x4000
|
||||
/* The set of characters which are path separators is OS-specific. */
|
||||
#define MAP_PATHSEP 0x8000
|
||||
/* The set of characters which are directory separators is OS-specific. */
|
||||
#define MAP_DIRSEP 0x8000
|
||||
|
||||
#ifdef VMS
|
||||
# define MAP_VMSCOMMA MAP_COMMA
|
||||
@@ -407,7 +407,40 @@ extern int unixy_shell;
|
||||
# define MAP_VMSCOMMA 0x0000
|
||||
#endif
|
||||
|
||||
#define STOP_SET(_v,_m) ANY_SET (stopchar_map[(int)(_v)],(_m))
|
||||
#define MAP_SPACE (MAP_BLANK|MAP_NEWLINE)
|
||||
|
||||
/* Handle other OSs.
|
||||
To overcome an issue parsing paths in a DOS/Windows environment when
|
||||
built in a unix based environment, override the PATH_SEPARATOR_CHAR
|
||||
definition unless being built for Cygwin. */
|
||||
#if defined(HAVE_DOS_PATHS) && !defined(__CYGWIN__)
|
||||
# undef PATH_SEPARATOR_CHAR
|
||||
# define PATH_SEPARATOR_CHAR ';'
|
||||
# define MAP_PATHSEP MAP_SEMI
|
||||
#elif !defined(PATH_SEPARATOR_CHAR)
|
||||
# if defined (VMS)
|
||||
# define PATH_SEPARATOR_CHAR (vms_comma_separator ? ',' : ':')
|
||||
# define MAP_PATHSEP (vms_comma_separator ? MAP_COMMA : MAP_SEMI)
|
||||
# else
|
||||
# define PATH_SEPARATOR_CHAR ':'
|
||||
# define MAP_PATHSEP MAP_COLON
|
||||
# endif
|
||||
#elif PATH_SEPARATOR_CHAR == ':'
|
||||
# define MAP_PATHSEP MAP_COLON
|
||||
#elif PATH_SEPARATOR_CHAR == ';'
|
||||
# define MAP_PATHSEP MAP_SEMI
|
||||
#elif PATH_SEPARATOR_CHAR == ','
|
||||
# define MAP_PATHSEP MAP_COMMA
|
||||
#else
|
||||
# error "Unknown PATH_SEPARATOR_CHAR"
|
||||
#endif
|
||||
|
||||
#define STOP_SET(_v,_m) ANY_SET(stopchar_map[(unsigned char)(_v)],(_m))
|
||||
|
||||
#define ISBLANK(c) STOP_SET((c),MAP_BLANK)
|
||||
#define ISSPACE(c) STOP_SET((c),MAP_SPACE)
|
||||
#define NEXT_TOKEN(s) while (ISSPACE (*(s))) ++(s)
|
||||
#define END_OF_TOKEN(s) while (! STOP_SET (*(s), MAP_SPACE|MAP_NUL)) ++(s)
|
||||
|
||||
#if defined(HAVE_SYS_RESOURCE_H) && defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT)
|
||||
# define SET_STACK_SIZE
|
||||
@@ -417,19 +450,56 @@ extern int unixy_shell;
|
||||
extern struct rlimit stack_limit;
|
||||
#endif
|
||||
|
||||
#define NILF ((gmk_floc *)0)
|
||||
#include <glob.h>
|
||||
|
||||
#define CSTRLEN(_s) (sizeof (_s)-1)
|
||||
#define NILF ((floc *)0)
|
||||
|
||||
#define CSTRLEN(_s) (sizeof (_s)-1)
|
||||
#define STRING_SIZE_TUPLE(_s) (_s), CSTRLEN(_s)
|
||||
|
||||
/* The number of bytes needed to represent the largest integer as a string. */
|
||||
#define INTSTR_LENGTH CSTRLEN ("18446744073709551616")
|
||||
|
||||
#define DEFAULT_TTYNAME "true"
|
||||
#ifdef HAVE_TTYNAME
|
||||
# define TTYNAME(_f) ttyname (_f)
|
||||
#else
|
||||
# define TTYNAME(_f) DEFAULT_TTYNAME
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Specify the location of elements read from makefiles. */
|
||||
typedef struct
|
||||
{
|
||||
const char *filenm;
|
||||
unsigned long lineno;
|
||||
unsigned long offset;
|
||||
} floc;
|
||||
|
||||
const char *concat (unsigned int, ...);
|
||||
void message (int prefix, const char *fmt, ...)
|
||||
__attribute__ ((__format__ (__printf__, 2, 3)));
|
||||
void error (const gmk_floc *flocp, const char *fmt, ...)
|
||||
__attribute__ ((__format__ (__printf__, 2, 3)));
|
||||
void fatal (const gmk_floc *flocp, const char *fmt, ...)
|
||||
__attribute__ ((noreturn, __format__ (__printf__, 2, 3)));
|
||||
void message (int prefix, size_t length, const char *fmt, ...)
|
||||
__attribute__ ((__format__ (__printf__, 3, 4)));
|
||||
void error (const floc *flocp, size_t length, const char *fmt, ...)
|
||||
__attribute__ ((__format__ (__printf__, 3, 4)));
|
||||
void fatal (const floc *flocp, size_t length, const char *fmt, ...)
|
||||
__attribute__ ((noreturn, __format__ (__printf__, 3, 4)));
|
||||
|
||||
#define O(_t,_a,_f) _t((_a), 0, (_f))
|
||||
#define OS(_t,_a,_f,_s) _t((_a), strlen (_s), (_f), (_s))
|
||||
#define OSS(_t,_a,_f,_s1,_s2) _t((_a), strlen (_s1) + strlen (_s2), \
|
||||
(_f), (_s1), (_s2))
|
||||
#define OSSS(_t,_a,_f,_s1,_s2,_s3) _t((_a), strlen (_s1) + strlen (_s2) + strlen (_s3), \
|
||||
(_f), (_s1), (_s2), (_s3))
|
||||
#define ON(_t,_a,_f,_n) _t((_a), INTSTR_LENGTH, (_f), (_n))
|
||||
#define ONN(_t,_a,_f,_n1,_n2) _t((_a), INTSTR_LENGTH*2, (_f), (_n1), (_n2))
|
||||
|
||||
#define OSN(_t,_a,_f,_s,_n) _t((_a), strlen (_s) + INTSTR_LENGTH, \
|
||||
(_f), (_s), (_n))
|
||||
#define ONS(_t,_a,_f,_n,_s) _t((_a), INTSTR_LENGTH + strlen (_s), \
|
||||
(_f), (_n), (_s))
|
||||
|
||||
#define OUT_OF_MEM() O (fatal, NILF, _("virtual memory exhausted"))
|
||||
|
||||
void die (int) __attribute__ ((noreturn));
|
||||
void pfatal_with_name (const char *) __attribute__ ((noreturn));
|
||||
@@ -459,7 +529,8 @@ time_t ar_member_date (const char *);
|
||||
typedef long int (*ar_member_func_t) (int desc, const char *mem, int truncated,
|
||||
long int hdrpos, long int datapos,
|
||||
long int size, long int date, int uid,
|
||||
int gid, int mode, const void *arg);
|
||||
int gid, unsigned int mode,
|
||||
const void *arg);
|
||||
|
||||
long int ar_scan (const char *archive, ar_member_func_t function, const void *arg);
|
||||
int ar_name_equal (const char *name, const char *mem, int truncated);
|
||||
@@ -473,6 +544,8 @@ int file_exists_p (const char *);
|
||||
int file_impossible_p (const char *);
|
||||
void file_impossible (const char *);
|
||||
const char *dir_name (const char *);
|
||||
void print_dir_data_base (void);
|
||||
void dir_setup_glob (glob_t *);
|
||||
void hash_init_directories (void);
|
||||
|
||||
void define_default_variables (void);
|
||||
@@ -495,22 +568,21 @@ void child_access (void);
|
||||
|
||||
char *strip_whitespace (const char **begpp, const char **endpp);
|
||||
|
||||
void show_goal_error (void);
|
||||
|
||||
/* String caching */
|
||||
void strcache_init (void);
|
||||
void strcache_print_stats (const char *prefix);
|
||||
int strcache_iscached (const char *str);
|
||||
const char *strcache_add (const char *str);
|
||||
const char *strcache_add_len (const char *str, unsigned int len);
|
||||
int strcache_setbufsize (unsigned int size);
|
||||
|
||||
/* Guile support */
|
||||
#ifdef HAVE_GUILE
|
||||
int guile_gmake_setup (const gmk_floc *flocp);
|
||||
#endif
|
||||
int guile_gmake_setup (const floc *flocp);
|
||||
|
||||
/* Loadable object support. Sets to the strcached name of the loaded file. */
|
||||
typedef int (*load_func_t)(const gmk_floc *flocp);
|
||||
int load_file (const gmk_floc *flocp, const char **filename, int noerror);
|
||||
typedef int (*load_func_t)(const floc *flocp);
|
||||
int load_file (const floc *flocp, const char **filename, int noerror);
|
||||
void unload_file (const char *name);
|
||||
|
||||
/* We omit these declarations on non-POSIX systems which define _POSIX_VERSION,
|
||||
@@ -523,16 +595,16 @@ long int atol ();
|
||||
long int lseek ();
|
||||
# endif
|
||||
|
||||
#endif /* Not GNU C library or POSIX. */
|
||||
|
||||
#ifdef HAVE_GETCWD
|
||||
# if !defined(VMS) && !defined(__DECC)
|
||||
# ifdef HAVE_GETCWD
|
||||
# if !defined(VMS) && !defined(__DECC)
|
||||
char *getcwd ();
|
||||
# endif
|
||||
#else
|
||||
# endif
|
||||
# else
|
||||
char *getwd ();
|
||||
# define getcwd(buf, len) getwd (buf)
|
||||
#endif
|
||||
# define getcwd(buf, len) getwd (buf)
|
||||
# endif
|
||||
|
||||
#endif /* Not GNU C library or POSIX. */
|
||||
|
||||
#if !HAVE_STRCASECMP
|
||||
# if HAVE_STRICMP
|
||||
@@ -556,20 +628,17 @@ int strncasecmp (const char *s1, const char *s2, int n);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef POSIX
|
||||
# define OUTPUT_SYNC
|
||||
#endif
|
||||
|
||||
#define OUTPUT_SYNC_NONE 0
|
||||
#define OUTPUT_SYNC_LINE 1
|
||||
#define OUTPUT_SYNC_TARGET 2
|
||||
#define OUTPUT_SYNC_RECURSE 3
|
||||
|
||||
extern const gmk_floc *reading_file;
|
||||
extern const gmk_floc **expanding_var;
|
||||
|
||||
/* Non-GNU systems may not declare this in unistd.h. */
|
||||
extern char **environ;
|
||||
|
||||
extern const floc *reading_file;
|
||||
extern const floc **expanding_var;
|
||||
|
||||
extern unsigned short stopchar_map[];
|
||||
|
||||
extern int just_print_flag, silent_flag, ignore_errors_flag, keep_going_flag;
|
||||
@@ -580,6 +649,8 @@ extern int warn_undefined_variables_flag, trace_flag, posix_pedantic;
|
||||
extern int not_parallel, second_expansion, clock_skew_detected;
|
||||
extern int rebuilding_makefiles, one_shell, output_sync, verify_flag;
|
||||
|
||||
extern const char *default_shell;
|
||||
|
||||
/* can we run commands via 'sh -c xxx' or must we use batch files? */
|
||||
extern int batch_mode_shell;
|
||||
|
||||
@@ -589,15 +660,59 @@ extern int batch_mode_shell;
|
||||
extern char cmd_prefix;
|
||||
|
||||
extern unsigned int job_slots;
|
||||
extern int job_fds[2];
|
||||
extern int job_rfd;
|
||||
#ifndef NO_FLOAT
|
||||
extern double max_load_average;
|
||||
#else
|
||||
extern int max_load_average;
|
||||
#endif
|
||||
|
||||
#ifdef WINDOWS32
|
||||
extern char *program;
|
||||
#else
|
||||
extern const char *program;
|
||||
#endif
|
||||
|
||||
#ifdef VMS
|
||||
const char *vms_command (const char *argv0);
|
||||
const char *vms_progname (const char *argv0);
|
||||
|
||||
void vms_exit (int);
|
||||
# define _exit(foo) vms_exit(foo)
|
||||
# define exit(foo) vms_exit(foo)
|
||||
|
||||
extern char *program_name;
|
||||
|
||||
void
|
||||
set_program_name (const char *arv0);
|
||||
|
||||
int
|
||||
need_vms_symbol (void);
|
||||
|
||||
int
|
||||
create_foreign_command (const char *command, const char *image);
|
||||
|
||||
int
|
||||
vms_export_dcl_symbol (const char *name, const char *value);
|
||||
|
||||
int
|
||||
vms_putenv_symbol (const char *string);
|
||||
|
||||
void
|
||||
vms_restore_symbol (const char *string);
|
||||
|
||||
#endif
|
||||
|
||||
void remote_setup (void);
|
||||
void remote_cleanup (void);
|
||||
int start_remote_job_p (int);
|
||||
int start_remote_job (char **, char **, int, int *, int *, int *);
|
||||
int remote_status (int *, int *, int *, int);
|
||||
void block_remote_children (void);
|
||||
void unblock_remote_children (void);
|
||||
int remote_kill (int id, int sig);
|
||||
void print_variable_data_base (void);
|
||||
void print_vpath_data_base (void);
|
||||
|
||||
extern char *starting_directory;
|
||||
extern unsigned int makelevel;
|
||||
extern char *version_string, *remote_description, *make_host;
|
||||
@@ -614,15 +729,10 @@ extern int handling_fatal_signal;
|
||||
#define MAX(_a,_b) ((_a)>(_b)?(_a):(_b))
|
||||
#endif
|
||||
|
||||
#ifdef VMS
|
||||
# define MAKE_SUCCESS 1
|
||||
# define MAKE_TROUBLE 2
|
||||
# define MAKE_FAILURE 3
|
||||
#else
|
||||
# define MAKE_SUCCESS 0
|
||||
# define MAKE_TROUBLE 1
|
||||
# define MAKE_FAILURE 2
|
||||
#endif
|
||||
|
||||
#define MAKE_SUCCESS 0
|
||||
#define MAKE_TROUBLE 1
|
||||
#define MAKE_FAILURE 2
|
||||
|
||||
/* Set up heap debugging library dmalloc. */
|
||||
|
||||
|
||||
43
misc.c
43
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"
|
||||
|
||||
@@ -90,12 +91,13 @@ collapse_continuations (char *line)
|
||||
{
|
||||
/* Backslash/newline handling:
|
||||
In traditional GNU make all trailing whitespace, consecutive
|
||||
backslash/newlines, and any leading whitespace on the next line
|
||||
is reduced to a single space.
|
||||
backslash/newlines, and any leading non-newline whitespace on the
|
||||
next line is reduced to a single space.
|
||||
In POSIX, each backslash/newline and is replaced by a space. */
|
||||
in = next_token (in);
|
||||
while (ISBLANK (*in))
|
||||
++in;
|
||||
if (! posix_pedantic)
|
||||
while (out > line && isblank ((unsigned char)out[-1]))
|
||||
while (out > line && ISBLANK (out[-1]))
|
||||
--out;
|
||||
*out++ = ' ';
|
||||
}
|
||||
@@ -218,7 +220,7 @@ xmalloc (unsigned int size)
|
||||
/* Make sure we don't allocate 0, for pre-ISO implementations. */
|
||||
void *result = malloc (size ? size : 1);
|
||||
if (result == 0)
|
||||
fatal (NILF, _("virtual memory exhausted"));
|
||||
OUT_OF_MEM();
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -229,7 +231,7 @@ xcalloc (unsigned int size)
|
||||
/* Make sure we don't allocate 0, for pre-ISO implementations. */
|
||||
void *result = calloc (size ? size : 1, 1);
|
||||
if (result == 0)
|
||||
fatal (NILF, _("virtual memory exhausted"));
|
||||
OUT_OF_MEM();
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -244,7 +246,7 @@ xrealloc (void *ptr, unsigned int size)
|
||||
size = 1;
|
||||
result = ptr ? realloc (ptr, size) : malloc (size);
|
||||
if (result == 0)
|
||||
fatal (NILF, _("virtual memory exhausted"));
|
||||
OUT_OF_MEM();
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -261,7 +263,7 @@ xstrdup (const char *ptr)
|
||||
#endif
|
||||
|
||||
if (result == 0)
|
||||
fatal (NILF, _("virtual memory exhausted"));
|
||||
OUT_OF_MEM();
|
||||
|
||||
#ifdef HAVE_STRDUP
|
||||
return result;
|
||||
@@ -280,7 +282,7 @@ xstrndup (const char *str, unsigned int length)
|
||||
#ifdef HAVE_STRNDUP
|
||||
result = strndup (str, length);
|
||||
if (result == 0)
|
||||
fatal (NILF, _("virtual memory exhausted"));
|
||||
OUT_OF_MEM();
|
||||
#else
|
||||
result = xmalloc (length + 1);
|
||||
if (length > 0)
|
||||
@@ -313,8 +315,7 @@ lindex (const char *s, const char *limit, int c)
|
||||
char *
|
||||
end_of_token (const char *s)
|
||||
{
|
||||
while (! STOP_SET (*s, MAP_BLANK|MAP_NUL))
|
||||
++s;
|
||||
END_OF_TOKEN (s);
|
||||
return (char *)s;
|
||||
}
|
||||
|
||||
@@ -323,8 +324,7 @@ end_of_token (const char *s)
|
||||
char *
|
||||
next_token (const char *s)
|
||||
{
|
||||
while (isblank ((unsigned char)*s))
|
||||
++s;
|
||||
NEXT_TOKEN (s);
|
||||
return (char *)s;
|
||||
}
|
||||
|
||||
@@ -376,19 +376,6 @@ copy_dep_chain (const struct dep *d)
|
||||
return firstnew;
|
||||
}
|
||||
|
||||
/* Free a chain of 'struct dep'. */
|
||||
|
||||
void
|
||||
free_dep_chain (struct dep *d)
|
||||
{
|
||||
while (d != 0)
|
||||
{
|
||||
struct dep *df = d;
|
||||
d = d->next;
|
||||
free_dep (df);
|
||||
}
|
||||
}
|
||||
|
||||
/* Free a chain of struct nameseq.
|
||||
For struct dep chains use free_dep_chain. */
|
||||
|
||||
@@ -399,7 +386,7 @@ free_ns_chain (struct nameseq *ns)
|
||||
{
|
||||
struct nameseq *t = ns;
|
||||
ns = ns->next;
|
||||
free (t);
|
||||
free_ns (t);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
84
os.h
Normal file
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
|
||||
228
output.c
228
output.c
@@ -1,5 +1,5 @@
|
||||
/* Output to stdout / stderr for GNU make
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
Copyright (C) 2013-2016 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
@@ -22,7 +22,10 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FCNTL_H
|
||||
# include <fcntl.h>
|
||||
@@ -30,32 +33,23 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
# include <sys/file.h>
|
||||
#endif
|
||||
|
||||
#ifdef WINDOWS32
|
||||
# include <windows.h>
|
||||
# include <io.h>
|
||||
# include "sub_proc.h"
|
||||
#endif /* WINDOWS32 */
|
||||
|
||||
struct output *output_context = NULL;
|
||||
static unsigned int stdio_traced = 0;
|
||||
unsigned int stdio_traced = 0;
|
||||
|
||||
#define OUTPUT_NONE (-1)
|
||||
|
||||
#define OUTPUT_ISSET(_out) ((_out)->out >= 0 || (_out)->err >= 0)
|
||||
|
||||
/* I really want to move to gnulib. However, this is a big undertaking
|
||||
especially for non-UNIX platforms: how to get bootstrapping to work, etc.
|
||||
I don't want to take the time to do it right now. Use a hack to get a
|
||||
useful version of vsnprintf() for Windows. */
|
||||
#ifdef _MSC_VER
|
||||
#define va_copy(_d, _s) ((_d) = (_s))
|
||||
#define snprintf msc_vsnprintf
|
||||
static int
|
||||
msc_vsnprintf (char *str, size_t size, const char *format, va_list ap)
|
||||
{
|
||||
int len = -1;
|
||||
|
||||
if (size > 0)
|
||||
len = _vsnprintf_s (str, size, _TRUNCATE, format, ap);
|
||||
if (len == -1)
|
||||
len = _vscprintf (format, ap);
|
||||
|
||||
return len;
|
||||
}
|
||||
#ifdef HAVE_FCNTL_H
|
||||
# define STREAM_OK(_s) ((fcntl (fileno (_s), F_GETFD) != -1) || (errno != EBADF))
|
||||
#else
|
||||
# define STREAM_OK(_s) 1
|
||||
#endif
|
||||
|
||||
/* Write a string to the current STDOUT or STDERR. */
|
||||
@@ -78,10 +72,8 @@ _outputs (struct output *out, int is_err, const char *msg)
|
||||
while (1)
|
||||
{
|
||||
EINTRLOOP (r, write (fd, msg, len));
|
||||
if (r == len)
|
||||
if (r == len || r <= 0)
|
||||
break;
|
||||
if (r <= 0)
|
||||
return;
|
||||
len -= r;
|
||||
msg += r;
|
||||
}
|
||||
@@ -92,7 +84,7 @@ _outputs (struct output *out, int is_err, const char *msg)
|
||||
left (according to ENTERING) the current directory. */
|
||||
|
||||
static int
|
||||
log_working_directory (struct output *out, int entering)
|
||||
log_working_directory (int entering)
|
||||
{
|
||||
static char *buf = NULL;
|
||||
static unsigned int len = 0;
|
||||
@@ -101,7 +93,7 @@ log_working_directory (struct output *out, int entering)
|
||||
char *p;
|
||||
|
||||
/* Get enough space for the longest possible output. */
|
||||
need = strlen (program) + INTEGER_LENGTH + 2 + 1;
|
||||
need = strlen (program) + INTSTR_LENGTH + 2 + 1;
|
||||
if (starting_directory)
|
||||
need += strlen (starting_directory);
|
||||
|
||||
@@ -154,7 +146,7 @@ log_working_directory (struct output *out, int entering)
|
||||
else
|
||||
sprintf (p, fmt, program, makelevel, starting_directory);
|
||||
|
||||
_outputs (out, 0, buf);
|
||||
_outputs (NULL, 0, buf);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -173,18 +165,16 @@ set_append_mode (int fd)
|
||||
}
|
||||
|
||||
|
||||
#ifdef OUTPUT_SYNC
|
||||
#ifndef NO_OUTPUT_SYNC
|
||||
|
||||
/* Semaphore for use in -j mode with output_sync. */
|
||||
static sync_handle_t sync_handle = -1;
|
||||
|
||||
#define STREAM_OK(_s) ((fcntl (fileno (_s), F_GETFD) != -1) || (errno != EBADF))
|
||||
|
||||
#define FD_NOT_EMPTY(_f) ((_f) != OUTPUT_NONE && lseek ((_f), 0, SEEK_END) > 0)
|
||||
|
||||
/* Set up the sync handle. Disables output_sync on error. */
|
||||
static int
|
||||
sync_init ()
|
||||
sync_init (void)
|
||||
{
|
||||
int combined_output = 0;
|
||||
|
||||
@@ -250,7 +240,11 @@ pump_from_tmp (int from, FILE *to)
|
||||
if (len <= 0)
|
||||
break;
|
||||
if (fwrite (buffer, len, 1, to) < 1)
|
||||
perror ("fwrite()");
|
||||
{
|
||||
perror ("fwrite()");
|
||||
break;
|
||||
}
|
||||
fflush (to);
|
||||
}
|
||||
|
||||
#ifdef WINDOWS32
|
||||
@@ -289,7 +283,7 @@ release_semaphore (void *sem)
|
||||
/* Returns a file descriptor to a temporary file. The file is automatically
|
||||
closed/deleted on exit. Don't use a FILE* stream. */
|
||||
int
|
||||
output_tmpfd ()
|
||||
output_tmpfd (void)
|
||||
{
|
||||
int fd = -1;
|
||||
FILE *tfile = tmpfile ();
|
||||
@@ -350,7 +344,7 @@ setup_tmpfile (struct output *out)
|
||||
/* If we failed to create a temp file, disable output sync going forward. */
|
||||
error:
|
||||
output_close (out);
|
||||
output_sync = 0;
|
||||
output_sync = OUTPUT_SYNC_NONE;
|
||||
}
|
||||
|
||||
/* Synchronize the output of jobs in -j mode to keep the results of
|
||||
@@ -369,22 +363,21 @@ output_dump (struct output *out)
|
||||
int traced = 0;
|
||||
|
||||
/* Try to acquire the semaphore. If it fails, dump the output
|
||||
unsynchronized; still better than silently discarding it. */
|
||||
unsynchronized; still better than silently discarding it.
|
||||
We want to keep this lock for as little time as possible. */
|
||||
void *sem = acquire_semaphore ();
|
||||
|
||||
/* Log the working directory for this dump. */
|
||||
if (print_directory_flag && output_sync != OUTPUT_SYNC_RECURSE)
|
||||
traced = log_working_directory (output_context, 1);
|
||||
traced = log_working_directory (1);
|
||||
|
||||
/* We've entered the "critical section" during which a lock is held. We
|
||||
want to keep it as short as possible. */
|
||||
if (outfd_not_empty)
|
||||
pump_from_tmp (out->out, stdout);
|
||||
if (errfd_not_empty && out->err != out->out)
|
||||
pump_from_tmp (out->err, stderr);
|
||||
|
||||
if (traced)
|
||||
log_working_directory (output_context, 0);
|
||||
log_working_directory (0);
|
||||
|
||||
/* Exit the critical section. */
|
||||
if (sem)
|
||||
@@ -405,7 +398,7 @@ output_dump (struct output *out)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* OUTPUT_SYNC */
|
||||
#endif /* NO_OUTPUT_SYNC */
|
||||
|
||||
|
||||
/* Provide support for temporary files. */
|
||||
@@ -448,7 +441,7 @@ output_tmpfile (char **name, const char *template)
|
||||
|
||||
# ifdef HAVE_FDOPEN
|
||||
/* Can't use mkstemp(), but guard against a race condition. */
|
||||
fd = open (*name, O_CREAT|O_EXCL|O_WRONLY, 0600);
|
||||
EINTRLOOP (fd, open (*name, O_CREAT|O_EXCL|O_WRONLY, 0600));
|
||||
if (fd == -1)
|
||||
return 0;
|
||||
return fdopen (fd, "w");
|
||||
@@ -499,10 +492,10 @@ close_stdout (void)
|
||||
if (prev_fail || fclose_fail)
|
||||
{
|
||||
if (fclose_fail)
|
||||
error (NILF, _("write error: %s"), strerror (errno));
|
||||
perror_with_name (_("write error: stdout"), "");
|
||||
else
|
||||
error (NILF, _("write error"));
|
||||
exit (EXIT_FAILURE);
|
||||
O (error, NILF, _("write error: stdout"));
|
||||
exit (MAKE_TROUBLE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -547,11 +540,11 @@ output_close (struct output *out)
|
||||
if (! out)
|
||||
{
|
||||
if (stdio_traced)
|
||||
log_working_directory (NULL, 0);
|
||||
log_working_directory (0);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef OUTPUT_SYNC
|
||||
#ifndef NO_OUTPUT_SYNC
|
||||
output_dump (out);
|
||||
#endif
|
||||
|
||||
@@ -565,18 +558,20 @@ output_close (struct output *out)
|
||||
|
||||
/* We're about to generate output: be sure it's set up. */
|
||||
void
|
||||
output_start ()
|
||||
output_start (void)
|
||||
{
|
||||
#ifdef OUTPUT_SYNC
|
||||
if (output_context && output_context->syncout && ! OUTPUT_ISSET(output_context))
|
||||
setup_tmpfile (output_context);
|
||||
#ifndef NO_OUTPUT_SYNC
|
||||
/* If we're syncing output make sure the temporary file is set up. */
|
||||
if (output_context && output_context->syncout)
|
||||
if (! OUTPUT_ISSET(output_context))
|
||||
setup_tmpfile (output_context);
|
||||
#endif
|
||||
|
||||
if (! output_context || output_sync == OUTPUT_SYNC_RECURSE)
|
||||
{
|
||||
if (! stdio_traced && print_directory_flag)
|
||||
stdio_traced = log_working_directory (NULL, 1);
|
||||
}
|
||||
/* If we're not syncing this output per-line or per-target, make sure we emit
|
||||
the "Entering..." message where appropriate. */
|
||||
if (output_sync == OUTPUT_SYNC_NONE || output_sync == OUTPUT_SYNC_RECURSE)
|
||||
if (! stdio_traced && print_directory_flag)
|
||||
stdio_traced = log_working_directory (1);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -591,141 +586,120 @@ outputs (int is_err, const char *msg)
|
||||
}
|
||||
|
||||
|
||||
/* Return formatted string buffers.
|
||||
If we move to gnulib we can use vasnprintf() etc. to make this simpler.
|
||||
Note these functions use a static buffer, so each call overwrites the
|
||||
results of the previous call. */
|
||||
|
||||
static struct fmtstring
|
||||
{
|
||||
char *buffer;
|
||||
unsigned int size;
|
||||
unsigned int len;
|
||||
} fmtbuf = { NULL, 0, 0 };
|
||||
size_t size;
|
||||
} fmtbuf = { NULL, 0 };
|
||||
|
||||
/* Concatenate a formatted string onto the format buffer. */
|
||||
static const char *
|
||||
vfmtconcat (const char *fmt, va_list args)
|
||||
static char *
|
||||
get_buffer (size_t need)
|
||||
{
|
||||
va_list vcopy;
|
||||
int tot;
|
||||
int unused = fmtbuf.size - fmtbuf.len;
|
||||
|
||||
va_copy (vcopy, args);
|
||||
|
||||
tot = vsnprintf (&fmtbuf.buffer[fmtbuf.len], unused, fmt, args);
|
||||
assert (tot >= 0);
|
||||
|
||||
if (tot >= unused)
|
||||
/* Make sure we have room. NEED includes space for \0. */
|
||||
if (need > fmtbuf.size)
|
||||
{
|
||||
fmtbuf.size += tot * 2;
|
||||
fmtbuf.size += need * 2;
|
||||
fmtbuf.buffer = xrealloc (fmtbuf.buffer, fmtbuf.size);
|
||||
|
||||
unused = fmtbuf.size - fmtbuf.len;
|
||||
tot = vsnprintf (&fmtbuf.buffer[fmtbuf.len], unused, fmt, vcopy);
|
||||
}
|
||||
|
||||
va_end (vcopy);
|
||||
|
||||
fmtbuf.len += tot;
|
||||
fmtbuf.buffer[need-1] = '\0';
|
||||
|
||||
return fmtbuf.buffer;
|
||||
}
|
||||
|
||||
static const char *
|
||||
fmtconcat (const char *fmt, ...)
|
||||
{
|
||||
const char *p;
|
||||
va_list args;
|
||||
|
||||
va_start (args, fmt);
|
||||
p = vfmtconcat (fmt, args);
|
||||
va_end (args);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Print a message on stdout. */
|
||||
|
||||
void
|
||||
message (int prefix, const char *fmt, ...)
|
||||
message (int prefix, size_t len, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char *p;
|
||||
|
||||
assert (fmt != NULL);
|
||||
|
||||
fmtbuf.len = 0;
|
||||
len += strlen (fmt) + strlen (program) + INTSTR_LENGTH + 4 + 1 + 1;
|
||||
p = get_buffer (len);
|
||||
|
||||
if (prefix)
|
||||
{
|
||||
if (makelevel == 0)
|
||||
fmtconcat ("%s: ", program);
|
||||
sprintf (p, "%s: ", program);
|
||||
else
|
||||
fmtconcat ("%s[%u]: ", program, makelevel);
|
||||
sprintf (p, "%s[%u]: ", program, makelevel);
|
||||
p += strlen (p);
|
||||
}
|
||||
|
||||
va_start (args, fmt);
|
||||
vfmtconcat (fmt, args);
|
||||
vsprintf (p, fmt, args);
|
||||
va_end (args);
|
||||
|
||||
fmtconcat ("\n");
|
||||
strcat (p, "\n");
|
||||
|
||||
assert (fmtbuf.buffer[len-1] == '\0');
|
||||
outputs (0, fmtbuf.buffer);
|
||||
}
|
||||
|
||||
/* Print an error message. */
|
||||
|
||||
void
|
||||
error (const gmk_floc *flocp, const char *fmt, ...)
|
||||
error (const floc *flocp, size_t len, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char *p;
|
||||
|
||||
assert (fmt != NULL);
|
||||
|
||||
fmtbuf.len = 0;
|
||||
len += (strlen (fmt) + strlen (program)
|
||||
+ (flocp && flocp->filenm ? strlen (flocp->filenm) : 0)
|
||||
+ INTSTR_LENGTH + 4 + 1 + 1);
|
||||
p = get_buffer (len);
|
||||
|
||||
if (flocp && flocp->filenm)
|
||||
fmtconcat ("%s:%lu: ", flocp->filenm, flocp->lineno);
|
||||
sprintf (p, "%s:%lu: ", flocp->filenm, flocp->lineno + flocp->offset);
|
||||
else if (makelevel == 0)
|
||||
fmtconcat ("%s: ", program);
|
||||
sprintf (p, "%s: ", program);
|
||||
else
|
||||
fmtconcat ("%s[%u]: ", program, makelevel);
|
||||
sprintf (p, "%s[%u]: ", program, makelevel);
|
||||
p += strlen (p);
|
||||
|
||||
va_start (args, fmt);
|
||||
vfmtconcat (fmt, args);
|
||||
vsprintf (p, fmt, args);
|
||||
va_end (args);
|
||||
|
||||
fmtconcat ("\n");
|
||||
strcat (p, "\n");
|
||||
|
||||
assert (fmtbuf.buffer[len-1] == '\0');
|
||||
outputs (1, fmtbuf.buffer);
|
||||
}
|
||||
|
||||
/* Print an error message and exit. */
|
||||
|
||||
void
|
||||
fatal (const gmk_floc *flocp, const char *fmt, ...)
|
||||
fatal (const floc *flocp, size_t len, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
const char *stop = _(". Stop.\n");
|
||||
char *p;
|
||||
|
||||
assert (fmt != NULL);
|
||||
|
||||
fmtbuf.len = 0;
|
||||
len += (strlen (fmt) + strlen (program)
|
||||
+ (flocp && flocp->filenm ? strlen (flocp->filenm) : 0)
|
||||
+ INTSTR_LENGTH + 8 + strlen (stop) + 1);
|
||||
p = get_buffer (len);
|
||||
|
||||
if (flocp && flocp->filenm)
|
||||
fmtconcat ("%s:%lu: *** ", flocp->filenm, flocp->lineno);
|
||||
sprintf (p, "%s:%lu: *** ", flocp->filenm, flocp->lineno + flocp->offset);
|
||||
else if (makelevel == 0)
|
||||
fmtconcat ("%s: *** ", program);
|
||||
sprintf (p, "%s: *** ", program);
|
||||
else
|
||||
fmtconcat ("%s[%u]: *** ", program, makelevel);
|
||||
sprintf (p, "%s[%u]: *** ", program, makelevel);
|
||||
p += strlen (p);
|
||||
|
||||
va_start (args, fmt);
|
||||
vfmtconcat (fmt, args);
|
||||
vsprintf (p, fmt, args);
|
||||
va_end (args);
|
||||
|
||||
fmtconcat (_(". Stop.\n"));
|
||||
strcat (p, stop);
|
||||
|
||||
assert (fmtbuf.buffer[len-1] == '\0');
|
||||
outputs (1, fmtbuf.buffer);
|
||||
|
||||
die (2);
|
||||
die (MAKE_FAILURE);
|
||||
}
|
||||
|
||||
/* Print an error message from errno. */
|
||||
@@ -733,7 +707,8 @@ fatal (const gmk_floc *flocp, const char *fmt, ...)
|
||||
void
|
||||
perror_with_name (const char *str, const char *name)
|
||||
{
|
||||
error (NILF, _("%s%s: %s"), str, name, strerror (errno));
|
||||
const char *err = strerror (errno);
|
||||
OSSS (error, NILF, _("%s%s: %s"), str, name, err);
|
||||
}
|
||||
|
||||
/* Print an error message from errno and exit. */
|
||||
@@ -741,7 +716,8 @@ perror_with_name (const char *str, const char *name)
|
||||
void
|
||||
pfatal_with_name (const char *name)
|
||||
{
|
||||
fatal (NILF, _("%s: %s"), name, strerror (errno));
|
||||
const char *err = strerror (errno);
|
||||
OSS (fatal, NILF, _("%s: %s"), name, err);
|
||||
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
10
output.h
10
output.h
@@ -1,5 +1,5 @@
|
||||
/* Output to stdout / stderr for GNU make
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
Copyright (C) 2013-2016 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
@@ -22,10 +22,14 @@ struct output
|
||||
};
|
||||
|
||||
extern struct output *output_context;
|
||||
extern unsigned int stdio_traced;
|
||||
|
||||
#define OUTPUT_SET(_new) do{ if ((_new)->syncout) output_context = (_new); }while(0)
|
||||
#define OUTPUT_SET(_new) do{ output_context = (_new)->syncout ? (_new) : NULL; }while(0)
|
||||
#define OUTPUT_UNSET() do{ output_context = NULL; }while(0)
|
||||
|
||||
#define OUTPUT_TRACED() do{ stdio_traced = 1; }while(0)
|
||||
#define OUTPUT_IS_TRACED() (!!stdio_traced)
|
||||
|
||||
FILE *output_tmpfile (char **, const char *);
|
||||
|
||||
/* Initialize and close a child output structure: if NULL do this program's
|
||||
@@ -40,7 +44,7 @@ void output_start (void);
|
||||
/* Show a message on stdout or stderr. Will start the output if needed. */
|
||||
void outputs (int is_err, const char *msg);
|
||||
|
||||
#ifdef OUTPUT_SYNC
|
||||
#ifndef NO_OUTPUT_SYNC
|
||||
int output_tmpfd (void);
|
||||
/* Dump any child output content to stdout, and reset it. */
|
||||
void output_dump (struct output *out);
|
||||
|
||||
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
|
||||
@@ -32,6 +32,7 @@ load.c
|
||||
main.c
|
||||
misc.c
|
||||
output.c
|
||||
posixos.c
|
||||
read.c
|
||||
remake.c
|
||||
remote-cstms.c
|
||||
@@ -43,3 +44,4 @@ variable.h
|
||||
vmsfunctions.c
|
||||
vmsjobs.c
|
||||
vpath.c
|
||||
w32/w32os.c
|
||||
|
||||
431
posixos.c
Normal file
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"
|
||||
353
read.c
353
read.c
@@ -1,5 +1,5 @@
|
||||
/* Reading and parsing of makefiles for GNU Make.
|
||||
Copyright (C) 1988-2013 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988-2016 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
@@ -18,10 +18,8 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <glob.h>
|
||||
|
||||
#include "dep.h"
|
||||
#include "filedef.h"
|
||||
#include "dep.h"
|
||||
#include "job.h"
|
||||
#include "commands.h"
|
||||
#include "variable.h"
|
||||
@@ -54,7 +52,7 @@ struct ebuffer
|
||||
char *bufstart; /* Start of the entire buffer. */
|
||||
unsigned int size; /* Malloc'd size of buffer. */
|
||||
FILE *fp; /* File, or NULL if this is an internal buffer. */
|
||||
gmk_floc floc; /* Info on the file in fp (if any). */
|
||||
floc floc; /* Info on the file in fp (if any). */
|
||||
};
|
||||
|
||||
/* Track the modifiers we can have on variable assignments */
|
||||
@@ -128,13 +126,13 @@ static unsigned int max_incl_len;
|
||||
/* The filename and pointer to line number of the
|
||||
makefile currently being read in. */
|
||||
|
||||
const gmk_floc *reading_file = 0;
|
||||
const floc *reading_file = 0;
|
||||
|
||||
/* The chain of files read by read_all_makefiles. */
|
||||
|
||||
static struct dep *read_files = 0;
|
||||
static struct goaldep *read_files = 0;
|
||||
|
||||
static int eval_makefile (const char *filename, int flags);
|
||||
static struct goaldep *eval_makefile (const char *filename, int flags);
|
||||
static void eval (struct ebuffer *buffer, int flags);
|
||||
|
||||
static long readline (struct ebuffer *ebuf);
|
||||
@@ -142,16 +140,16 @@ static void do_undefine (char *name, enum variable_origin origin,
|
||||
struct ebuffer *ebuf);
|
||||
static struct variable *do_define (char *name, enum variable_origin origin,
|
||||
struct ebuffer *ebuf);
|
||||
static int conditional_line (char *line, int len, const gmk_floc *flocp);
|
||||
static int conditional_line (char *line, int len, const floc *flocp);
|
||||
static void record_files (struct nameseq *filenames, const char *pattern,
|
||||
const char *pattern_percent, char *depstr,
|
||||
unsigned int cmds_started, char *commands,
|
||||
unsigned int commands_idx, int two_colon,
|
||||
char prefix, const gmk_floc *flocp);
|
||||
char prefix, const floc *flocp);
|
||||
static void record_target_var (struct nameseq *filenames, char *defn,
|
||||
enum variable_origin origin,
|
||||
struct vmodifiers *vmod,
|
||||
const gmk_floc *flocp);
|
||||
const floc *flocp);
|
||||
static enum make_word_type get_next_mword (char *buffer, char *delim,
|
||||
char **startp, unsigned int *length);
|
||||
static void remove_comments (char *line);
|
||||
@@ -167,7 +165,7 @@ static char *unescape_char (char *string, int c);
|
||||
|
||||
/* Read in all the makefiles and return a chain of targets to rebuild. */
|
||||
|
||||
struct dep *
|
||||
struct goaldep *
|
||||
read_all_makefiles (const char **makefiles)
|
||||
{
|
||||
unsigned int num_makefiles = 0;
|
||||
@@ -217,17 +215,11 @@ read_all_makefiles (const char **makefiles)
|
||||
if (makefiles != 0)
|
||||
while (*makefiles != 0)
|
||||
{
|
||||
struct dep *tail = read_files;
|
||||
struct dep *d;
|
||||
struct goaldep *d = eval_makefile (*makefiles, 0);
|
||||
|
||||
if (! eval_makefile (*makefiles, 0))
|
||||
if (errno)
|
||||
perror_with_name ("", *makefiles);
|
||||
|
||||
/* Find the first element eval_makefile() added to read_files. */
|
||||
d = read_files;
|
||||
while (d->next != tail)
|
||||
d = d->next;
|
||||
|
||||
/* Reuse the storage allocated for the read_file. */
|
||||
*makefiles = dep_name (d);
|
||||
++num_makefiles;
|
||||
@@ -238,42 +230,47 @@ read_all_makefiles (const char **makefiles)
|
||||
|
||||
if (num_makefiles == 0)
|
||||
{
|
||||
static char *default_makefiles[] =
|
||||
static const char *default_makefiles[] =
|
||||
#ifdef VMS
|
||||
/* all lower case since readdir() (the vms version) 'lowercasifies' */
|
||||
{ "makefile.vms", "gnumakefile.", "makefile.", 0 };
|
||||
/* TODO: Above is not always true, this needs more work */
|
||||
{ "makefile.vms", "gnumakefile", "makefile", 0 };
|
||||
#else
|
||||
#ifdef _AMIGA
|
||||
{ "GNUmakefile", "Makefile", "SMakefile", 0 };
|
||||
#else /* !Amiga && !VMS */
|
||||
#ifdef WINDOWS32
|
||||
{ "GNUmakefile", "makefile", "Makefile", "makefile.mak", 0 };
|
||||
#else /* !Amiga && !VMS && !WINDOWS32 */
|
||||
{ "GNUmakefile", "makefile", "Makefile", 0 };
|
||||
#endif /* !Amiga && !VMS && !WINDOWS32 */
|
||||
#endif /* AMIGA */
|
||||
#endif /* VMS */
|
||||
register char **p = default_makefiles;
|
||||
const char **p = default_makefiles;
|
||||
while (*p != 0 && !file_exists_p (*p))
|
||||
++p;
|
||||
|
||||
if (*p != 0)
|
||||
{
|
||||
if (! eval_makefile (*p, 0))
|
||||
eval_makefile (*p, 0);
|
||||
if (errno)
|
||||
perror_with_name ("", *p);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No default makefile was found. Add the default makefiles to the
|
||||
'read_files' chain so they will be updated if possible. */
|
||||
struct dep *tail = read_files;
|
||||
struct goaldep *tail = read_files;
|
||||
/* Add them to the tail, after any MAKEFILES variable makefiles. */
|
||||
while (tail != 0 && tail->next != 0)
|
||||
tail = tail->next;
|
||||
for (p = default_makefiles; *p != 0; ++p)
|
||||
{
|
||||
struct dep *d = alloc_dep ();
|
||||
struct goaldep *d = alloc_goaldep ();
|
||||
d->file = enter_file (strcache_add (*p));
|
||||
d->dontcare = 1;
|
||||
/* Tell update_goal_chain to bail out as soon as this file is
|
||||
made, and main not to die if we can't make this file. */
|
||||
d->changed = RM_DONTCARE;
|
||||
d->flags = RM_DONTCARE;
|
||||
if (tail == 0)
|
||||
read_files = d;
|
||||
else
|
||||
@@ -307,26 +304,25 @@ static void
|
||||
restore_conditionals (struct conditionals *saved)
|
||||
{
|
||||
/* Free any space allocated by conditional_line. */
|
||||
if (conditionals->ignoring)
|
||||
free (conditionals->ignoring);
|
||||
if (conditionals->seen_else)
|
||||
free (conditionals->seen_else);
|
||||
free (conditionals->ignoring);
|
||||
free (conditionals->seen_else);
|
||||
|
||||
/* Restore state. */
|
||||
conditionals = saved;
|
||||
}
|
||||
|
||||
static int
|
||||
static struct goaldep *
|
||||
eval_makefile (const char *filename, int flags)
|
||||
{
|
||||
struct dep *deps;
|
||||
struct goaldep *deps;
|
||||
struct ebuffer ebuf;
|
||||
const gmk_floc *curfile;
|
||||
const floc *curfile;
|
||||
char *expanded = 0;
|
||||
int makefile_errno;
|
||||
|
||||
ebuf.floc.filenm = filename; /* Use the original file name. */
|
||||
ebuf.floc.lineno = 1;
|
||||
ebuf.floc.offset = 0;
|
||||
|
||||
if (ISDB (DB_VERBOSE))
|
||||
{
|
||||
@@ -368,7 +364,10 @@ eval_makefile (const char *filename, int flags)
|
||||
case ENFILE:
|
||||
#endif
|
||||
case ENOMEM:
|
||||
fatal (reading_file, "%s", strerror (makefile_errno));
|
||||
{
|
||||
const char *err = strerror (makefile_errno);
|
||||
OS (fatal, reading_file, "%s", err);
|
||||
}
|
||||
}
|
||||
|
||||
/* If the makefile wasn't found and it's either a makefile from
|
||||
@@ -395,29 +394,26 @@ eval_makefile (const char *filename, int flags)
|
||||
filename = strcache_add (filename);
|
||||
|
||||
/* Add FILENAME to the chain of read makefiles. */
|
||||
deps = alloc_dep ();
|
||||
deps = alloc_goaldep ();
|
||||
deps->next = read_files;
|
||||
read_files = deps;
|
||||
deps->file = lookup_file (filename);
|
||||
if (deps->file == 0)
|
||||
deps->file = enter_file (filename);
|
||||
filename = deps->file->name;
|
||||
deps->changed = flags;
|
||||
if (flags & RM_DONTCARE)
|
||||
deps->dontcare = 1;
|
||||
deps->flags = flags;
|
||||
|
||||
if (expanded)
|
||||
free (expanded);
|
||||
free (expanded);
|
||||
|
||||
/* If the makefile can't be found at all, give up entirely. */
|
||||
|
||||
if (ebuf.fp == 0)
|
||||
{
|
||||
/* If we did some searching, errno has the error from the last
|
||||
attempt, rather from FILENAME itself. Restore it in case the
|
||||
attempt, rather from FILENAME itself. Store it in case the
|
||||
caller wants to use it in a message. */
|
||||
errno = makefile_errno;
|
||||
return 0;
|
||||
return deps;
|
||||
}
|
||||
|
||||
/* Set close-on-exec to avoid leaking the makefile to children, such as
|
||||
@@ -447,16 +443,17 @@ eval_makefile (const char *filename, int flags)
|
||||
free (ebuf.bufstart);
|
||||
alloca (0);
|
||||
|
||||
return 1;
|
||||
errno = 0;
|
||||
return deps;
|
||||
}
|
||||
|
||||
void
|
||||
eval_buffer (char *buffer, const gmk_floc *floc)
|
||||
eval_buffer (char *buffer, const floc *flocp)
|
||||
{
|
||||
struct ebuffer ebuf;
|
||||
struct conditionals *saved;
|
||||
struct conditionals new;
|
||||
const gmk_floc *curfile;
|
||||
const floc *curfile;
|
||||
|
||||
/* Evaluate the buffer */
|
||||
|
||||
@@ -464,14 +461,15 @@ eval_buffer (char *buffer, const gmk_floc *floc)
|
||||
ebuf.buffer = ebuf.bufnext = ebuf.bufstart = buffer;
|
||||
ebuf.fp = NULL;
|
||||
|
||||
if (floc)
|
||||
ebuf.floc = *floc;
|
||||
if (flocp)
|
||||
ebuf.floc = *flocp;
|
||||
else if (reading_file)
|
||||
ebuf.floc = *reading_file;
|
||||
else
|
||||
{
|
||||
ebuf.floc.filenm = NULL;
|
||||
ebuf.floc.lineno = 1;
|
||||
ebuf.floc.offset = 0;
|
||||
}
|
||||
|
||||
curfile = reading_file;
|
||||
@@ -506,7 +504,7 @@ parse_var_assignment (const char *line, struct vmodifiers *vmod)
|
||||
memset (vmod, '\0', sizeof (*vmod));
|
||||
|
||||
/* Find the start of the next token. If there isn't one we're done. */
|
||||
line = next_token (line);
|
||||
NEXT_TOKEN (line);
|
||||
if (*line == '\0')
|
||||
return (char *)line;
|
||||
|
||||
@@ -585,8 +583,8 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
char prefix = cmd_prefix;
|
||||
const char *pattern = 0;
|
||||
const char *pattern_percent;
|
||||
gmk_floc *fstart;
|
||||
gmk_floc fi;
|
||||
floc *fstart;
|
||||
floc fi;
|
||||
|
||||
#define record_waiting_files() \
|
||||
do \
|
||||
@@ -594,6 +592,7 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
if (filenames != 0) \
|
||||
{ \
|
||||
fi.lineno = tgts_started; \
|
||||
fi.offset = 0; \
|
||||
record_files (filenames, pattern, pattern_percent, depstr, \
|
||||
cmds_started, commands, commands_idx, two_colon, \
|
||||
prefix, &fi); \
|
||||
@@ -704,8 +703,7 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
if (collapsed_length < linelen+1)
|
||||
{
|
||||
collapsed_length = linelen+1;
|
||||
if (collapsed)
|
||||
free (collapsed);
|
||||
free (collapsed);
|
||||
/* Don't need xrealloc: we don't need to preserve the content. */
|
||||
collapsed = xmalloc (collapsed_length);
|
||||
}
|
||||
@@ -716,8 +714,7 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
|
||||
/* Get rid if starting space (including formfeed, vtab, etc.) */
|
||||
p = collapsed;
|
||||
while (isspace ((unsigned char)*p))
|
||||
++p;
|
||||
NEXT_TOKEN (p);
|
||||
|
||||
/* See if this is a variable assignment. We need to do this early, to
|
||||
allow variables with names like 'ifdef', 'export', 'private', etc. */
|
||||
@@ -727,9 +724,6 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
struct variable *v;
|
||||
enum variable_origin origin = vmod.override_v ? o_override : o_file;
|
||||
|
||||
/* Variable assignment ends the previous rule. */
|
||||
record_waiting_files ();
|
||||
|
||||
/* If we're ignoring then we're done now. */
|
||||
if (ignoring)
|
||||
{
|
||||
@@ -738,6 +732,9 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Variable assignment ends the previous rule. */
|
||||
record_waiting_files ();
|
||||
|
||||
if (vmod.undefine_v)
|
||||
{
|
||||
do_undefine (p, origin, ebuf);
|
||||
@@ -765,7 +762,7 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
|
||||
p2 = end_of_token (p);
|
||||
wlen = p2 - p;
|
||||
p2 = next_token (p2);
|
||||
NEXT_TOKEN (p2);
|
||||
|
||||
/* If we're in an ignored define, skip this line (but maybe get out). */
|
||||
if (in_ignored_define)
|
||||
@@ -783,7 +780,7 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
if (i != -2)
|
||||
{
|
||||
if (i == -1)
|
||||
fatal (fstart, _("invalid syntax in conditional"));
|
||||
O (fatal, fstart, _("invalid syntax in conditional"));
|
||||
|
||||
ignoring = i;
|
||||
continue;
|
||||
@@ -853,8 +850,7 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
/* No pattern means remove all previous selective VPATH's. */
|
||||
vpat = 0;
|
||||
construct_vpath_list (vpat, p);
|
||||
if (vpat != 0)
|
||||
free (vpat);
|
||||
free (vpat);
|
||||
|
||||
continue;
|
||||
}
|
||||
@@ -901,18 +897,20 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
while (files != 0)
|
||||
{
|
||||
struct nameseq *next = files->next;
|
||||
const char *name = files->name;
|
||||
int r;
|
||||
int flags = (RM_INCLUDED | RM_NO_TILDE
|
||||
| (noerror ? RM_DONTCARE : 0)
|
||||
| (set_default ? 0 : RM_NO_DEFAULT_GOAL));
|
||||
|
||||
struct goaldep *d = eval_makefile (files->name, flags);
|
||||
|
||||
if (errno)
|
||||
{
|
||||
d->error = (unsigned short)errno;
|
||||
d->floc = *fstart;
|
||||
}
|
||||
|
||||
free_ns (files);
|
||||
files = next;
|
||||
|
||||
r = eval_makefile (name,
|
||||
(RM_INCLUDED | RM_NO_TILDE
|
||||
| (noerror ? RM_DONTCARE : 0)
|
||||
| (set_default ? 0 : RM_NO_DEFAULT_GOAL)));
|
||||
if (!r && !noerror)
|
||||
error (fstart, "%s: %s", name, strerror (errno));
|
||||
}
|
||||
|
||||
/* Restore conditional state. */
|
||||
@@ -947,20 +945,28 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
PARSEFS_NOAR);
|
||||
free (p);
|
||||
|
||||
/* Load each file and add it to the list "to be rebuilt". */
|
||||
/* Load each file. */
|
||||
while (files != 0)
|
||||
{
|
||||
struct nameseq *next = files->next;
|
||||
const char *name = files->name;
|
||||
struct dep *deps;
|
||||
struct goaldep *deps;
|
||||
int r;
|
||||
|
||||
/* Load the file. 0 means failure. */
|
||||
r = load_file (&ebuf->floc, &name, noerror);
|
||||
if (! r && ! noerror)
|
||||
OS (fatal, &ebuf->floc, _("%s: failed to load"), name);
|
||||
|
||||
free_ns (files);
|
||||
files = next;
|
||||
|
||||
if (! load_file (&ebuf->floc, &name, noerror) && ! noerror)
|
||||
fatal (&ebuf->floc, _("%s: failed to load"), name);
|
||||
/* Return of -1 means a special load: don't rebuild it. */
|
||||
if (r == -1)
|
||||
continue;
|
||||
|
||||
deps = alloc_dep ();
|
||||
/* It succeeded, so add it to the list "to be rebuilt". */
|
||||
deps = alloc_goaldep ();
|
||||
deps->next = read_files;
|
||||
read_files = deps;
|
||||
deps->file = lookup_file (name);
|
||||
@@ -976,7 +982,7 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
was no preceding target, and the line might have been usable as a
|
||||
variable definition. But now we know it is definitely lossage. */
|
||||
if (line[0] == cmd_prefix)
|
||||
fatal (fstart, _("recipe commences before first target"));
|
||||
O (fatal, fstart, _("recipe commences before first target"));
|
||||
|
||||
/* This line describes some target files. This is complicated by
|
||||
the existence of target-specific variables, because we can't
|
||||
@@ -1025,7 +1031,7 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
{
|
||||
case w_eol:
|
||||
if (cmdleft != 0)
|
||||
fatal (fstart, _("missing rule before recipe"));
|
||||
O (fatal, fstart, _("missing rule before recipe"));
|
||||
/* This line contained something but turned out to be nothing
|
||||
but whitespace (a comment?). */
|
||||
continue;
|
||||
@@ -1065,7 +1071,7 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
here, but merely copy, since now you're beyond a ";"
|
||||
and into a command script. However, the old parser
|
||||
expanded the whole line, so we continue that for
|
||||
backwards-compatiblity. Also, it wouldn't be
|
||||
backwards-compatibility. Also, it wouldn't be
|
||||
entirely consistent, since we do an unconditional
|
||||
expand below once we know we don't have a
|
||||
target-specific variable. */
|
||||
@@ -1109,13 +1115,15 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
it. If so, we can't parse this line so punt. */
|
||||
if (wtype == w_eol)
|
||||
{
|
||||
if (*p2 != '\0')
|
||||
/* There's no need to be ivory-tower about this: check for
|
||||
one of the most common bugs found in makefiles... */
|
||||
fatal (fstart, _("missing separator%s"),
|
||||
(cmd_prefix == '\t' && !strneq (line, " ", 8))
|
||||
? "" : _(" (did you mean TAB instead of 8 spaces?)"));
|
||||
continue;
|
||||
if (*p2 == '\0')
|
||||
continue;
|
||||
|
||||
/* There's no need to be ivory-tower about this: check for
|
||||
one of the most common bugs found in makefiles... */
|
||||
if (cmd_prefix == '\t' && strneq (line, " ", 8))
|
||||
O (fatal, fstart, _("missing separator (did you mean TAB instead of 8 spaces?)"));
|
||||
else
|
||||
O (fatal, fstart, _("missing separator"));
|
||||
}
|
||||
|
||||
/* Make the colon the end-of-string so we know where to stop
|
||||
@@ -1226,8 +1234,7 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
The rule is that it's only a target, if there are TWO :'s
|
||||
OR a space around the :.
|
||||
*/
|
||||
if (p && !(isspace ((unsigned char)p[1]) || !p[1]
|
||||
|| isspace ((unsigned char)p[-1])))
|
||||
if (p && !(ISSPACE (p[1]) || !p[1] || ISSPACE (p[-1])))
|
||||
p = 0;
|
||||
#endif
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
@@ -1252,13 +1259,13 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
PARSEFS_NOGLOB);
|
||||
++p2;
|
||||
if (target == 0)
|
||||
fatal (fstart, _("missing target pattern"));
|
||||
O (fatal, fstart, _("missing target pattern"));
|
||||
else if (target->next != 0)
|
||||
fatal (fstart, _("multiple target patterns"));
|
||||
O (fatal, fstart, _("multiple target patterns"));
|
||||
pattern_percent = find_percent_cached (&target->name);
|
||||
pattern = target->name;
|
||||
if (pattern_percent == 0)
|
||||
fatal (fstart, _("target pattern contains no '%%'"));
|
||||
O (fatal, fstart, _("target pattern contains no '%%'"));
|
||||
free_ns (target);
|
||||
}
|
||||
else
|
||||
@@ -1380,13 +1387,12 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
#undef word1eq
|
||||
|
||||
if (conditionals->if_cmds)
|
||||
fatal (fstart, _("missing 'endif'"));
|
||||
O (fatal, fstart, _("missing 'endif'"));
|
||||
|
||||
/* At eof, record the last rule. */
|
||||
record_waiting_files ();
|
||||
|
||||
if (collapsed)
|
||||
free (collapsed);
|
||||
free (collapsed);
|
||||
free (commands);
|
||||
}
|
||||
|
||||
@@ -1419,9 +1425,9 @@ do_undefine (char *name, enum variable_origin origin, struct ebuffer *ebuf)
|
||||
var = allocated_variable_expand (name);
|
||||
name = next_token (var);
|
||||
if (*name == '\0')
|
||||
fatal (&ebuf->floc, _("empty variable name"));
|
||||
O (fatal, &ebuf->floc, _("empty variable name"));
|
||||
p = name + strlen (name) - 1;
|
||||
while (p > name && isblank ((unsigned char)*p))
|
||||
while (p > name && ISBLANK (*p))
|
||||
--p;
|
||||
p[1] = '\0';
|
||||
|
||||
@@ -1438,7 +1444,7 @@ do_define (char *name, enum variable_origin origin, struct ebuffer *ebuf)
|
||||
{
|
||||
struct variable *v;
|
||||
struct variable var;
|
||||
gmk_floc defstart;
|
||||
floc defstart;
|
||||
int nlevels = 1;
|
||||
unsigned int length = 100;
|
||||
char *definition = xmalloc (length);
|
||||
@@ -1454,7 +1460,7 @@ do_define (char *name, enum variable_origin origin, struct ebuffer *ebuf)
|
||||
else
|
||||
{
|
||||
if (var.value[0] != '\0')
|
||||
error (&defstart, _("extraneous text after 'define' directive"));
|
||||
O (error, &defstart, _("extraneous text after 'define' directive"));
|
||||
|
||||
/* Chop the string before the assignment token to get the name. */
|
||||
var.name[var.length] = '\0';
|
||||
@@ -1464,9 +1470,9 @@ do_define (char *name, enum variable_origin origin, struct ebuffer *ebuf)
|
||||
n = allocated_variable_expand (name);
|
||||
name = next_token (n);
|
||||
if (name[0] == '\0')
|
||||
fatal (&defstart, _("empty variable name"));
|
||||
O (fatal, &defstart, _("empty variable name"));
|
||||
p = name + strlen (name) - 1;
|
||||
while (p > name && isblank ((unsigned char)*p))
|
||||
while (p > name && ISBLANK (*p))
|
||||
--p;
|
||||
p[1] = '\0';
|
||||
|
||||
@@ -1479,7 +1485,7 @@ do_define (char *name, enum variable_origin origin, struct ebuffer *ebuf)
|
||||
|
||||
/* If there is nothing left to be eval'd, there's no 'endef'!! */
|
||||
if (nlines < 0)
|
||||
fatal (&defstart, _("missing 'endef', unterminated 'define'"));
|
||||
O (fatal, &defstart, _("missing 'endef', unterminated 'define'"));
|
||||
|
||||
ebuf->floc.lineno += nlines;
|
||||
line = ebuf->buffer;
|
||||
@@ -1494,20 +1500,20 @@ do_define (char *name, enum variable_origin origin, struct ebuffer *ebuf)
|
||||
len = strlen (p);
|
||||
|
||||
/* If this is another 'define', increment the level count. */
|
||||
if ((len == 6 || (len > 6 && isblank ((unsigned char)p[6])))
|
||||
if ((len == 6 || (len > 6 && ISBLANK (p[6])))
|
||||
&& strneq (p, "define", 6))
|
||||
++nlevels;
|
||||
|
||||
/* If this is an 'endef', decrement the count. If it's now 0,
|
||||
we've found the last one. */
|
||||
else if ((len == 5 || (len > 5 && isblank ((unsigned char)p[5])))
|
||||
else if ((len == 5 || (len > 5 && ISBLANK (p[5])))
|
||||
&& strneq (p, "endef", 5))
|
||||
{
|
||||
p += 5;
|
||||
remove_comments (p);
|
||||
if (*(next_token (p)) != '\0')
|
||||
error (&ebuf->floc,
|
||||
_("extraneous text after 'endef' directive"));
|
||||
O (error, &ebuf->floc,
|
||||
_("extraneous text after 'endef' directive"));
|
||||
|
||||
if (--nlevels == 0)
|
||||
break;
|
||||
@@ -1554,9 +1560,9 @@ do_define (char *name, enum variable_origin origin, struct ebuffer *ebuf)
|
||||
1 if following text should be ignored. */
|
||||
|
||||
static int
|
||||
conditional_line (char *line, int len, const gmk_floc *flocp)
|
||||
conditional_line (char *line, int len, const floc *flocp)
|
||||
{
|
||||
char *cmdname;
|
||||
const char *cmdname;
|
||||
enum { c_ifdef, c_ifndef, c_ifeq, c_ifneq, c_else, c_endif } cmdtype;
|
||||
unsigned int i;
|
||||
unsigned int o;
|
||||
@@ -1576,18 +1582,20 @@ conditional_line (char *line, int len, const gmk_floc *flocp)
|
||||
return -2;
|
||||
|
||||
/* Found one: skip past it and any whitespace after it. */
|
||||
line = next_token (line + len);
|
||||
line += len;
|
||||
NEXT_TOKEN (line);
|
||||
|
||||
#define EXTRANEOUS() error (flocp, _("extraneous text after '%s' directive"), cmdname)
|
||||
#define EXTRATEXT() OS (error, flocp, _("extraneous text after '%s' directive"), cmdname)
|
||||
#define EXTRACMD() OS (fatal, flocp, _("extraneous '%s'"), cmdname)
|
||||
|
||||
/* An 'endif' cannot contain extra text, and reduces the if-depth by 1 */
|
||||
if (cmdtype == c_endif)
|
||||
{
|
||||
if (*line != '\0')
|
||||
EXTRANEOUS ();
|
||||
EXTRATEXT ();
|
||||
|
||||
if (!conditionals->if_cmds)
|
||||
fatal (flocp, _("extraneous '%s'"), cmdname);
|
||||
EXTRACMD ();
|
||||
|
||||
--conditionals->if_cmds;
|
||||
|
||||
@@ -1601,12 +1609,12 @@ conditional_line (char *line, int len, const gmk_floc *flocp)
|
||||
const char *p;
|
||||
|
||||
if (!conditionals->if_cmds)
|
||||
fatal (flocp, _("extraneous '%s'"), cmdname);
|
||||
EXTRACMD ();
|
||||
|
||||
o = conditionals->if_cmds - 1;
|
||||
|
||||
if (conditionals->seen_else[o])
|
||||
fatal (flocp, _("only one 'else' per conditional"));
|
||||
O (fatal, flocp, _("only one 'else' per conditional"));
|
||||
|
||||
/* Change the state of ignorance. */
|
||||
switch (conditionals->ignoring[o])
|
||||
@@ -1639,7 +1647,7 @@ conditional_line (char *line, int len, const gmk_floc *flocp)
|
||||
/* If it's 'else' or 'endif' or an illegal conditional, fail. */
|
||||
if (word1eq ("else") || word1eq ("endif")
|
||||
|| conditional_line (line, len, flocp) < 0)
|
||||
EXTRANEOUS ();
|
||||
EXTRATEXT ();
|
||||
else
|
||||
{
|
||||
/* conditional_line() created a new level of conditional.
|
||||
@@ -1696,7 +1704,7 @@ conditional_line (char *line, int len, const gmk_floc *flocp)
|
||||
/* Make sure there's only one variable name to test. */
|
||||
p = end_of_token (var);
|
||||
i = p - var;
|
||||
p = next_token (p);
|
||||
NEXT_TOKEN (p);
|
||||
if (*p != '\0')
|
||||
return -1;
|
||||
|
||||
@@ -1742,7 +1750,7 @@ conditional_line (char *line, int len, const gmk_floc *flocp)
|
||||
{
|
||||
/* Strip blanks after the first string. */
|
||||
char *p = line++;
|
||||
while (isblank ((unsigned char)p[-1]))
|
||||
while (ISBLANK (p[-1]))
|
||||
--p;
|
||||
*p = '\0';
|
||||
}
|
||||
@@ -1758,7 +1766,7 @@ conditional_line (char *line, int len, const gmk_floc *flocp)
|
||||
|
||||
if (termin != ',')
|
||||
/* Find the start of the second string. */
|
||||
line = next_token (line);
|
||||
NEXT_TOKEN (line);
|
||||
|
||||
termin = termin == ',' ? ')' : *line;
|
||||
if (termin != ')' && termin != '"' && termin != '\'')
|
||||
@@ -1793,10 +1801,10 @@ conditional_line (char *line, int len, const gmk_floc *flocp)
|
||||
if (*line == '\0')
|
||||
return -1;
|
||||
|
||||
*line = '\0';
|
||||
line = next_token (++line);
|
||||
*(line++) = '\0';
|
||||
NEXT_TOKEN (line);
|
||||
if (*line != '\0')
|
||||
EXTRANEOUS ();
|
||||
EXTRATEXT ();
|
||||
|
||||
s2 = variable_expand (s2);
|
||||
conditionals->ignoring[o] = (streq (s1, s2) == (cmdtype == c_ifneq));
|
||||
@@ -1823,7 +1831,7 @@ conditional_line (char *line, int len, const gmk_floc *flocp)
|
||||
static void
|
||||
record_target_var (struct nameseq *filenames, char *defn,
|
||||
enum variable_origin origin, struct vmodifiers *vmod,
|
||||
const gmk_floc *flocp)
|
||||
const floc *flocp)
|
||||
{
|
||||
struct nameseq *nextf;
|
||||
struct variable_set_list *global;
|
||||
@@ -1881,7 +1889,7 @@ record_target_var (struct nameseq *filenames, char *defn,
|
||||
current_variable_set_list = f->variables;
|
||||
v = try_variable_definition (flocp, defn, origin, 1);
|
||||
if (!v)
|
||||
fatal (flocp, _("Malformed target-specific variable definition"));
|
||||
O (fatal, flocp, _("Malformed target-specific variable definition"));
|
||||
current_variable_set_list = global;
|
||||
}
|
||||
|
||||
@@ -1901,8 +1909,7 @@ record_target_var (struct nameseq *filenames, char *defn,
|
||||
if (gv && v != gv
|
||||
&& (gv->origin == o_env_override || gv->origin == o_command))
|
||||
{
|
||||
if (v->value != 0)
|
||||
free (v->value);
|
||||
free (v->value);
|
||||
v->value = xstrdup (gv->value);
|
||||
v->origin = gv->origin;
|
||||
v->recursive = gv->recursive;
|
||||
@@ -1928,7 +1935,7 @@ record_files (struct nameseq *filenames, const char *pattern,
|
||||
const char *pattern_percent, char *depstr,
|
||||
unsigned int cmds_started, char *commands,
|
||||
unsigned int commands_idx, int two_colon,
|
||||
char prefix, const gmk_floc *flocp)
|
||||
char prefix, const floc *flocp)
|
||||
{
|
||||
struct commands *cmds;
|
||||
struct dep *deps;
|
||||
@@ -1940,7 +1947,7 @@ record_files (struct nameseq *filenames, const char *pattern,
|
||||
at this time, since they won't get snapped and we'll get core dumps.
|
||||
See Savannah bug # 12124. */
|
||||
if (snapped_deps)
|
||||
fatal (flocp, _("prerequisites cannot be defined in recipes"));
|
||||
O (fatal, flocp, _("prerequisites cannot be defined in recipes"));
|
||||
|
||||
/* Determine if this is a pattern rule or not. */
|
||||
name = filenames->name;
|
||||
@@ -1952,6 +1959,7 @@ record_files (struct nameseq *filenames, const char *pattern,
|
||||
cmds = xmalloc (sizeof (struct commands));
|
||||
cmds->fileinfo.filenm = flocp->filenm;
|
||||
cmds->fileinfo.lineno = cmds_started;
|
||||
cmds->fileinfo.offset = 0;
|
||||
cmds->commands = xstrndup (commands, commands_idx);
|
||||
cmds->command_lines = 0;
|
||||
cmds->recipe_prefix = prefix;
|
||||
@@ -1998,7 +2006,7 @@ record_files (struct nameseq *filenames, const char *pattern,
|
||||
unsigned int c;
|
||||
|
||||
if (pattern != 0)
|
||||
fatal (flocp, _("mixed implicit and static pattern rules"));
|
||||
O (fatal, flocp, _("mixed implicit and static pattern rules"));
|
||||
|
||||
/* Count the targets to create an array of target names.
|
||||
We already have the first one. */
|
||||
@@ -2021,7 +2029,7 @@ record_files (struct nameseq *filenames, const char *pattern,
|
||||
implicit_percent = find_percent_cached (&name);
|
||||
|
||||
if (implicit_percent == 0)
|
||||
fatal (flocp, _("mixed implicit and normal rules"));
|
||||
O (fatal, flocp, _("mixed implicit and normal rules"));
|
||||
|
||||
targets[c] = name;
|
||||
target_pats[c] = implicit_percent;
|
||||
@@ -2073,7 +2081,8 @@ record_files (struct nameseq *filenames, const char *pattern,
|
||||
'targets: target%pattern: prereq%pattern; recipe',
|
||||
make sure the pattern matches this target name. */
|
||||
if (pattern && !pattern_matches (pattern, pattern_percent, name))
|
||||
error (flocp, _("target '%s' doesn't match the target pattern"), name);
|
||||
OS (error, flocp,
|
||||
_("target '%s' doesn't match the target pattern"), name);
|
||||
else if (deps)
|
||||
/* If there are multiple targets, copy the chain DEPS for all but the
|
||||
last one. It is not safe for the same deps to go in more than one
|
||||
@@ -2087,25 +2096,26 @@ record_files (struct nameseq *filenames, const char *pattern,
|
||||
if any. */
|
||||
f = enter_file (strcache_add (name));
|
||||
if (f->double_colon)
|
||||
fatal (flocp,
|
||||
_("target file '%s' has both : and :: entries"), f->name);
|
||||
OS (fatal, flocp,
|
||||
_("target file '%s' has both : and :: entries"), f->name);
|
||||
|
||||
/* If CMDS == F->CMDS, this target was listed in this rule
|
||||
more than once. Just give a warning since this is harmless. */
|
||||
if (cmds != 0 && cmds == f->cmds)
|
||||
error (flocp,
|
||||
_("target '%s' given more than once in the same rule"),
|
||||
f->name);
|
||||
OS (error, flocp,
|
||||
_("target '%s' given more than once in the same rule"),
|
||||
f->name);
|
||||
|
||||
/* Check for two single-colon entries both with commands.
|
||||
Check is_target so that we don't lose on files such as .c.o
|
||||
whose commands were preinitialized. */
|
||||
else if (cmds != 0 && f->cmds != 0 && f->is_target)
|
||||
{
|
||||
error (&cmds->fileinfo,
|
||||
size_t l = strlen (f->name);
|
||||
error (&cmds->fileinfo, l,
|
||||
_("warning: overriding recipe for target '%s'"),
|
||||
f->name);
|
||||
error (&f->cmds->fileinfo,
|
||||
error (&f->cmds->fileinfo, l,
|
||||
_("warning: ignoring old recipe for target '%s'"),
|
||||
f->name);
|
||||
}
|
||||
@@ -2132,8 +2142,8 @@ record_files (struct nameseq *filenames, const char *pattern,
|
||||
/* Check for both : and :: rules. Check is_target so we don't lose
|
||||
on default suffix rules or makefiles. */
|
||||
if (f != 0 && f->is_target && !f->double_colon)
|
||||
fatal (flocp,
|
||||
_("target file '%s' has both : and :: entries"), f->name);
|
||||
OS (fatal, flocp,
|
||||
_("target file '%s' has both : and :: entries"), f->name);
|
||||
|
||||
f = enter_file (strcache_add (name));
|
||||
/* If there was an existing entry and it was a double-colon entry,
|
||||
@@ -2209,7 +2219,8 @@ record_files (struct nameseq *filenames, const char *pattern,
|
||||
/* Reduce escaped percents. If there are any unescaped it's an error */
|
||||
name = filenames->name;
|
||||
if (find_percent_cached (&name))
|
||||
fatal (flocp, _("mixed implicit and normal rules"));
|
||||
O (error, flocp,
|
||||
_("*** mixed implicit and normal rules: deprecated syntax"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2244,6 +2255,10 @@ find_char_unquote (char *string, int map)
|
||||
{
|
||||
char openparen = p[1];
|
||||
|
||||
/* Check if '$' is the last character in the string. */
|
||||
if (openparen == '\0')
|
||||
break;
|
||||
|
||||
p += 2;
|
||||
|
||||
/* Skip the contents of a non-quoted, multi-char variable ref. */
|
||||
@@ -2323,16 +2338,21 @@ unescape_char (char *string, int c)
|
||||
if (*e != c || l%2 == 0)
|
||||
{
|
||||
/* It's not; just take it all without unescaping. */
|
||||
memcpy (p, s, l);
|
||||
memmove (p, s, l);
|
||||
p += l;
|
||||
|
||||
// If we hit the end of the string, we're done
|
||||
if (*e == '\0')
|
||||
break;
|
||||
}
|
||||
else if (l > 1)
|
||||
{
|
||||
/* It is, and there's >1 backslash. Take half of them. */
|
||||
l /= 2;
|
||||
memcpy (p, s, l);
|
||||
memmove (p, s, l);
|
||||
p += l;
|
||||
}
|
||||
|
||||
s = e;
|
||||
}
|
||||
|
||||
@@ -2440,7 +2460,7 @@ find_percent_cached (const char **string)
|
||||
Since we aren't really reading from a file, don't bother with linenumbers.
|
||||
*/
|
||||
|
||||
static unsigned long
|
||||
static long
|
||||
readstring (struct ebuffer *ebuf)
|
||||
{
|
||||
char *eol;
|
||||
@@ -2518,8 +2538,8 @@ readline (struct ebuffer *ebuf)
|
||||
lossage strikes again! (xmkmf puts NULs in its makefiles.)
|
||||
There is nothing really to be done; we synthesize a newline so
|
||||
the following line doesn't appear to be part of this line. */
|
||||
error (&ebuf->floc,
|
||||
_("warning: NUL character seen; rest of line ignored"));
|
||||
O (error, &ebuf->floc,
|
||||
_("warning: NUL character seen; rest of line ignored"));
|
||||
p[0] = '\n';
|
||||
len = 1;
|
||||
}
|
||||
@@ -2614,7 +2634,7 @@ get_next_mword (char *buffer, char *delim, char **startp, unsigned int *length)
|
||||
char c;
|
||||
|
||||
/* Skip any leading whitespace. */
|
||||
while (isblank ((unsigned char)*p))
|
||||
while (ISBLANK (*p))
|
||||
++p;
|
||||
|
||||
beg = p;
|
||||
@@ -2712,6 +2732,8 @@ get_next_mword (char *buffer, char *delim, char **startp, unsigned int *length)
|
||||
c = *(p++);
|
||||
if (c == '$')
|
||||
break;
|
||||
if (c == '\0')
|
||||
goto done_word;
|
||||
|
||||
/* This is a variable reference, so note that it's expandable.
|
||||
Then read it to the matching close paren. */
|
||||
@@ -2834,8 +2856,7 @@ construct_include_path (const char **arg_dirs)
|
||||
dirs[idx++] = strcache_add_len (dir, len);
|
||||
}
|
||||
|
||||
if (expanded)
|
||||
free (expanded);
|
||||
free (expanded);
|
||||
}
|
||||
|
||||
/* Now add the standard default dirs at the end. */
|
||||
@@ -2897,7 +2918,6 @@ tilde_expand (const char *name)
|
||||
#ifndef VMS
|
||||
if (name[1] == '/' || name[1] == '\0')
|
||||
{
|
||||
extern char *getenv ();
|
||||
char *home_dir;
|
||||
int is_variable;
|
||||
|
||||
@@ -2920,7 +2940,6 @@ tilde_expand (const char *name)
|
||||
# if !defined(_AMIGA) && !defined(WINDOWS32)
|
||||
if (home_dir == 0 || home_dir[0] == '\0')
|
||||
{
|
||||
extern char *getlogin ();
|
||||
char *logname = getlogin ();
|
||||
home_dir = 0;
|
||||
if (logname != 0)
|
||||
@@ -2989,8 +3008,6 @@ void *
|
||||
parse_file_seq (char **stringp, unsigned int size, int stopmap,
|
||||
const char *prefix, int flags)
|
||||
{
|
||||
extern void dir_setup_glob (glob_t *glob);
|
||||
|
||||
/* tmp points to tmpbuf after the prefix, if any.
|
||||
tp is the end of the buffer. */
|
||||
static char *tmpbuf = NULL;
|
||||
@@ -3048,7 +3065,7 @@ parse_file_seq (char **stringp, unsigned int size, int stopmap,
|
||||
int i;
|
||||
|
||||
/* Skip whitespace; at the end of the string or STOPCHAR we're done. */
|
||||
p = next_token (p);
|
||||
NEXT_TOKEN (p);
|
||||
if (STOP_SET (*p, stopmap))
|
||||
break;
|
||||
|
||||
@@ -3063,8 +3080,7 @@ parse_file_seq (char **stringp, unsigned int size, int stopmap,
|
||||
#endif
|
||||
#ifdef _AMIGA
|
||||
if (p && STOP_SET (*p, stopmap & MAP_COLON)
|
||||
&& !(isspace ((unsigned char)p[1]) || !p[1]
|
||||
|| isspace ((unsigned char)p[-1])))
|
||||
&& !(ISSPACE (p[1]) || !p[1] || ISSPACE (p[-1])))
|
||||
p = find_char_unquote (p+1, stopmap|MAP_VMSCOMMA|MAP_BLANK);
|
||||
#endif
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
@@ -3073,7 +3089,7 @@ parse_file_seq (char **stringp, unsigned int size, int stopmap,
|
||||
Note that tokens separated by spaces should be treated as separate
|
||||
tokens since make doesn't allow path names with spaces */
|
||||
if (stopmap | MAP_COLON)
|
||||
while (p != 0 && !isspace ((unsigned char)*p) &&
|
||||
while (p != 0 && !ISSPACE (*p) &&
|
||||
(p[1] == '\\' || p[1] == '/') && isalpha ((unsigned char)p[-1]))
|
||||
p = find_char_unquote (p + 1, stopmap|MAP_VMSCOMMA|MAP_BLANK);
|
||||
#endif
|
||||
@@ -3083,12 +3099,15 @@ parse_file_seq (char **stringp, unsigned int size, int stopmap,
|
||||
/* Strip leading "this directory" references. */
|
||||
if (NONE_SET (flags, PARSEFS_NOSTRIP))
|
||||
#ifdef VMS
|
||||
/* Skip leading '[]'s. */
|
||||
while (p - s > 2 && s[0] == '[' && s[1] == ']')
|
||||
#else
|
||||
/* Skip leading '[]'s. should only be one set or bug somwhere else */
|
||||
if (p - s > 2 && s[0] == '[' && s[1] == ']')
|
||||
s += 2;
|
||||
/* Skip leading '<>'s. should only be one set or bug somwhere else */
|
||||
if (p - s > 2 && s[0] == '<' && s[1] == '>')
|
||||
s += 2;
|
||||
#endif
|
||||
/* Skip leading './'s. */
|
||||
while (p - s > 2 && s[0] == '.' && s[1] == '/')
|
||||
#endif
|
||||
{
|
||||
/* Skip "./" and all following slashes. */
|
||||
s += 2;
|
||||
@@ -3102,9 +3121,7 @@ parse_file_seq (char **stringp, unsigned int size, int stopmap,
|
||||
if (s == p)
|
||||
{
|
||||
/* The name was stripped to empty ("./"). */
|
||||
#if defined(VMS)
|
||||
continue;
|
||||
#elif defined(_AMIGA)
|
||||
#if defined(_AMIGA)
|
||||
/* PDS-- This cannot be right!! */
|
||||
tp[0] = '\0';
|
||||
nlen = 0;
|
||||
@@ -3167,7 +3184,7 @@ parse_file_seq (char **stringp, unsigned int size, int stopmap,
|
||||
do
|
||||
{
|
||||
const char *o = e;
|
||||
e = next_token (e);
|
||||
NEXT_TOKEN (e);
|
||||
/* Find the end of this word. We don't want to unquote and
|
||||
we don't care about quoting since we're looking for the
|
||||
last char in the word. */
|
||||
@@ -3261,7 +3278,7 @@ parse_file_seq (char **stringp, unsigned int size, int stopmap,
|
||||
switch (glob (name, GLOB_NOSORT|GLOB_ALTDIRFUNC, NULL, &gl))
|
||||
{
|
||||
case GLOB_NOSPACE:
|
||||
fatal (NILF, _("virtual memory exhausted"));
|
||||
OUT_OF_MEM();
|
||||
|
||||
case 0:
|
||||
/* Success. */
|
||||
@@ -3327,12 +3344,10 @@ parse_file_seq (char **stringp, unsigned int size, int stopmap,
|
||||
globfree (&gl);
|
||||
|
||||
#ifndef NO_ARCHIVES
|
||||
if (arname)
|
||||
free (arname);
|
||||
free (arname);
|
||||
#endif
|
||||
|
||||
if (tildep)
|
||||
free (tildep);
|
||||
free (tildep);
|
||||
}
|
||||
|
||||
*stringp = p;
|
||||
|
||||
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/>.
|
||||
282
remake.c
282
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,13 +53,18 @@ 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);
|
||||
/* 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);
|
||||
@@ -77,31 +80,22 @@ static const char *library_search (const char *lib, FILE_TIMESTAMP *mtime_ptr);
|
||||
one goal whose 'changed' member is nonzero is successfully made. */
|
||||
|
||||
enum update_status
|
||||
update_goal_chain (struct dep *goals)
|
||||
update_goal_chain (struct goaldep *goaldeps)
|
||||
{
|
||||
int t = touch_flag, q = question_flag, n = just_print_flag;
|
||||
enum update_status status = us_none;
|
||||
|
||||
/* 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 fail;
|
||||
enum update_status fail;
|
||||
|
||||
file->dontcare = g->dontcare;
|
||||
file->dontcare = ANY_SET (g->flags, RM_DONTCARE);
|
||||
|
||||
check_renamed (file);
|
||||
if (rebuilding_makefiles)
|
||||
@@ -161,14 +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 ((fail || file->updated) && status < us_question)
|
||||
{
|
||||
if (file->update_status != us_success)
|
||||
/* We updated this goal. Update STATUS and decide whether
|
||||
to stop. */
|
||||
if (file->update_status)
|
||||
{
|
||||
/* Updating failed, or -q triggered. The STATUS value
|
||||
tells our caller which. */
|
||||
@@ -228,10 +222,10 @@ update_goal_chain (struct dep *goals)
|
||||
&& file->update_status == us_success && !g->changed
|
||||
/* Never give a message under -s or -q. */
|
||||
&& !silent_flag && !question_flag)
|
||||
message (1, ((file->phony || file->cmds == 0)
|
||||
? _("Nothing to be done for '%s'.")
|
||||
: _("'%s' is up to date.")),
|
||||
file->name);
|
||||
OS (message, 1, ((file->phony || file->cmds == 0)
|
||||
? _("Nothing to be done for '%s'.")
|
||||
: _("'%s' is up to date.")),
|
||||
file->name);
|
||||
|
||||
/* This goal is finished. Remove it from the chain. */
|
||||
if (lastgoal == 0)
|
||||
@@ -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,6 +264,30 @@ update_goal_chain (struct dep *goals)
|
||||
return status;
|
||||
}
|
||||
|
||||
/* If we're rebuilding an included makefile that failed, and we care
|
||||
about errors, show an error message the first time. */
|
||||
|
||||
void
|
||||
show_goal_error (void)
|
||||
{
|
||||
struct goaldep *goal;
|
||||
|
||||
if ((goal_dep->flags & (RM_INCLUDED|RM_DONTCARE)) != RM_INCLUDED)
|
||||
return;
|
||||
|
||||
for (goal = goal_list; goal; goal = goal->next)
|
||||
if (goal_dep->file == goal->file)
|
||||
{
|
||||
if (goal->error)
|
||||
{
|
||||
OSS (error, &goal->floc, "%s: %s",
|
||||
goal->file->name, strerror ((int)goal->error));
|
||||
goal->error = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* If FILE is not up to date, execute the commands for it.
|
||||
Return 0 if successful, non-0 if unsuccessful;
|
||||
but with some flag settings, just call 'exit' if unsuccessful.
|
||||
@@ -282,11 +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)
|
||||
{
|
||||
int status = 0;
|
||||
register struct file *f;
|
||||
enum update_status status = us_success;
|
||||
struct file *f;
|
||||
|
||||
f = file->double_colon ? file->double_colon : file;
|
||||
|
||||
@@ -303,7 +321,7 @@ update_file (struct file *file, unsigned int depth)
|
||||
&& !f->dontcare && f->no_diag))
|
||||
{
|
||||
DBF (DB_VERBOSE, _("Pruning file '%s'.\n"));
|
||||
return f->command_state == cs_finished ? f->update_status : 0;
|
||||
return f->command_state == cs_finished ? f->update_status : us_success;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,26 +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
|
||||
@@ -343,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;
|
||||
@@ -373,24 +397,29 @@ complain (struct file *file)
|
||||
|
||||
if (d == 0)
|
||||
{
|
||||
const char *msg_noparent
|
||||
= _("%sNo rule to make target '%s'%s");
|
||||
const char *msg_parent
|
||||
= _("%sNo rule to make target '%s', needed by '%s'%s");
|
||||
show_goal_error ();
|
||||
|
||||
/* Didn't find any dependencies to complain about. */
|
||||
if (!keep_going_flag)
|
||||
if (file->parent)
|
||||
{
|
||||
if (file->parent == 0)
|
||||
fatal (NILF, msg_noparent, "", file->name, "");
|
||||
size_t l = strlen (file->name) + strlen (file->parent->name) + 4;
|
||||
const char *m = _("%sNo rule to make target '%s', needed by '%s'%s");
|
||||
|
||||
fatal (NILF, msg_parent, "", file->name, file->parent->name, "");
|
||||
if (!keep_going_flag)
|
||||
fatal (NILF, l, m, "", file->name, file->parent->name, "");
|
||||
|
||||
error (NILF, l, m, "*** ", file->name, file->parent->name, ".");
|
||||
}
|
||||
|
||||
if (file->parent == 0)
|
||||
error (NILF, msg_noparent, "*** ", file->name, ".");
|
||||
else
|
||||
error (NILF, msg_parent, "*** ", file->name, file->parent->name, ".");
|
||||
{
|
||||
size_t l = strlen (file->name) + 4;
|
||||
const char *m = _("%sNo rule to make target '%s'%s");
|
||||
|
||||
if (!keep_going_flag)
|
||||
fatal (NILF, l, m, "", file->name, "");
|
||||
|
||||
error (NILF, l, m, "*** ", file->name, ".");
|
||||
}
|
||||
|
||||
file->no_diag = 0;
|
||||
}
|
||||
@@ -399,12 +428,12 @@ complain (struct file *file)
|
||||
/* Consider a single 'struct file' and update it as appropriate.
|
||||
Return 0 on success, or non-0 on failure. */
|
||||
|
||||
static int
|
||||
static enum update_status
|
||||
update_file_1 (struct file *file, unsigned int depth)
|
||||
{
|
||||
enum update_status dep_status = us_success;
|
||||
FILE_TIMESTAMP this_mtime;
|
||||
int noexist, must_make, deps_changed;
|
||||
int dep_status = 0;
|
||||
struct file *ofile;
|
||||
struct dep *d, *ad;
|
||||
struct dep amake;
|
||||
@@ -478,8 +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;
|
||||
}
|
||||
|
||||
@@ -521,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;
|
||||
@@ -532,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. */
|
||||
@@ -555,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)
|
||||
@@ -583,8 +616,8 @@ update_file_1 (struct file *file, unsigned int depth)
|
||||
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));
|
||||
|
||||
@@ -601,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);
|
||||
@@ -617,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)
|
||||
@@ -664,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 = us_failed;
|
||||
/* I'm not sure if we can't just assign dep_status... */
|
||||
file->update_status = dep_status == us_none ? us_failed : dep_status;
|
||||
notice_finished_file (file);
|
||||
|
||||
--depth;
|
||||
@@ -675,8 +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;
|
||||
}
|
||||
@@ -981,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);
|
||||
@@ -1051,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);
|
||||
}
|
||||
@@ -1060,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;
|
||||
@@ -1083,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
|
||||
@@ -1122,7 +1162,7 @@ static enum update_status
|
||||
touch_file (struct file *file)
|
||||
{
|
||||
if (!silent_flag)
|
||||
message (0, "touch %s", file->name);
|
||||
OS (message, 0, "touch %s", file->name);
|
||||
|
||||
/* Print-only (-n) takes precedence over touch (-t). */
|
||||
if (just_print_flag)
|
||||
@@ -1134,8 +1174,9 @@ touch_file (struct file *file)
|
||||
else
|
||||
#endif
|
||||
{
|
||||
int fd = open (file->name, O_RDWR | O_CREAT, 0666);
|
||||
int fd;
|
||||
|
||||
EINTRLOOP (fd, open (file->name, O_RDWR | O_CREAT, 0666));
|
||||
if (fd < 0)
|
||||
TOUCH_ERROR ("touch: open: ");
|
||||
else
|
||||
@@ -1148,18 +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: ");
|
||||
}
|
||||
@@ -1225,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. */
|
||||
|
||||
@@ -1301,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. */
|
||||
@@ -1309,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);
|
||||
@@ -1369,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)
|
||||
@@ -1382,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
|
||||
@@ -1405,7 +1467,8 @@ f_mtime (struct file *file, int search)
|
||||
&& !file->tried_implicit && file->intermediate)
|
||||
file->intermediate = 0;
|
||||
|
||||
file->last_mtime = mtime;
|
||||
if (file->updated == propagate_timestamp)
|
||||
file->last_mtime = mtime;
|
||||
file = file->prev;
|
||||
}
|
||||
while (file != 0);
|
||||
@@ -1520,7 +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",
|
||||
@@ -1550,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)"));
|
||||
|
||||
@@ -1580,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
|
||||
@@ -151,7 +151,7 @@ start_remote_job (char **argv, char **envp, int stdin_fd,
|
||||
retsock = Rpc_UdpCreate (True, 0);
|
||||
if (retsock < 0)
|
||||
{
|
||||
error (NILF, "exporting: Couldn't create return socket.");
|
||||
O (error, NILF, "exporting: Couldn't create return socket.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -192,35 +192,37 @@ start_remote_job (char **argv, char **envp, int stdin_fd,
|
||||
|
||||
host = gethostbyaddr ((char *)&permit.addr, sizeof(permit.addr), AF_INET);
|
||||
|
||||
if (status != RPC_SUCCESS)
|
||||
{
|
||||
(void) close (retsock);
|
||||
(void) close (sock);
|
||||
error (NILF, "exporting to %s: %s",
|
||||
host ? host->h_name : inet_ntoa (permit.addr),
|
||||
Rpc_ErrorMessage (status));
|
||||
return 1;
|
||||
}
|
||||
else if (msg[0] != 'O' || msg[1] != 'k' || msg[2] != '\0')
|
||||
{
|
||||
(void) close (retsock);
|
||||
(void) close (sock);
|
||||
error (NILF, "exporting to %s: %s",
|
||||
host ? host->h_name : inet_ntoa (permit.addr),
|
||||
msg);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
error (NILF, "*** exported to %s (id %u)",
|
||||
host ? host->h_name : inet_ntoa (permit.addr),
|
||||
permit.id);
|
||||
}
|
||||
{
|
||||
const char *hnm = host ? host->h_name : inet_ntoa (permit.addr);
|
||||
size_t hlen = strlen (hnm);
|
||||
|
||||
fflush (stdout);
|
||||
fflush (stderr);
|
||||
if (status != RPC_SUCCESS)
|
||||
{
|
||||
const char *err = Rpc_ErrorMessage (status);
|
||||
(void) close (retsock);
|
||||
(void) close (sock);
|
||||
error (NILF, hlen + strlen (err),
|
||||
"exporting to %s: %s", hnm, err);
|
||||
return 1;
|
||||
}
|
||||
else if (msg[0] != 'O' || msg[1] != 'k' || msg[2] != '\0')
|
||||
{
|
||||
(void) close (retsock);
|
||||
(void) close (sock);
|
||||
error (NILF, hlen + strlen (msg), "exporting to %s: %s", hnm, msg);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
error (NILF, hlen + INTSTR_LENGTH,
|
||||
"*** exported to %s (id %u)", hnm, permit.id);
|
||||
}
|
||||
|
||||
pid = fork ();
|
||||
fflush (stdout);
|
||||
fflush (stderr);
|
||||
}
|
||||
|
||||
pid = vfork ();
|
||||
if (pid < 0)
|
||||
{
|
||||
/* The fork failed! */
|
||||
|
||||
@@ -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_SIMPLE_SEQ (&ptr, struct dep);
|
||||
r->deps = PARSE_SIMPLE_SEQ ((char **)&ptr, struct dep);
|
||||
|
||||
if (new_pattern_rule (r, 0))
|
||||
{
|
||||
@@ -381,6 +380,7 @@ install_pattern_rule (struct pspec *p, int terminal)
|
||||
r->cmds = xmalloc (sizeof (struct commands));
|
||||
r->cmds->fileinfo.filenm = 0;
|
||||
r->cmds->fileinfo.lineno = 0;
|
||||
r->cmds->fileinfo.offset = 0;
|
||||
/* These will all be string literals, but we malloc space for them
|
||||
anyway because somebody might want to free them later. */
|
||||
r->cmds->commands = xstrdup (p->commands);
|
||||
@@ -528,7 +528,7 @@ print_rule_data_base (void)
|
||||
/* This can happen if a fatal error was detected while reading the
|
||||
makefiles and thus count_implicit_rule_limits wasn't called yet. */
|
||||
if (num_pattern_rules != 0)
|
||||
fatal (NILF, _("BUG: num_pattern_rules is wrong! %u != %u"),
|
||||
num_pattern_rules, rules);
|
||||
ONN (fatal, NILF, _("BUG: num_pattern_rules is wrong! %u != %u"),
|
||||
num_pattern_rules, rules);
|
||||
}
|
||||
}
|
||||
|
||||
5
rule.h
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
|
||||
|
||||
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,82 @@
|
||||
2013-10-09 Paul Smith <psmith@gnu.org>
|
||||
|
||||
* scripts/features/patspecific_vars: Typo fixes.
|
||||
|
||||
2013-10-05 Paul Smith <psmith@gnu.org>
|
||||
|
||||
* test_driver.pl (run_all_tests): Rewrite to be more clear.
|
||||
* scripts/features/jobserver: Avoid using $ENV{HOME} as it doesn't
|
||||
exist everywhere.
|
||||
* scripts/features/default_names: End with 1;
|
||||
|
||||
* scripts/features/loadapi: Use new calling signatures. Verify
|
||||
the NOEXPAND flag works. Test with all valid function name
|
||||
characters.
|
||||
|
||||
2013-09-29 Paul Smith <psmith@gnu.org>
|
||||
|
||||
* scripts/variables/SHELL: Solaris /bin/sh can't handle options in
|
||||
multiple words; skip that test.
|
||||
* scripts/targets/ONESHELL: Ditto.
|
||||
|
||||
* scripts/variables/GNUMAKEFLAGS: Verify that GNUMAKEFLAGS is
|
||||
cleared and options are not duplicated.
|
||||
|
||||
2013-09-23 Paul Smith <psmith@gnu.org>
|
||||
|
||||
* scripts/options/print-directory: Rename dash-w to
|
||||
print-directory to avoid conflicts with dash-W on case-insensitive
|
||||
filesystems.
|
||||
|
||||
2013-09-22 Paul Smith <psmith@gnu.org>
|
||||
|
||||
* scripts/features/se_implicit: Verify that order-only tokens
|
||||
inside second expansion are parsed correctly.
|
||||
Test for Savannah bug #31155.
|
||||
|
||||
* run_make_tests.pl (set_more_defaults): If we can't find
|
||||
gnumake.h based on the make program we might be running from a
|
||||
remote build directory. Parse the Makefile for the right path.
|
||||
|
||||
Fix some test issues on Solaris.
|
||||
|
||||
* scripts/features/archives: Determine what output ar gives when
|
||||
adding and replacing objects and compare with that.
|
||||
* scripts/features/escape: Solaris /bin/sh doesn't properly handle
|
||||
backslashes inside single quotes, so don't rely on it.
|
||||
* scripts/features/output-sync: false(1) gives different exit
|
||||
codes on different systems; use "exit 1" instead.
|
||||
* scripts/features/parallelism: Increase the timeout for slower systems.
|
||||
|
||||
2013-09-21 Paul Smith <psmith@gnu.org>
|
||||
|
||||
* scripts/features/archives: Some versions of ar (MacOSX) generate
|
||||
different output when creating archives. Run it and verify the
|
||||
real output.
|
||||
* scripts/features/default_names: MacOSX is, like Windows,
|
||||
case-preserving / case-insensitive. Redo the test to avoid
|
||||
checking for "UNIX".
|
||||
* test_driver.pl (attach_default_output): Don't dup stdout into
|
||||
stderr. Reported by Denis Excoffier <bug-tar@Denis-Excoffier.org>
|
||||
|
||||
* scripts/features/se_explicit: Fix a test that behaves
|
||||
differently with/without archive capability enabled.
|
||||
* scripts/features/output-sync: Don't test output-sync if it's not
|
||||
enabled. We also skip it if parallelism is not enabled, although
|
||||
strictly speaking some of the output-sync tests are valid even
|
||||
without parallelism.
|
||||
* scripts/features/jobserver: Move some tests that require the
|
||||
jobserver from features/parallelism to a separate suite. Only run
|
||||
this if jobserver mode is enabled.
|
||||
|
||||
* scripts/features/output-sync: Test shell functions writing to
|
||||
stderr in recipes: ensure it's captured via output-sync. Test
|
||||
output generated while reading makefiles and make sure it's
|
||||
captured via output-sync. Make sure that fatal errors dump the
|
||||
output so it's not lost.
|
||||
|
||||
* scripts/options/dash-w: Add a test for -w flag.
|
||||
|
||||
2013-09-15 Paul Smith <psmith@gnu.org>
|
||||
|
||||
* scripts/misc/fopen-fail: Check for failure on infinite recursion.
|
||||
@@ -1334,7 +1413,7 @@
|
||||
ChangeLog file for the test suite created.
|
||||
|
||||
|
||||
Copyright (C) 1992-2013 Free Software Foundation, Inc.
|
||||
Copyright (C) 1992-2016 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
@@ -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
|
||||
|
||||
272
tests/run_make_tests.com
Executable file
272
tests/run_make_tests.com
Executable file
@@ -0,0 +1,272 @@
|
||||
$! Test_make.com
|
||||
$!
|
||||
$! This is a wrapper for the GNU make perl test programs on VMS.
|
||||
$!
|
||||
$! Parameter "-help" for description on how to use described below.
|
||||
$!
|
||||
$! Copyright (C) 2014-2016 Free Software Foundation, Inc.
|
||||
$! This file is part of GNU Make.
|
||||
$!
|
||||
$! GNU Make is free software; you can redistribute it and/or modify it under
|
||||
$! the terms of the GNU General Public License as published by the Free Software
|
||||
$! Foundation; either version 3 of the License, or (at your option) any later
|
||||
$! version.
|
||||
$!
|
||||
$! GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
$! WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
$! FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
$! details.
|
||||
$!
|
||||
$! You should have received a copy of the GNU General Public License along with
|
||||
$! this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
$!
|
||||
$!
|
||||
$! Allow more than 8 paramters with using commas as a delimiter.
|
||||
$!
|
||||
$ params = "''p1',''p2',''p3',''p4',''p5',''p6',''p7',''p8'"
|
||||
$!
|
||||
$ test_flags = ",verbose,detail,keep,usage,help,debug,"
|
||||
$ test_flags_len = f$length(test_flags)
|
||||
$ verbose_flag = ""
|
||||
$ detail_flag = ""
|
||||
$ keep_flag = ""
|
||||
$ usage_flag = ""
|
||||
$ help_flag = ""
|
||||
$ debug_flag = ""
|
||||
$!
|
||||
$ ignored_options = "profile,make,srcdir,valgrind,memcheck,massif,"
|
||||
$ ignored_option_len = f$length(ignored_options)
|
||||
$!
|
||||
$ testname = ""
|
||||
$ make :== $bin:make.exe"
|
||||
$!
|
||||
$ i = 0
|
||||
$param_loop:
|
||||
$ param = f$element(i, ",", params)
|
||||
$ i = i + 1
|
||||
$ if param .eqs. "" then goto param_loop
|
||||
$ if param .eqs. "," then goto param_loop_end
|
||||
$ param_len = f$length(param)
|
||||
$ if f$locate("/", param) .lt. param_len
|
||||
$ then
|
||||
$ if testname .nes. ""
|
||||
$ then
|
||||
$ write sys$output "Only the last test name specified will be run!"
|
||||
$ endif
|
||||
$ testname = param
|
||||
$ goto param_loop
|
||||
$ endif
|
||||
$ lc_param = f$edit(param,"LOWERCASE") - "-"
|
||||
$ if f$locate(",''lc_param',", ignored_options) .lt. ignored_option_len
|
||||
$ then
|
||||
$ write sys$output "parameter ''param' is ignored on VMS for now."
|
||||
$ goto param_loop
|
||||
$ endif
|
||||
$ if f$locate(",''lc_param',", test_flags) .lt. test_flags_len
|
||||
$ then
|
||||
$ 'lc_param'_flag = "-" + lc_param
|
||||
$ goto param_loop
|
||||
$ endif
|
||||
$ write sys$output "parameter ''param' is not known to VMS."
|
||||
$ goto param_loop
|
||||
$!
|
||||
$param_loop_end:
|
||||
$!
|
||||
$no_gnv = 1
|
||||
$no_perl = 1
|
||||
$!
|
||||
$! Find GNV 2.1.3 + manditory updates
|
||||
$! If properly updated, the GNV$GNU logical name is present.
|
||||
$! Updated GNV utilities have a gnv$ prefix on them.
|
||||
$ gnv_root = f$trnlnm("GNV$GNU", "LNM$SYSTEM_TABLE")
|
||||
$ if gnv_root .nes. ""
|
||||
$ then
|
||||
$ no_gnv = 0
|
||||
$ ! Check for update ar utility.
|
||||
$ new_ar = "gnv$gnu:[usr.bin]gnv$ar.exe"
|
||||
$ if f$search(new_ar) .nes. ""
|
||||
$ then
|
||||
$ ! See if a new port of ar exists.
|
||||
$ ar :== $'new_ar'
|
||||
$ else
|
||||
$ ! Fall back to legacy GNV AR wrapper.
|
||||
$ old_ar = "gnv$gnu:[bin]ar.exe"
|
||||
$ if f$search(old_ar) .nes. ""
|
||||
$ then
|
||||
$ ar :== $'old_ar'
|
||||
$ else
|
||||
$ no_gnv = 1
|
||||
$ endif
|
||||
$ endif
|
||||
$ ! Check for updated bash
|
||||
$ if no_gnv .eq. 0
|
||||
$ then
|
||||
$ new_bash = "gnv$gnu:[bin]gnv$bash.exe"
|
||||
$ if f$search(new_bash) .nes. ""
|
||||
$ then
|
||||
$ bash :== $'new_bash'
|
||||
$ sh :== $'new_bash'
|
||||
$ else
|
||||
$ no_gnv = 1
|
||||
$ endif
|
||||
$ endif
|
||||
$ ! Check for updated coreutils
|
||||
$ if no_gnv .eq. 0
|
||||
$ then
|
||||
$ new_cat = "gnv$gnu:[bin]gnv$cat.exe"
|
||||
$ if f$search(new_cat) .nes. ""
|
||||
$ then
|
||||
$ cat :== $'new_cat'
|
||||
$ cp :== $gnv$gnu:[bin]gnv$cp.exe
|
||||
$ echo :== $gnv$gnu:[bin]gnv$echo.exe
|
||||
$ false :== $gnv$gnu:[bin]gnv$false.exe
|
||||
$ true :== $gnv$gnu:[bin]gnv$true.exe
|
||||
$ touch :== $gnv$gnu:[bin]gnv$touch.exe
|
||||
$ mkdir :== $gnv$gnu:[bin]gnv$mkdir.exe
|
||||
$ rm :== $gnv$gnu:[bin]gnv$rm.exe
|
||||
$ sleep :== $gnv$gnu:[bin]gnv$sleep.exe
|
||||
$ else
|
||||
$ no_gnv = 1
|
||||
$ endif
|
||||
$ endif
|
||||
$ ! Check for updated diff utility.
|
||||
$ if no_gnv .eq. 0
|
||||
$ then
|
||||
$ new_diff = "gnv$gnu:[usr.bin]gnv$diff.exe"
|
||||
$ if f$search(new_diff) .nes. ""
|
||||
$ then
|
||||
$ ! See if a new port of diff exists.
|
||||
$ diff :== $'new_diff'
|
||||
$ else
|
||||
$ ! Fall back to legacy GNV diff
|
||||
$ old_diff = "gnv$gnu:[bin]diff.exe"
|
||||
$ if f$search(old_diff) .nes. ""
|
||||
$ then
|
||||
$ diff :== $'old_diff'
|
||||
$ else
|
||||
$ no_gnv = 1
|
||||
$ endif
|
||||
$ endif
|
||||
$ endif
|
||||
$ endif
|
||||
$!
|
||||
$if no_gnv
|
||||
$then
|
||||
$ write sys$output "Could not find an up to date GNV installed!"
|
||||
$ help_flag = 1
|
||||
$endif
|
||||
$!
|
||||
$! Find perl 5.18.1 or later.
|
||||
$!
|
||||
$! look in perl_root:[000000]perl_setup.com
|
||||
$ perl_root = f$trnlnm("perl_root")
|
||||
$ ! This works with known perl installed from PCSI kits.
|
||||
$ if perl_root .nes. ""
|
||||
$ then
|
||||
$ perl_ver = f$element(1, ".", perl_root)
|
||||
$ if f$locate("-", perl_ver) .lt. f$length(perl_ver)
|
||||
$ then
|
||||
$ no_perl = 0
|
||||
$ endif
|
||||
$ endif
|
||||
$ if no_perl
|
||||
$ then
|
||||
$! look for sys$common:[perl-*]perl_setup.com
|
||||
$ perl_setup = f$search("sys$common:[perl-*]perl_setup.com")
|
||||
$ if perl_setup .eqs. ""
|
||||
$ then
|
||||
$ if gnv_root .nes. ""
|
||||
$ then
|
||||
$ gnv_device = f$parse(gnv_root,,,"DEVICE")
|
||||
$ perl_templ = "[vms$common.perl-*]perl_setup.com"
|
||||
$ perl_search = f$parse(perl_templ, gnv_device)
|
||||
$ perl_setup = f$search(perl_search)
|
||||
$ endif
|
||||
$ endif
|
||||
$ if perl_setup .nes. ""
|
||||
$ then
|
||||
$ @'perl_setup'
|
||||
$ no_perl = 0
|
||||
$ endif
|
||||
$ endif
|
||||
$!
|
||||
$ if no_perl
|
||||
$ then
|
||||
$ write sys$output "Could not find an up to date Perl installed!"
|
||||
$ help_flag = "-help"
|
||||
$ endif
|
||||
$!
|
||||
$!
|
||||
$ if help_flag .nes. ""
|
||||
$ then
|
||||
$ type sys$input
|
||||
$DECK
|
||||
This is a test script wrapper for the run_make_tests.pl script.
|
||||
|
||||
This wrapper makes sure that the DCL symbols and logical names needed to
|
||||
run the perl script are in place.
|
||||
|
||||
The test wrapper currently requires that the DCL symbols be global symbols.
|
||||
Those symbols will be left behind after the procedure is run.
|
||||
|
||||
The PERL_ROOT will be set to a compatible perl if such a perl is found and
|
||||
is not the default PERL_ROOT:. This setting will persist after the test.
|
||||
|
||||
This wrapper should be run with the default set to the base directory
|
||||
of the make source.
|
||||
|
||||
The HELP parameter will bring up this text and then run the help script
|
||||
for the Perl wrapper. Not all options for the perl script have been
|
||||
implemented, such as valgrind or specifying the make path or source path.
|
||||
|
||||
Running the wrapper script requires:
|
||||
Perl 5.18 or later.
|
||||
PCSI kits available from http://sourceforge.net/projects/vmsperlkit/files/
|
||||
|
||||
GNV 2.1.3 or later. GNV 3.0.1 has not tested with this script.
|
||||
Bash 4.2.47 or later.
|
||||
Coreutils 8.21 or later.
|
||||
http://sourceforge.net/projects/gnv/files/
|
||||
Read before installing:
|
||||
http://sourceforge.net/p/gnv/wiki/InstallingGNVPackages/
|
||||
As updates for other GNV components get posted, those updates should
|
||||
be used.
|
||||
|
||||
$EOD
|
||||
$ endif
|
||||
$!
|
||||
$ if no_gnv .or. no_perl then exit 44
|
||||
$!
|
||||
$!
|
||||
$ default = f$environment("DEFAULT")
|
||||
$ default_dev = f$element(0, ":", default) + ":"
|
||||
$ this = f$environment("PROCEDURE")
|
||||
$ on error then goto all_error
|
||||
$ set default 'default_dev''f$parse(this,,,"DIRECTORY")'
|
||||
$!
|
||||
$! Need to make sure that the config-flags.pm exists.
|
||||
$ if f$search("config-flags.pm") .eqs. ""
|
||||
$ then
|
||||
$ @config_flags_pm.com
|
||||
$ endif
|
||||
$ define/user bin 'default_dev'[-],gnv$gnu:[bin]
|
||||
$ define/user decc$filename_unix_noversion enable
|
||||
$ define/user decc$filename_unix_report enable
|
||||
$ define/user decc$readdir_dropdotnotype enable
|
||||
$ flags = ""
|
||||
$ if verbose_flag .nes. "" then flags = verbose_flag
|
||||
$ if detail_flag .nes. "" then flags = flags + " " + detail_flag
|
||||
$ if keep_flag .nes. "" then flags = flags + " " + keep_flag
|
||||
$ if usage_flag .nes. "" then flags = flags + " " + usage_flag
|
||||
$ if help_flag .nes. "" then flags = flags + " " + help_flag
|
||||
$ if debug_flag .nes. "" then flags = flags + " " + debug_flag
|
||||
$ flags = f$edit(flags, "TRIM, COMPRESS")
|
||||
$ if testname .nes. ""
|
||||
$ then
|
||||
$ perl run_make_tests.pl "''testname'" 'flags'
|
||||
$ else
|
||||
$ perl run_make_tests.pl 'flags'
|
||||
$ endif
|
||||
$all_error:
|
||||
$ set default 'default'
|
||||
$!
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user