mirror of
https://github.com/mirror/make.git
synced 2026-08-21 09:23:27 +08:00
Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 |
152
ChangeLog
152
ChangeLog
@@ -1,3 +1,155 @@
|
||||
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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -82,7 +82,7 @@ EXTRA_DIST = README build.sh.in $(man_MANS) \
|
||||
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 \
|
||||
README.VMS makefile.vms makefile.com config.h-vms \
|
||||
vmsdir.h vmsfunctions.c vmsify.c \
|
||||
gmk-default.scm gmk-default.h
|
||||
|
||||
|
||||
32
NEWS
32
NEWS
@@ -1,6 +1,6 @@
|
||||
GNU make NEWS -*-indented-text-*-
|
||||
History of user-visible changes.
|
||||
16 Sep 2013
|
||||
1 Oct 2013
|
||||
|
||||
See the end of this file for copyrights and conditions.
|
||||
|
||||
@@ -9,7 +9,7 @@ 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 3.99.93
|
||||
|
||||
A complete list of bugs fixed in this version is available here:
|
||||
|
||||
@@ -23,6 +23,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 +55,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 +68,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 +78,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 +87,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.
|
||||
@@ -341,7 +349,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
|
||||
@@ -491,7 +499,7 @@ 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.
|
||||
|
||||
Version 3.78 (22 Sep 1999)
|
||||
|
||||
|
||||
@@ -1,23 +1,33 @@
|
||||
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).
|
||||
This version of GNU make has been tested on
|
||||
OpenVMS V8.3 (Alpha) and V8.4 (Integrity).
|
||||
|
||||
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
|
||||
$ copy make.exe 1st-make.exe
|
||||
Use the 1st version to generate a 2nd version
|
||||
$ mc sys$disk:[]1st-make clean ! ignore any file not found messages
|
||||
$ mc sys$disk:[]1st-make
|
||||
Verify your 2nd version
|
||||
$ rena make.exe 2nd-make.exe
|
||||
Verify your 2nd version
|
||||
$ copy make.exe 2nd-make.exe
|
||||
$ mc sys$disk:[]2nd-make clean
|
||||
$ mc sys$disk:[]2nd-make
|
||||
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.
|
||||
|
||||
Changes since GNU make 3.82
|
||||
---------------------------
|
||||
|
||||
Changes (3.81.90)
|
||||
Fix build problems.
|
||||
|
||||
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 VMS does not support running multiple commands simultaneously.
|
||||
|
||||
Changes for GNU make 3.82
|
||||
|
||||
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
|
||||
@@ -34,30 +44,6 @@ 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
|
||||
@@ -78,117 +64,24 @@ 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
|
||||
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.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
Changes (3.80)
|
||||
Changes for GNU make 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.
|
||||
|
||||
@@ -7,7 +7,7 @@ It builds with the MinGW port of GCC (tested with GCC 3.4.2).
|
||||
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.
|
||||
|
||||
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
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
24
TODO.private
24
TODO.private
@@ -99,30 +99,6 @@ 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.
|
||||
|
||||
@@ -17,8 +17,8 @@ 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"
|
||||
|
||||
@@ -321,6 +321,9 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
/* 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
|
||||
|
||||
|
||||
@@ -411,5 +411,8 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
#define alloca(n) __ALLOCA(n)
|
||||
#endif
|
||||
|
||||
/* Output sync sypport */
|
||||
#define NO_OUTPUT_SYNC
|
||||
|
||||
/* Build host information. */
|
||||
#define MAKE_HOST "VMS"
|
||||
|
||||
@@ -523,5 +523,3 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
#ifdef HAVE_CYGWIN_SHELL
|
||||
#undef BATCH_MODE_ONLY_SHELL
|
||||
#endif
|
||||
|
||||
#define OUTPUT_SYNC
|
||||
|
||||
@@ -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%"
|
||||
|
||||
47
configure.ac
47
configure.ac
@@ -16,7 +16,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/>.
|
||||
|
||||
AC_INIT([GNU make],[3.99.91],[bug-make@gnu.org])
|
||||
AC_INIT([GNU make],[3.99.93],[bug-make@gnu.org])
|
||||
|
||||
AC_PREREQ([2.62])
|
||||
|
||||
@@ -62,7 +62,7 @@ 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])
|
||||
|
||||
AM_PROG_CC_C_O
|
||||
AC_C_CONST
|
||||
@@ -90,12 +90,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 +103,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 +117,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])
|
||||
|
||||
# We need to check declarations, not just existence, because on Tru64 this
|
||||
# function is not declared without special flags, which themselves cause
|
||||
@@ -181,11 +181,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.])
|
||||
@@ -244,7 +244,7 @@ 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])],
|
||||
[enable remote jobs via Customs--see README.customs])],
|
||||
[ AS_CASE([$withval], [n|no], [:],
|
||||
[make_cppflags="$CPPFLAGS"
|
||||
AS_CASE([$withval],
|
||||
@@ -254,7 +254,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 +268,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.
|
||||
@@ -368,7 +368,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 +428,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])
|
||||
])
|
||||
|
||||
|
||||
1
dir.c
1
dir.c
@@ -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
|
||||
|
||||
@@ -4808,10 +4808,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
|
||||
@@ -10910,7 +10917,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 +10986,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:
|
||||
|
||||
|
||||
2
file.c
2
file.c
@@ -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"
|
||||
|
||||
27
function.c
27
function.c
@@ -1620,7 +1620,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 +1636,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);
|
||||
@@ -1652,15 +1652,15 @@ func_shell_base (char *o, char **argv, int trim_newlines)
|
||||
#endif
|
||||
|
||||
/* 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;
|
||||
@@ -1678,6 +1678,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)
|
||||
@@ -1710,7 +1713,7 @@ func_shell_base (char *o, char **argv, int trim_newlines)
|
||||
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);
|
||||
pid = child_execute_job (FD_STDIN, pipedes[1], errfd, command_argv, envp);
|
||||
if (pid < 0)
|
||||
perror_with_name (error_prefix, "spawn");
|
||||
# else /* ! __EMX__ */
|
||||
@@ -1719,12 +1722,12 @@ func_shell_base (char *o, char **argv, int trim_newlines)
|
||||
perror_with_name (error_prefix, "fork");
|
||||
else if (pid == 0)
|
||||
{
|
||||
#ifdef SET_STACK_SIZE
|
||||
# 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);
|
||||
# endif
|
||||
child_execute_job (FD_STDIN, pipedes[1], errfd, command_argv, envp);
|
||||
}
|
||||
else
|
||||
# endif
|
||||
|
||||
10
gnumake.h
10
gnumake.h
@@ -38,17 +38,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
|
||||
@@ -65,7 +65,7 @@ char * GMK_EXPORT gmk_expand (const char *str);
|
||||
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.
|
||||
*/
|
||||
void GMK_EXPORT gmk_add_function (const char *name,
|
||||
GMK_EXPORT void gmk_add_function (const char *name,
|
||||
char *(*func)(const char *nm,
|
||||
int argc, char **argv),
|
||||
int min_args, int max_args, int expand_args);
|
||||
|
||||
29
guile.c
29
guile.c
@@ -18,11 +18,22 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
#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 +82,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 +110,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)
|
||||
{
|
||||
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]);
|
||||
|
||||
@@ -119,9 +139,6 @@ func_guile (const char *funcname UNUSED, int argc UNUSED, char **argv)
|
||||
int
|
||||
guile_gmake_setup (const gmk_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);
|
||||
|
||||
|
||||
39
implicit.c
39
implicit.c
@@ -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
|
||||
|
||||
157
job.c
157
job.c
@@ -894,7 +894,7 @@ reap_children (int block, int err)
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef OUTPUT_SYNC
|
||||
#ifndef NO_OUTPUT_SYNC
|
||||
/* If we're sync'ing per line, write the previous line's
|
||||
output before starting the next one. */
|
||||
if (output_sync == OUTPUT_SYNC_LINE)
|
||||
@@ -930,10 +930,10 @@ reap_children (int block, int err)
|
||||
|
||||
/* When we get here, all the commands for c->file are finished. */
|
||||
|
||||
#ifdef OUTPUT_SYNC
|
||||
#ifndef NO_OUTPUT_SYNC
|
||||
/* Synchronize any remaining parallel output. */
|
||||
output_dump (&c->output);
|
||||
#endif /* OUTPUT_SYNC */
|
||||
#endif
|
||||
|
||||
/* At this point c->file->update_status is success or failed. But
|
||||
c->file->command_state is still cs_running if all the commands
|
||||
@@ -1267,12 +1267,12 @@ start_job_command (struct child *child)
|
||||
|
||||
OUTPUT_SET (&child->output);
|
||||
|
||||
#ifdef OUTPUT_SYNC
|
||||
#ifndef NO_OUTPUT_SYNC
|
||||
if (! child->output.syncout)
|
||||
/* We don't want to sync this command: to avoid misordered
|
||||
output ensure any already-synced content is written. */
|
||||
output_dump (&child->output);
|
||||
#endif /* OUTPUT_SYNC */
|
||||
#endif
|
||||
|
||||
/* Print the command if appropriate. */
|
||||
if (just_print_flag || trace_flag
|
||||
@@ -1438,7 +1438,8 @@ start_job_command (struct child *child)
|
||||
CLOSE_ON_EXEC (job_rfd);
|
||||
|
||||
/* Never use fork()/exec() here! Use spawn() instead in exec_command() */
|
||||
child->pid = child_execute_job (child->good_stdin ? 0 : bad_stdin, 1,
|
||||
child->pid = child_execute_job (child->good_stdin ? FD_STDIN : bad_stdin,
|
||||
FD_STDOUT, FD_STDERR,
|
||||
argv, child->environment);
|
||||
if (child->pid < 0)
|
||||
{
|
||||
@@ -1463,6 +1464,9 @@ start_job_command (struct child *child)
|
||||
environ = parent_environ; /* Restore value child may have clobbered. */
|
||||
if (child->pid == 0)
|
||||
{
|
||||
int outfd = FD_STDOUT;
|
||||
int errfd = FD_STDERR;
|
||||
|
||||
/* We are the child side. */
|
||||
unblock_sigs ();
|
||||
|
||||
@@ -1482,26 +1486,17 @@ start_job_command (struct child *child)
|
||||
setrlimit (RLIMIT_STACK, &stack_limit);
|
||||
#endif
|
||||
|
||||
#ifdef OUTPUT_SYNC
|
||||
/* Divert child output if output_sync in use. Don't capture
|
||||
recursive make output unless we are synchronizing "make" mode. */
|
||||
/* Divert child output if output_sync in use. */
|
||||
if (child->output.syncout)
|
||||
{
|
||||
int outfd = fileno (stdout);
|
||||
int errfd = fileno (stderr);
|
||||
|
||||
if ((child->output.out >= 0
|
||||
&& (close (outfd) == -1
|
||||
|| dup2 (child->output.out, outfd) == -1))
|
||||
|| (child->output.err >= 0
|
||||
&& (close (errfd) == -1
|
||||
|| dup2 (child->output.err, errfd) == -1)))
|
||||
perror_with_name ("output-sync: ", "dup2()");
|
||||
if (child->output.out >= 0)
|
||||
outfd = child->output.out;
|
||||
if (child->output.err >= 0)
|
||||
errfd = child->output.err;
|
||||
}
|
||||
#endif /* OUTPUT_SYNC */
|
||||
|
||||
child_execute_job (child->good_stdin ? 0 : bad_stdin, 1,
|
||||
argv, child->environment);
|
||||
child_execute_job (child->good_stdin ? FD_STDIN : bad_stdin,
|
||||
outfd, errfd, argv, child->environment);
|
||||
}
|
||||
else if (child->pid < 0)
|
||||
{
|
||||
@@ -1597,7 +1592,7 @@ start_job_command (struct child *child)
|
||||
/* make sure CreateProcess() has Path it needs */
|
||||
sync_Path_environment ();
|
||||
|
||||
#ifdef OUTPUT_SYNC
|
||||
#ifndef NO_OUTPUT_SYNC
|
||||
/* Divert child output if output_sync in use. Don't capture
|
||||
recursive make output unless we are synchronizing "make" mode. */
|
||||
if (child->output.syncout)
|
||||
@@ -2185,59 +2180,82 @@ start_waiting_jobs (void)
|
||||
/* EMX: Start a child process. This function returns the new pid. */
|
||||
# if defined __EMX__
|
||||
int
|
||||
child_execute_job (int stdin_fd, int stdout_fd, char **argv, char **envp)
|
||||
child_execute_job (int stdin_fd, int stdout_fd, int stderr_fd,
|
||||
char **argv, char **envp)
|
||||
{
|
||||
int pid;
|
||||
/* stdin_fd == 0 means: nothing to do for stdin;
|
||||
stdout_fd == 1 means: nothing to do for stdout */
|
||||
int save_stdin = (stdin_fd != 0) ? dup (0) : 0;
|
||||
int save_stdout = (stdout_fd != 1) ? dup (1): 1;
|
||||
int save_stdin = -1;
|
||||
int save_stdout = -1;
|
||||
int save_stderr = -1;
|
||||
|
||||
/* < 0 only if dup() failed */
|
||||
if (save_stdin < 0)
|
||||
fatal (NILF, _("no more file handles: could not duplicate stdin\n"));
|
||||
if (save_stdout < 0)
|
||||
fatal (NILF, _("no more file handles: could not duplicate stdout\n"));
|
||||
/* For each FD which needs to be redirected first make a dup of the standard
|
||||
FD to save and mark it close on exec so our child won't see it. Then
|
||||
dup2() the standard FD to the redirect FD, and also mark the redirect FD
|
||||
as close on exec. */
|
||||
if (stdin_fd != FD_STDIN)
|
||||
{
|
||||
save_stdin = dup (FD_STDIN);
|
||||
if (save_stdin < 0)
|
||||
fatal (NILF, _("no more file handles: could not duplicate stdin\n"));
|
||||
CLOSE_ON_EXEC (save_stdin);
|
||||
|
||||
/* Close unnecessary file handles for the child. */
|
||||
if (save_stdin != 0)
|
||||
CLOSE_ON_EXEC (save_stdin);
|
||||
if (save_stdout != 1)
|
||||
CLOSE_ON_EXEC (save_stdout);
|
||||
dup2 (stdin_fd, FD_STDIN);
|
||||
CLOSE_ON_EXEC (stdin_fd);
|
||||
}
|
||||
|
||||
/* Connect the pipes to the child process. */
|
||||
if (stdin_fd != 0)
|
||||
(void) dup2 (stdin_fd, 0);
|
||||
if (stdout_fd != 1)
|
||||
(void) dup2 (stdout_fd, 1);
|
||||
if (stdout_fd != FD_STDOUT)
|
||||
{
|
||||
save_stdout = dup (FD_STDOUT);
|
||||
if (save_stdout < 0)
|
||||
fatal (NILF, _("no more file handles: could not duplicate stdout\n"));
|
||||
CLOSE_ON_EXEC (save_stdout);
|
||||
|
||||
/* stdin_fd and stdout_fd must be closed on exit because we are
|
||||
still in the parent process */
|
||||
if (stdin_fd != 0)
|
||||
CLOSE_ON_EXEC (stdin_fd);
|
||||
if (stdout_fd != 1)
|
||||
CLOSE_ON_EXEC (stdout_fd);
|
||||
dup2 (stdout_fd, FD_STDOUT);
|
||||
CLOSE_ON_EXEC (stdout_fd);
|
||||
}
|
||||
|
||||
if (stderr_fd != FD_STDERR)
|
||||
{
|
||||
if (stderr_fd != stdout_fd)
|
||||
{
|
||||
save_stderr = dup (FD_STDERR);
|
||||
if (save_stderr < 0)
|
||||
fatal (NILF, _("no more file handles: could not duplicate stderr\n"));
|
||||
CLOSE_ON_EXEC (save_stderr);
|
||||
}
|
||||
|
||||
dup2 (stderr_fd, FD_STDERR);
|
||||
CLOSE_ON_EXEC (stderr_fd);
|
||||
}
|
||||
|
||||
/* Run the command. */
|
||||
pid = exec_command (argv, envp);
|
||||
|
||||
/* Restore stdout/stdin of the parent and close temporary FDs. */
|
||||
if (stdin_fd != 0)
|
||||
/* Restore stdout/stdin/stderr of the parent and close temporary FDs. */
|
||||
if (save_stdin >= 0)
|
||||
{
|
||||
if (dup2 (save_stdin, 0) != 0)
|
||||
if (dup2 (save_stdin, FD_STDIN) != FD_STDIN)
|
||||
fatal (NILF, _("Could not restore stdin\n"));
|
||||
else
|
||||
close (save_stdin);
|
||||
}
|
||||
|
||||
if (stdout_fd != 1)
|
||||
if (save_stdout >= 0)
|
||||
{
|
||||
if (dup2 (save_stdout, 1) != 1)
|
||||
if (dup2 (save_stdout, FD_STDOUT) != FD_STDOUT)
|
||||
fatal (NILF, _("Could not restore stdout\n"));
|
||||
else
|
||||
close (save_stdout);
|
||||
}
|
||||
|
||||
if (save_stderr >= 0)
|
||||
{
|
||||
if (dup2 (save_stderr, FD_STDERR) != FD_STDERR)
|
||||
fatal (NILF, _("Could not restore stderr\n"));
|
||||
else
|
||||
close (save_stderr);
|
||||
}
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
@@ -2245,19 +2263,28 @@ child_execute_job (int stdin_fd, int stdout_fd, char **argv, char **envp)
|
||||
|
||||
/* UNIX:
|
||||
Replace the current process with one executing the command in ARGV.
|
||||
STDIN_FD and STDOUT_FD are used as the process's stdin and stdout; ENVP is
|
||||
the environment of the new program. This function does not return. */
|
||||
STDIN_FD/STDOUT_FD/STDERR_FD are used as the process's stdin/stdout/stderr;
|
||||
ENVP is the environment of the new program. This function does not return. */
|
||||
void
|
||||
child_execute_job (int stdin_fd, int stdout_fd, char **argv, char **envp)
|
||||
child_execute_job (int stdin_fd, int stdout_fd, int stderr_fd,
|
||||
char **argv, char **envp)
|
||||
{
|
||||
if (stdin_fd != 0)
|
||||
(void) dup2 (stdin_fd, 0);
|
||||
if (stdout_fd != 1)
|
||||
(void) dup2 (stdout_fd, 1);
|
||||
if (stdin_fd != 0)
|
||||
(void) close (stdin_fd);
|
||||
if (stdout_fd != 1)
|
||||
(void) close (stdout_fd);
|
||||
/* For any redirected FD, dup2() it to the standard FD then close it. */
|
||||
if (stdin_fd != FD_STDIN)
|
||||
{
|
||||
dup2 (stdin_fd, FD_STDIN);
|
||||
close (stdin_fd);
|
||||
}
|
||||
|
||||
if (stdout_fd != FD_STDOUT)
|
||||
dup2 (stdout_fd, FD_STDOUT);
|
||||
if (stderr_fd != FD_STDERR)
|
||||
dup2 (stderr_fd, FD_STDERR);
|
||||
|
||||
if (stdout_fd != FD_STDOUT)
|
||||
close (stdout_fd);
|
||||
if (stderr_fd != FD_STDERR && stderr_fd != stdout_fd)
|
||||
close (stderr_fd);
|
||||
|
||||
/* Run the command. */
|
||||
exec_command (argv, envp);
|
||||
|
||||
26
job.h
26
job.h
@@ -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) \
|
||||
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. */
|
||||
|
||||
@@ -123,10 +122,17 @@ 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);
|
||||
#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))
|
||||
# if defined(__EMX__)
|
||||
int child_execute_job (int stdin_fd, int stdout_fd, int stderr_fd,
|
||||
char **argv, char **envp);
|
||||
# else
|
||||
void child_execute_job (int stdin_fd, int stdout_fd, int stderr_fd,
|
||||
char **argv, char **envp) __attribute__ ((noreturn));
|
||||
# endif
|
||||
#endif
|
||||
#ifdef _AMIGA
|
||||
void exec_command (char **argv) __attribute__ ((noreturn));
|
||||
|
||||
4
load.c
4
load.c
@@ -82,12 +82,12 @@ load_object (const gmk_floc *flocp, int noerror,
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
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 ());
|
||||
|
||||
164
main.c
164
main.c
@@ -15,8 +15,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/>. */
|
||||
|
||||
#include "makeint.h"
|
||||
#include "dep.h"
|
||||
#include "filedef.h"
|
||||
#include "dep.h"
|
||||
#include "variable.h"
|
||||
#include "job.h"
|
||||
#include "commands.h"
|
||||
@@ -550,6 +550,11 @@ int clock_skew_detected;
|
||||
#endif
|
||||
unsigned short stopchar_map[UCHAR_MAX + 1] = {0};
|
||||
|
||||
/* If output-sync is enabled we'll collect all the output generated due to
|
||||
options, while reading makefiles, etc. */
|
||||
|
||||
struct output make_sync;
|
||||
|
||||
|
||||
/* Mask of signals that are being caught with fatal_error_signal. */
|
||||
|
||||
@@ -784,7 +789,7 @@ decode_output_sync_flags (void)
|
||||
|
||||
#ifdef WINDOWS32
|
||||
|
||||
#ifdef OUTPUT_SYNC
|
||||
#ifndef NO_OUTPUT_SYNC
|
||||
|
||||
/* This is called from start_job_command when it detects that
|
||||
output_sync option is in effect. The handle to the synchronization
|
||||
@@ -809,7 +814,7 @@ prepare_mutex_handle_string (sync_handle_t handle)
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* OUTPUT_SYNC */
|
||||
#endif /* NO_OUTPUT_SYNC */
|
||||
|
||||
/*
|
||||
* HANDLE runtime exceptions by avoiding a requestor on the GUI. Capture
|
||||
@@ -1041,6 +1046,7 @@ main (int argc, char **argv, char **envp)
|
||||
struct dep *read_files;
|
||||
PATH_VAR (current_directory);
|
||||
unsigned int restarts = 0;
|
||||
unsigned int syncing = 0;
|
||||
#ifdef WINDOWS32
|
||||
char *unix_path = NULL;
|
||||
char *windows32_path = NULL;
|
||||
@@ -1052,6 +1058,8 @@ main (int argc, char **argv, char **envp)
|
||||
no_default_sh_exe = 1;
|
||||
#endif
|
||||
|
||||
output_init (&make_sync);
|
||||
|
||||
initialize_stopchar_map();
|
||||
|
||||
#ifdef SET_STACK_SIZE
|
||||
@@ -1255,7 +1263,7 @@ main (int argc, char **argv, char **envp)
|
||||
#ifdef MAKE_JOBSERVER
|
||||
" jobserver"
|
||||
#endif
|
||||
#ifdef OUTPUT_SYNC
|
||||
#ifndef NO_OUTPUT_SYNC
|
||||
" output-sync"
|
||||
#endif
|
||||
#ifdef MAKE_SYMLINKS
|
||||
@@ -1287,58 +1295,62 @@ main (int argc, char **argv, char **envp)
|
||||
|
||||
for (i = 0; envp[i] != 0; ++i)
|
||||
{
|
||||
int do_not_define = 0;
|
||||
struct variable *v;
|
||||
char *ep = envp[i];
|
||||
/* By default, export all variables culled from the environment. */
|
||||
enum variable_export export = v_export;
|
||||
unsigned int len;
|
||||
|
||||
while (! STOP_SET (*ep, MAP_EQUALS))
|
||||
++ep;
|
||||
|
||||
/* If there's no equals sign it's a malformed environment. Ignore. */
|
||||
if (*ep == '\0')
|
||||
continue;
|
||||
|
||||
#ifdef WINDOWS32
|
||||
if (!unix_path && strneq (envp[i], "PATH=", 5))
|
||||
unix_path = ep+1;
|
||||
else if (!strnicmp (envp[i], "Path=", 5))
|
||||
{
|
||||
do_not_define = 1; /* it gets defined after loop exits */
|
||||
if (!windows32_path)
|
||||
windows32_path = ep+1;
|
||||
/* PATH gets defined after the loop exits. */
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
/* The result of pointer arithmetic is cast to unsigned int for
|
||||
machines where ptrdiff_t is a different size that doesn't widen
|
||||
the same. */
|
||||
if (!do_not_define)
|
||||
|
||||
/* Length of the variable name, and skip the '='. */
|
||||
len = ep++ - envp[i];
|
||||
|
||||
/* If this is MAKE_RESTARTS, check to see if the "already printed
|
||||
the enter statement" flag is set. */
|
||||
if (len == 13 && strneq (envp[i], "MAKE_RESTARTS", 13))
|
||||
{
|
||||
struct variable *v;
|
||||
|
||||
v = define_variable (envp[i], (unsigned int) (ep - envp[i]),
|
||||
ep + 1, o_env, 1);
|
||||
/* Force exportation of every variable culled from the
|
||||
environment. We used to rely on target_environment's
|
||||
v_default code to do this. But that does not work for the
|
||||
case where an environment variable is redefined in a makefile
|
||||
with 'override'; it should then still be exported, because it
|
||||
was originally in the environment. */
|
||||
v->export = v_export;
|
||||
|
||||
/* Another wrinkle is that POSIX says the value of SHELL set in
|
||||
the makefile won't change the value of SHELL given to
|
||||
subprocesses. */
|
||||
if (streq (v->name, "SHELL"))
|
||||
if (*ep == '-')
|
||||
{
|
||||
#ifndef __MSDOS__
|
||||
v->export = v_noexport;
|
||||
#endif
|
||||
shell_var.name = "SHELL";
|
||||
shell_var.length = 5;
|
||||
shell_var.value = xstrdup (ep + 1);
|
||||
}
|
||||
|
||||
/* If MAKE_RESTARTS is set, remember it but don't export it. */
|
||||
if (streq (v->name, "MAKE_RESTARTS"))
|
||||
{
|
||||
v->export = v_noexport;
|
||||
restarts = (unsigned int) atoi (ep + 1);
|
||||
OUTPUT_TRACED ();
|
||||
++ep;
|
||||
}
|
||||
restarts = (unsigned int) atoi (ep);
|
||||
export = v_noexport;
|
||||
}
|
||||
|
||||
v = define_variable (envp[i], len, ep, o_env, 1);
|
||||
|
||||
/* POSIX says the value of SHELL set in the makefile won't change the
|
||||
value of SHELL given to subprocesses. */
|
||||
if (streq (v->name, "SHELL"))
|
||||
{
|
||||
#ifndef __MSDOS__
|
||||
export = v_noexport;
|
||||
#endif
|
||||
shell_var.name = "SHELL";
|
||||
shell_var.length = 5;
|
||||
shell_var.value = xstrdup (ep);
|
||||
}
|
||||
|
||||
v->export = export;
|
||||
}
|
||||
}
|
||||
#ifdef WINDOWS32
|
||||
@@ -1382,8 +1394,19 @@ main (int argc, char **argv, char **envp)
|
||||
/* Decode the switches. */
|
||||
|
||||
decode_env_switches (STRING_SIZE_TUPLE ("GNUMAKEFLAGS"));
|
||||
|
||||
/* Clear GNUMAKEFLAGS to avoid duplication. */
|
||||
define_variable_cname ("GNUMAKEFLAGS", "", o_env, 0);
|
||||
|
||||
decode_env_switches (STRING_SIZE_TUPLE ("MAKEFLAGS"));
|
||||
|
||||
/* In output sync mode we need to sync any output generated by reading the
|
||||
makefiles, such as in $(info ...) or stderr from $(shell ...) etc. */
|
||||
|
||||
syncing = make_sync.syncout = (output_sync == OUTPUT_SYNC_LINE
|
||||
|| output_sync == OUTPUT_SYNC_TARGET);
|
||||
OUTPUT_SET (&make_sync);
|
||||
|
||||
#if 0
|
||||
/* People write things like:
|
||||
MFLAGS="CC=gcc -pipe" "CFLAGS=-g"
|
||||
@@ -1393,6 +1416,16 @@ main (int argc, char **argv, char **envp)
|
||||
|
||||
decode_switches (argc, argv, 0);
|
||||
|
||||
/* Reset in case the switches changed our minds. */
|
||||
syncing = (output_sync == OUTPUT_SYNC_LINE
|
||||
|| output_sync == OUTPUT_SYNC_TARGET);
|
||||
|
||||
if (make_sync.syncout && ! syncing)
|
||||
output_close (&make_sync);
|
||||
|
||||
make_sync.syncout = syncing;
|
||||
OUTPUT_SET (&make_sync);
|
||||
|
||||
/* Figure out the level of recursion. */
|
||||
{
|
||||
struct variable *v = lookup_variable (STRING_SIZE_TUPLE (MAKELEVEL_NAME));
|
||||
@@ -1477,6 +1510,9 @@ main (int argc, char **argv, char **envp)
|
||||
#endif /* WINDOWS32 */
|
||||
#endif
|
||||
|
||||
/* We may move, but until we do, here we are. */
|
||||
starting_directory = current_directory;
|
||||
|
||||
#ifdef MAKE_JOBSERVER
|
||||
/* If the jobserver-fds option is seen, make sure that -j is reasonable.
|
||||
This can't be usefully set in the makefile, and we want to verify the
|
||||
@@ -1526,7 +1562,11 @@ main (int argc, char **argv, char **envp)
|
||||
error (NILF, _("warning: -jN forced in submake: disabling jobserver mode."));
|
||||
}
|
||||
#ifndef WINDOWS32
|
||||
#define FD_OK(_f) ((fcntl ((_f), F_GETFD) != -1) || (errno != EBADF))
|
||||
#ifdef HAVE_FCNTL
|
||||
# define FD_OK(_f) ((fcntl ((_f), F_GETFD) != -1) || (errno != EBADF))
|
||||
#else
|
||||
# define FD_OK(_f) 1
|
||||
#endif
|
||||
/* 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, print a
|
||||
@@ -1667,11 +1707,8 @@ main (int argc, char **argv, char **envp)
|
||||
construct_include_path (include_directories == 0
|
||||
? 0 : include_directories->list);
|
||||
|
||||
/* Figure out where we are now, after chdir'ing. */
|
||||
if (directories == 0)
|
||||
/* We didn't move, so we're still in the same place. */
|
||||
starting_directory = current_directory;
|
||||
else
|
||||
/* If we chdir'ed, figure out where we are now. */
|
||||
if (directories)
|
||||
{
|
||||
#ifdef WINDOWS32
|
||||
if (getcwd_fs (current_directory, GET_PATH_MAX) == 0)
|
||||
@@ -1896,11 +1933,25 @@ main (int argc, char **argv, char **envp)
|
||||
|
||||
/* Decode switches again, for variables set by the makefile. */
|
||||
decode_env_switches (STRING_SIZE_TUPLE ("GNUMAKEFLAGS"));
|
||||
|
||||
/* Clear GNUMAKEFLAGS to avoid duplication. */
|
||||
define_variable_cname ("GNUMAKEFLAGS", "", o_override, 0);
|
||||
|
||||
decode_env_switches (STRING_SIZE_TUPLE ("MAKEFLAGS"));
|
||||
#if 0
|
||||
decode_env_switches (STRING_SIZE_TUPLE ("MFLAGS"));
|
||||
#endif
|
||||
|
||||
/* Reset in case the switches changed our mind. */
|
||||
syncing = (output_sync == OUTPUT_SYNC_LINE
|
||||
|| output_sync == OUTPUT_SYNC_TARGET);
|
||||
|
||||
if (make_sync.syncout && ! syncing)
|
||||
output_close (&make_sync);
|
||||
|
||||
make_sync.syncout = syncing;
|
||||
OUTPUT_SET (&make_sync);
|
||||
|
||||
/* If we've disabled builtin rules, get rid of them. */
|
||||
if (no_builtin_rules_flag && ! old_builtin_rules_flag)
|
||||
{
|
||||
@@ -2071,6 +2122,11 @@ main (int argc, char **argv, char **envp)
|
||||
/* Initialize the remote job module. */
|
||||
remote_setup ();
|
||||
|
||||
/* Dump any output we've collected. */
|
||||
|
||||
OUTPUT_UNSET ();
|
||||
output_close (&make_sync);
|
||||
|
||||
if (read_files != 0)
|
||||
{
|
||||
/* Update any makefiles if necessary. */
|
||||
@@ -2309,7 +2365,8 @@ main (int argc, char **argv, char **envp)
|
||||
else if (strneq (*p, "MAKE_RESTARTS=", CSTRLEN ("MAKE_RESTARTS=")))
|
||||
{
|
||||
*p = alloca (40);
|
||||
sprintf (*p, "MAKE_RESTARTS=%u", restarts);
|
||||
sprintf (*p, "MAKE_RESTARTS=%s%u",
|
||||
OUTPUT_IS_TRACED () ? "-" : "", restarts);
|
||||
restarts = 0;
|
||||
}
|
||||
}
|
||||
@@ -2321,7 +2378,7 @@ main (int argc, char **argv, char **envp)
|
||||
sprintf (buffer, "%u", makelevel);
|
||||
SetVar (MAKELEVEL_NAME, buffer, -1, GVF_GLOBAL_ONLY);
|
||||
|
||||
sprintf (buffer, "%u", restarts);
|
||||
sprintf (buffer, "%s%u", OUTPUT_IS_TRACED () ? "-" : "", restarts);
|
||||
SetVar ("MAKE_RESTARTS", buffer, -1, GVF_GLOBAL_ONLY);
|
||||
restarts = 0;
|
||||
}
|
||||
@@ -2331,7 +2388,8 @@ main (int argc, char **argv, char **envp)
|
||||
if (restarts)
|
||||
{
|
||||
char *b = alloca (40);
|
||||
sprintf (b, "MAKE_RESTARTS=%u", restarts);
|
||||
sprintf (b, "MAKE_RESTARTS=%s%u",
|
||||
OUTPUT_IS_TRACED () ? "-" : "", restarts);
|
||||
putenv (b);
|
||||
}
|
||||
|
||||
@@ -2355,7 +2413,8 @@ main (int argc, char **argv, char **envp)
|
||||
termination. */
|
||||
int pid;
|
||||
int r;
|
||||
pid = child_execute_job (0, 1, nargv, environ);
|
||||
pid = child_execute_job (FD_STDIN, FD_STDOUT, FD_STDERR,
|
||||
nargv, environ);
|
||||
|
||||
/* is this loop really necessary? */
|
||||
do {
|
||||
@@ -3349,6 +3408,13 @@ die (int status)
|
||||
|
||||
clean_jobserver (status);
|
||||
|
||||
if (output_context)
|
||||
{
|
||||
assert (output_context == &make_sync);
|
||||
OUTPUT_UNSET ();
|
||||
output_close (&make_sync);
|
||||
}
|
||||
|
||||
output_close (NULL);
|
||||
|
||||
/* Try to move back to the original directory. This is essential on
|
||||
|
||||
@@ -184,10 +184,41 @@ 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
|
||||
|
||||
checkcfg.%: distdir
|
||||
@ 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)' \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) check
|
||||
|
||||
|
||||
.PHONY: update
|
||||
update: po-update scm-update
|
||||
|
||||
|
||||
## --------------- ##
|
||||
## Sanity checks. ##
|
||||
## --------------- ##
|
||||
|
||||
# Before we build a distribution be sure we run our local checks
|
||||
#distdir: local-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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -68,7 +68,7 @@ $ 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 " + -
|
||||
"output signame variable version vmsfunctions vmsify vpath " + -
|
||||
"[.glob]glob [.glob]fnmatch getopt1 getopt strcache"
|
||||
$ copy config.h-vms config.h
|
||||
$ n=0
|
||||
|
||||
@@ -556,10 +556,6 @@ 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
|
||||
|
||||
1
misc.c
1
misc.c
@@ -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"
|
||||
|
||||
|
||||
71
output.c
71
output.c
@@ -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,20 +33,35 @@ 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)
|
||||
|
||||
#ifdef HAVE_FCNTL
|
||||
# define STREAM_OK(_s) ((fcntl (fileno (_s), F_GETFD) != -1) || (errno != EBADF))
|
||||
#else
|
||||
# define STREAM_OK(_s) 1
|
||||
#endif
|
||||
|
||||
/* 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 __VMS
|
||||
# define va_copy(_d, _s) ((_d) = (_s))
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
#define va_copy(_d, _s) ((_d) = (_s))
|
||||
#define snprintf msc_vsnprintf
|
||||
# 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)
|
||||
{
|
||||
@@ -78,10 +96,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 +108,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;
|
||||
@@ -154,7 +170,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,13 +189,11 @@ 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. */
|
||||
@@ -369,22 +383,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 +418,7 @@ output_dump (struct output *out)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* OUTPUT_SYNC */
|
||||
#endif /* NO_OUTPUT_SYNC */
|
||||
|
||||
|
||||
/* Provide support for temporary files. */
|
||||
@@ -547,11 +560,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
|
||||
|
||||
@@ -567,16 +580,18 @@ output_close (struct output *out)
|
||||
void
|
||||
output_start ()
|
||||
{
|
||||
#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
|
||||
|
||||
8
output.h
8
output.h
@@ -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);
|
||||
|
||||
16
read.c
16
read.c
@@ -20,8 +20,8 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <glob.h>
|
||||
|
||||
#include "dep.h"
|
||||
#include "filedef.h"
|
||||
#include "dep.h"
|
||||
#include "job.h"
|
||||
#include "commands.h"
|
||||
#include "variable.h"
|
||||
@@ -947,19 +947,27 @@ 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;
|
||||
int r;
|
||||
|
||||
/* Load the file. 0 means failure. */
|
||||
r = load_file (&ebuf->floc, &name, noerror);
|
||||
if (! r && ! noerror)
|
||||
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;
|
||||
|
||||
/* It succeeded, so add it to the list "to be rebuilt". */
|
||||
deps = alloc_dep ();
|
||||
deps->next = read_files;
|
||||
read_files = deps;
|
||||
|
||||
2
rule.c
2
rule.c
@@ -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"
|
||||
|
||||
@@ -1,3 +1,67 @@
|
||||
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.
|
||||
|
||||
@@ -369,6 +369,15 @@ sub set_more_defaults
|
||||
-f "${d}gnumake.h" and $srcdir = $d;
|
||||
}
|
||||
|
||||
# Not with the make program, so see if we can get it out of the makefile
|
||||
if (! $srcdir && open(MF, "< ../Makefile")) {
|
||||
local $/ = undef;
|
||||
$_ = <MF>;
|
||||
close(MF);
|
||||
/^abs_srcdir\s*=\s*(.*?)\s*$/m;
|
||||
-f "$1/gnumake.h" and $srcdir = $1;
|
||||
}
|
||||
|
||||
# Get Purify log info--if any.
|
||||
|
||||
if (exists $ENV{PURIFYOPTIONS}
|
||||
|
||||
@@ -11,17 +11,32 @@ exists $FEATURES{archives} or return -1;
|
||||
# Create some .o files to work with
|
||||
utouch(-60, qw(a1.o a2.o a3.o));
|
||||
|
||||
# Some versions of ar print different things on creation. Find out.
|
||||
my $created = `ar rv libxx.a a1.o 2>&1`;
|
||||
|
||||
# Some versions of ar print different things on add. Find out.
|
||||
my $add = `ar rv libxx.a a2.o 2>&1`;
|
||||
$add =~ s/a2\.o/#OBJECT#/g;
|
||||
|
||||
# Some versions of ar print different things on replacement. Find out.
|
||||
my $repl = `ar rv libxx.a a2.o 2>&1`;
|
||||
$repl =~ s/a2\.o/#OBJECT#/g;
|
||||
|
||||
unlink('libxx.a');
|
||||
|
||||
# Very simple
|
||||
run_make_test('all: libxx.a(a1.o)',
|
||||
'', "ar rv libxx.a a1.o\nar: creating libxx.a\na - a1.o\n");
|
||||
'', "ar rv libxx.a a1.o\n$created");
|
||||
|
||||
# Multiple .o's. Add a new one to the existing library
|
||||
($_ = $add) =~ s/#OBJECT#/a2.o/g;
|
||||
run_make_test('all: libxx.a(a1.o a2.o)',
|
||||
'', "ar rv libxx.a a2.o\na - a2.o\n");
|
||||
'', "ar rv libxx.a a2.o\n$_");
|
||||
|
||||
# Touch one of the .o's so it's rebuilt
|
||||
utouch(-40, 'a1.o');
|
||||
run_make_test(undef, '', "ar rv libxx.a a1.o\nr - a1.o\n");
|
||||
($_ = $repl) =~ s/#OBJECT#/a1.o/g;
|
||||
run_make_test(undef, '', "ar rv libxx.a a1.o\n$_");
|
||||
|
||||
# Use wildcards
|
||||
run_make_test('all: libxx.a(*.o)',
|
||||
@@ -29,17 +44,22 @@ run_make_test('all: libxx.a(*.o)',
|
||||
|
||||
# Touch one of the .o's so it's rebuilt
|
||||
utouch(-30, 'a1.o');
|
||||
run_make_test(undef, '', "ar rv libxx.a a1.o\nr - a1.o\n");
|
||||
($_ = $repl) =~ s/#OBJECT#/a1.o/g;
|
||||
run_make_test(undef, '', "ar rv libxx.a a1.o\n$_");
|
||||
|
||||
# Use both wildcards and simple names
|
||||
utouch(-50, 'a2.o');
|
||||
($_ = $add) =~ s/#OBJECT#/a3.o/g;
|
||||
$_ .= "ar rv libxx.a a2.o\n";
|
||||
($_ .= $repl) =~ s/#OBJECT#/a2.o/g;
|
||||
run_make_test('all: libxx.a(a3.o *.o)', '',
|
||||
"ar rv libxx.a a3.o\na - a3.o\nar rv libxx.a a2.o\nr - a2.o\n");
|
||||
"ar rv libxx.a a3.o\n$_");
|
||||
|
||||
# Check whitespace handling
|
||||
utouch(-40, 'a2.o');
|
||||
($_ = $repl) =~ s/#OBJECT#/a2.o/g;
|
||||
run_make_test('all: libxx.a( a3.o *.o )', '',
|
||||
"ar rv libxx.a a2.o\nr - a2.o\n");
|
||||
"ar rv libxx.a a2.o\n$_");
|
||||
|
||||
rmfiles(qw(a1.o a2.o a3.o libxx.a));
|
||||
|
||||
|
||||
@@ -10,32 +10,33 @@ open(MAKEFILE,"> $makefile");
|
||||
print MAKEFILE "FIRST: ; \@echo It chose GNUmakefile\n";
|
||||
close(MAKEFILE);
|
||||
|
||||
# DOS/WIN32 platforms preserve case, but Makefile is the same file as makefile.
|
||||
# Just test what we can here (avoid Makefile versus makefile test).
|
||||
|
||||
if ($port_type eq 'UNIX') {
|
||||
# Create another makefile called "makefile"
|
||||
open(MAKEFILE,"> makefile");
|
||||
print MAKEFILE "SECOND: ; \@echo It chose makefile\n";
|
||||
close(MAKEFILE);
|
||||
}
|
||||
|
||||
# Create another makefile called "Makefile"
|
||||
open(MAKEFILE,"> Makefile");
|
||||
print MAKEFILE "THIRD: ; \@echo It chose Makefile\n";
|
||||
# Create another makefile called "makefile"
|
||||
open(MAKEFILE,"> makefile");
|
||||
print MAKEFILE "SECOND: ; \@echo It chose makefile\n";
|
||||
close(MAKEFILE);
|
||||
|
||||
# DOS/WIN32/MacOSX platforms are case-insensitive / case-preserving, so
|
||||
# Makefile is the same file as makefile. Just test what we can here.
|
||||
|
||||
&run_make_with_options("","",&get_logfile);
|
||||
&compare_output("It chose GNUmakefile\n",&get_logfile(1));
|
||||
unlink $makefile;
|
||||
|
||||
if ($port_type eq 'UNIX') {
|
||||
&run_make_with_options("","",&get_logfile);
|
||||
&compare_output("It chose makefile\n",&get_logfile(1));
|
||||
unlink "makefile";
|
||||
my $case_sensitive = 0;
|
||||
if (! -f 'Makefile') {
|
||||
# Create another makefile called "Makefile"
|
||||
$case_sensitive = 1;
|
||||
open(MAKEFILE,"> Makefile");
|
||||
print MAKEFILE "THIRD: ; \@echo It chose Makefile\n";
|
||||
close(MAKEFILE);
|
||||
}
|
||||
|
||||
&run_make_with_options("","",&get_logfile);
|
||||
&compare_output("It chose Makefile\n",&get_logfile(1));
|
||||
unlink "Makefile";
|
||||
run_make_with_options("","",&get_logfile);
|
||||
compare_output("It chose GNUmakefile\n",&get_logfile(1));
|
||||
unlink($makefile);
|
||||
|
||||
run_make_with_options("","",&get_logfile);
|
||||
compare_output("It chose makefile\n",&get_logfile(1));
|
||||
unlink("makefile");
|
||||
|
||||
if ($case_sensitive) {
|
||||
run_make_with_options("","",&get_logfile);
|
||||
compare_output("It chose Makefile\n",&get_logfile(1));
|
||||
unlink("Makefile");
|
||||
}
|
||||
|
||||
@@ -54,19 +54,21 @@ run_make_test(undef,
|
||||
|
||||
# Test escaped colons in prerequisites
|
||||
# Quoting of backslashes in q!! is kind of messy.
|
||||
# Solaris sh does not properly handle backslashes even in '' so just
|
||||
# check the output make prints, not what the shell interprets.
|
||||
run_make_test(q!
|
||||
foo: foo\\:bar foo\\\\\\:bar foo\\\\\\\\\\:bar
|
||||
foo foo\\:bar foo\\\\\\:bar foo\\\\\\\\\\:bar: ; @echo '$@'
|
||||
foo foo\\:bar foo\\\\\\:bar foo\\\\\\\\\\:bar: ; : '$@'
|
||||
!,
|
||||
'', "foo:bar\nfoo\\:bar\nfoo\\\\:bar\nfoo\n");
|
||||
'', ": 'foo:bar'\n: 'foo\\:bar'\n: 'foo\\\\:bar'\n: 'foo'\n");
|
||||
|
||||
# Test backslash before non-special chars: should be kept as-is
|
||||
|
||||
run_make_test(q!
|
||||
all: ..\foo
|
||||
.DEFAULT: ; @echo '$@'
|
||||
.DEFAULT: ; : '$@'
|
||||
!,
|
||||
'', '..\foo');
|
||||
'', ": '..\\foo'\n");
|
||||
|
||||
# This tells the test driver that the perl test script executed properly.
|
||||
1;
|
||||
|
||||
61
tests/scripts/features/jobserver
Normal file
61
tests/scripts/features/jobserver
Normal file
@@ -0,0 +1,61 @@
|
||||
# -*-perl-*-
|
||||
|
||||
$description = "Test jobserver.";
|
||||
|
||||
$details = "These tests are ones that specifically are different when the
|
||||
jobserver feature is available. Most -j tests are the same whether or not
|
||||
jobserver is available, and those appear in the 'parallelism' test suite.";
|
||||
|
||||
exists $FEATURES{'jobserver'} or return -1;
|
||||
|
||||
if (!$parallel_jobs) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
# Don't put --jobserver-fds into a re-exec'd MAKEFLAGS.
|
||||
# We can't test this directly because there's no way a makefile can
|
||||
# show the value of MAKEFLAGS we were re-exec'd with. We can intuit it
|
||||
# by looking for "disabling jobserver mode" warnings; we should only
|
||||
# get one from the original invocation and none from the re-exec.
|
||||
# See Savannah bug #18124
|
||||
|
||||
unlink('inc.mk');
|
||||
|
||||
run_make_test(q!
|
||||
-include inc.mk
|
||||
recur:
|
||||
# @echo 'MAKEFLAGS = $(MAKEFLAGS)'
|
||||
@rm -f inc.mk
|
||||
@$(MAKE) -j2 -f #MAKEFILE# all
|
||||
all:
|
||||
# @echo 'MAKEFLAGS = $(MAKEFLAGS)'
|
||||
@echo $@
|
||||
inc.mk:
|
||||
# @echo 'MAKEFLAGS = $(MAKEFLAGS)'
|
||||
@echo 'FOO = bar' > $@
|
||||
!,
|
||||
'--no-print-directory -j2', "#MAKE#[1]: warning: -jN forced in submake: disabling jobserver mode.\nall\n");
|
||||
|
||||
unlink('inc.mk');
|
||||
|
||||
# Test recursion when make doesn't think it exists.
|
||||
# See Savannah bug #39934
|
||||
# Or Red Hat bug https://bugzilla.redhat.com/show_bug.cgi?id=885474
|
||||
|
||||
open(MAKEFILE,"> Makefile2");
|
||||
print MAKEFILE <<EOF;
|
||||
vpath %.c $ENV{HOME}/
|
||||
foo:
|
||||
EOF
|
||||
close(MAKEFILE);
|
||||
|
||||
run_make_test(q!
|
||||
default: ; @ #MAKEPATH# -f Makefile2
|
||||
!,
|
||||
'-j2 --no-print-directory',
|
||||
"#MAKE#[1]: warning: jobserver unavailable: using -j1. Add '+' to parent make rule.
|
||||
#MAKE#[1]: Nothing to be done for 'foo'.");
|
||||
|
||||
rmfiles('Makefile2');
|
||||
|
||||
1;
|
||||
@@ -4,9 +4,12 @@ $description = "Test --output-sync (-O) option.";
|
||||
|
||||
$details = "Test the synchronization of output from parallel jobs.";
|
||||
|
||||
if (!$parallel_jobs) {
|
||||
return -1;
|
||||
}
|
||||
# If we don't have output sync support, never mind.
|
||||
exists $FEATURES{'output-sync'} or return -1;
|
||||
|
||||
# Output sync can't be tested without parallelization
|
||||
$parallel_jobs or return -1;
|
||||
|
||||
|
||||
if ($vos) {
|
||||
$sleep_command = "sleep -seconds";
|
||||
@@ -88,7 +91,7 @@ foo-fail:
|
||||
\t\@echo foo-fail: start
|
||||
\t\@$wait_bar
|
||||
\t\@echo foo-fail: end
|
||||
\t\@false
|
||||
\t\@exit 1
|
||||
EOF
|
||||
close(MAKEFILE);
|
||||
|
||||
@@ -261,5 +264,71 @@ all:
|
||||
|
||||
run_make_test(undef, '-j -Otarget', "foobar\ntrue\n");
|
||||
|
||||
# Ensure that shell functions inside recipes write stderr to the sync file
|
||||
run_make_test(q!
|
||||
all: ; @: $(shell echo foo 1>&2)
|
||||
!,
|
||||
'-w -Oline', "#MAKE#: Entering directory '#PWD#'\nfoo\n#MAKE#: Leaving directory '#PWD#'\n");
|
||||
|
||||
# Ensure that output generated while parsing makefiles is synced
|
||||
# when appropriate.
|
||||
run_make_test(q!
|
||||
$(shell echo foo 1>&2)
|
||||
all: ; echo bar
|
||||
!,
|
||||
'-s -w -Otarget', "#MAKE#: Entering directory '#PWD#'\nfoo\n#MAKE#: Leaving directory '#PWD#'\n#MAKE#: Entering directory '#PWD#'\nbar\n#MAKE#: Leaving directory '#PWD#'\n");
|
||||
|
||||
# Test recursion
|
||||
$m1 = get_tmpfile();
|
||||
$m2 = get_tmpfile();
|
||||
|
||||
open(M1, "> $m1");
|
||||
print M1 <<'EOF';
|
||||
$(shell echo d1 stderr 1>&2)
|
||||
$(info d1 stdout)
|
||||
all:; @:
|
||||
EOF
|
||||
close(M1);
|
||||
|
||||
open(M2, "> $m2");
|
||||
print M2 <<'EOF';
|
||||
$(shell echo d2 stderr 1>&2)
|
||||
$(info d2 stdout)
|
||||
all:; @:
|
||||
# Force an ordering on the output
|
||||
$(shell sleep 1)
|
||||
EOF
|
||||
close(M2);
|
||||
|
||||
run_make_test(qq!
|
||||
all: t1 t2
|
||||
t1: ; \@\$(MAKE) -f $m1
|
||||
t2: ; \@\$(MAKE) -f $m2
|
||||
!,
|
||||
"-j -Oline", "#MAKE#[1]: Entering directory '#PWD#'\nd1 stderr\nd1 stdout\n#MAKE#[1]: Leaving directory '#PWD#'\n#MAKE#[1]: Entering directory '#PWD#'\nd2 stderr\nd2 stdout\n#MAKE#[1]: Leaving directory '#PWD#'\n");
|
||||
|
||||
rmfiles($m1, $m2);
|
||||
|
||||
# Ensure that output generated while parsing makefiles is synced
|
||||
# when appropriate.
|
||||
$m1 = get_tmpfile();
|
||||
|
||||
open(M1, "> $m1");
|
||||
print M1 <<'EOF';
|
||||
$(shell echo d1 stderr 1>&2)
|
||||
$(info d1 stdout)
|
||||
$(error d1 failed)
|
||||
all:; @:
|
||||
EOF
|
||||
close(M1);
|
||||
|
||||
run_make_test(qq!
|
||||
all: t1
|
||||
t1: ; -\@\$(MAKE) -f $m1
|
||||
!,
|
||||
"-j -Oline", "#MAKE#[1]: Entering directory '#PWD#'\nd1 stderr\nd1 stdout\n$m1:3: *** d1 failed. Stop.\n#MAKE#[1]: Leaving directory '#PWD#'\n#MAKEFILE#:3: recipe for target 't1' failed\n#MAKE#: [t1] Error 2 (ignored)\n");
|
||||
|
||||
rmfiles($m1);
|
||||
|
||||
# This tells the test driver that the perl test script executed properly.
|
||||
1;
|
||||
|
||||
@@ -41,7 +41,7 @@ all: 1 2; \@echo success
|
||||
1.inc: ; \@echo ONE.inc; $sleep_command 2; echo TWO.inc; echo '1: ; \@echo ONE; $sleep_command 2; echo TWO' > \$\@
|
||||
2.inc: ; \@$sleep_command 1; echo THREE.inc; echo '2: ; \@$sleep_command 1; echo THREE' > \$\@",
|
||||
"-j4",
|
||||
"ONE.inc\nTHREE.inc\nTWO.inc\nONE\nTHREE\nTWO\nsuccess\n");
|
||||
"ONE.inc\nTHREE.inc\nTWO.inc\nONE\nTHREE\nTWO\nsuccess\n", 0, 7);
|
||||
|
||||
rmfiles(qw(1.inc 2.inc));
|
||||
|
||||
@@ -60,7 +60,7 @@ endif
|
||||
1.inc: ; \@echo ONE.inc; $sleep_command 2; echo TWO.inc; echo '1: ; \@echo ONE; $sleep_command 2; echo TWO' > \$\@
|
||||
2.inc: ; \@$sleep_command 1; echo THREE.inc; echo '2: ; \@$sleep_command 1; echo THREE' > \$\@",
|
||||
"-j4",
|
||||
"ONE.inc\nTHREE.inc\nTWO.inc\nONE\nTHREE\nTWO\nsuccess\n");
|
||||
"ONE.inc\nTHREE.inc\nTWO.inc\nONE\nTHREE\nTWO\nsuccess\n", 0, 7);
|
||||
|
||||
rmfiles(qw(1.inc 2.inc));
|
||||
|
||||
@@ -143,30 +143,6 @@ intermed: | phony ; touch $@
|
||||
phony: ; : phony', '-rR -j', ': phony');
|
||||
rmfiles('target');
|
||||
|
||||
# TEST #10: Don't put --jobserver-fds into a re-exec'd MAKEFLAGS.
|
||||
# We can't test this directly because there's no way a makefile can
|
||||
# show the value of MAKEFLAGS we were re-exec'd with. We can intuit it
|
||||
# by looking for "disabling jobserver mode" warnings; we should only
|
||||
# get one from the original invocation and none from the re-exec.
|
||||
# See Savannah bug #18124
|
||||
|
||||
run_make_test(q!
|
||||
-include inc.mk
|
||||
recur:
|
||||
# @echo 'MAKEFLAGS = $(MAKEFLAGS)'
|
||||
@rm -f inc.mk
|
||||
@$(MAKE) -j2 -f #MAKEFILE# all
|
||||
all:
|
||||
# @echo 'MAKEFLAGS = $(MAKEFLAGS)'
|
||||
@echo $@
|
||||
inc.mk:
|
||||
# @echo 'MAKEFLAGS = $(MAKEFLAGS)'
|
||||
@echo 'FOO = bar' > $@
|
||||
!,
|
||||
'--no-print-directory -j2', "#MAKE#[1]: warning: -jN forced in submake: disabling jobserver mode.\nall\n");
|
||||
|
||||
rmfiles('inc.mk');
|
||||
|
||||
# TEST #11: Make sure -jN from MAKEFLAGS is processed even when we re-exec
|
||||
# See Savannah bug #33873
|
||||
|
||||
@@ -185,36 +161,6 @@ inc.mk: ; @touch $@
|
||||
delete $extraENV{MAKEFLAGS};
|
||||
rmfiles('inc.mk');
|
||||
|
||||
if ($all_tests) {
|
||||
# Implicit files aren't properly recreated during parallel builds
|
||||
# Savannah bug #26864
|
||||
|
||||
# The first run works fine
|
||||
run_make_test(q!
|
||||
%.bar: %.x foo.y ; cat $^ > $@
|
||||
%.x: ; touch $@
|
||||
foo.y: foo.y.in ; cp $< $@
|
||||
foo.y.in: ; touch $@
|
||||
!,
|
||||
'-j2 main.bar',
|
||||
"touch foo.y.in
|
||||
touch main.x
|
||||
cp foo.y.in foo.y
|
||||
cat main.x foo.y > main.bar
|
||||
rm main.x");
|
||||
|
||||
# Now we touch the .in file and make sure it still works
|
||||
touch('foo.y.in');
|
||||
|
||||
run_make_test(undef, '-j2 main.bar', "cp foo.y.in foo.y
|
||||
touch main.x
|
||||
cat main.x foo.y > main.bar
|
||||
rm main.x");
|
||||
|
||||
# Clean up
|
||||
rmfiles(qw(foo.y foo.y.in main.bar));
|
||||
}
|
||||
|
||||
# Ensure intermediate/secondary files are not pruned incorrectly.
|
||||
# See Savannah bug #30653
|
||||
|
||||
@@ -232,48 +178,6 @@ file2: file1 ; @touch $@
|
||||
|
||||
rmfiles('file1', 'file2', 'file3', 'file4');
|
||||
|
||||
if ($all_tests) {
|
||||
# Jobserver FD handling is messed up in some way.
|
||||
# Savannah bug #28189
|
||||
# It doesn't look like that bug anymore but this is the code it runs
|
||||
|
||||
run_make_test(q!
|
||||
ifdef EXTRA
|
||||
vpath %.dst /
|
||||
xxx.dst: ; true
|
||||
yyy.dst: ; true
|
||||
endif
|
||||
|
||||
M := $(MAKE)
|
||||
xx: ; $M --no-print-directory -j2 -f $(MAKEFILE_LIST) xxx.dst yyy.dst EXTRA=1
|
||||
!,
|
||||
'-j2',
|
||||
'#MAKE#[1]: warning: -jN forced in submake: disabling jobserver mode.
|
||||
true
|
||||
true
|
||||
');
|
||||
}
|
||||
|
||||
# Test recursion when make doesn't think it exists.
|
||||
# See Savannah bug #39934
|
||||
# Or Red Hat bug https://bugzilla.redhat.com/show_bug.cgi?id=885474
|
||||
|
||||
open(MAKEFILE,"> Makefile2");
|
||||
print MAKEFILE <<EOF;
|
||||
vpath %.c $ENV{HOME}/
|
||||
foo:
|
||||
EOF
|
||||
close(MAKEFILE);
|
||||
|
||||
run_make_test(q!
|
||||
default: ; @ #MAKEPATH# -f Makefile2
|
||||
!,
|
||||
'-j2 --no-print-directory',
|
||||
"#MAKE#[1]: warning: jobserver unavailable: using -j1. Add '+' to parent make rule.
|
||||
#MAKE#[1]: Nothing to be done for 'foo'.");
|
||||
|
||||
unlink('Makefile2');
|
||||
|
||||
# Make sure that all jobserver FDs are closed if we need to re-exec the
|
||||
# master copy.
|
||||
#
|
||||
|
||||
@@ -6,6 +6,9 @@ $details = "";
|
||||
# TEST #0: Test handing of '$' in prerequisites with and without second
|
||||
# expansion.
|
||||
|
||||
# If we don't support archives then the prerequisite is different
|
||||
my $prereq = exists $FEATURES{'archives'} ? '$' : '$(PRE)';
|
||||
|
||||
run_make_test(q!
|
||||
ifdef SE
|
||||
.SECONDEXPANSION:
|
||||
@@ -18,7 +21,7 @@ PRE = three four
|
||||
.DEFAULT: ; @echo '$@'
|
||||
!,
|
||||
'',
|
||||
"\$\nbar\$biz\nfoo\$bar : bar\$baz bar\$biz");
|
||||
"$prereq\nbar\$biz\nfoo\$bar : bar\$baz bar\$biz");
|
||||
|
||||
run_make_test(undef, 'SE=1', "three\nfour\nbariz\nfoo\$bar : baraz bariz");
|
||||
|
||||
|
||||
@@ -244,5 +244,17 @@ sim_%: \
|
||||
|
||||
unlink('a');
|
||||
|
||||
# Ensure that order-only tokens embedded in second expansions are parsed
|
||||
run_make_test(q!
|
||||
.SECONDEXPANSION:
|
||||
PREREQS=p1|p2
|
||||
P2=p2
|
||||
all : foo bar
|
||||
f%o: $$(PREREQS) ; @echo '$@' from '$^' and '$|'
|
||||
b%r: p1|$$(P2) ; @echo '$@' from '$^' and '$|'
|
||||
p% : ; : $@
|
||||
!,
|
||||
"", ": p1\n: p2\nfoo from p1 and p2\nbar from p1 and p2\n");
|
||||
|
||||
# This tells the test driver that the perl test script executed properly.
|
||||
1;
|
||||
|
||||
33
tests/scripts/options/print-directory
Normal file
33
tests/scripts/options/print-directory
Normal file
@@ -0,0 +1,33 @@
|
||||
# -*-perl-*-
|
||||
|
||||
$description = "Test the -w option to GNU make.";
|
||||
|
||||
# Simple test without -w
|
||||
run_make_test(q!
|
||||
all: ; @echo hi
|
||||
!,
|
||||
"", "hi\n");
|
||||
|
||||
# Simple test with -w
|
||||
run_make_test(undef, "-w",
|
||||
"#MAKE#: Entering directory '#PWD#'\nhi\n#MAKE#: Leaving directory '#PWD#'\n");
|
||||
|
||||
# Test makefile rebuild to ensure no enter/leave
|
||||
run_make_test(q!
|
||||
include foo
|
||||
all: ;@:
|
||||
foo: ; touch foo
|
||||
!,
|
||||
"", "#MAKEFILE#:2: foo: No such file or directory\ntouch foo\n");
|
||||
unlink('foo');
|
||||
|
||||
# Test makefile rebuild with -w
|
||||
run_make_test(q!
|
||||
include foo
|
||||
all: ;@:
|
||||
foo: ; touch foo
|
||||
!,
|
||||
"-w", "#MAKE#: Entering directory '#PWD#'\n#MAKEFILE#:2: foo: No such file or directory\ntouch foo\n#MAKE#: Leaving directory '#PWD#'\n");
|
||||
unlink('foo');
|
||||
|
||||
1;
|
||||
@@ -4,6 +4,10 @@ $description = "Test the behaviour of the .ONESHELL target.";
|
||||
|
||||
$details = "";
|
||||
|
||||
# Some shells (*shakes fist at Solaris*) cannot handle multiple flags in
|
||||
# separate arguments.
|
||||
my $t = `/bin/sh -e -c true 2>/dev/null`;
|
||||
my $multi_ok = $? == 0;
|
||||
|
||||
# Simple
|
||||
|
||||
@@ -19,7 +23,8 @@ all:
|
||||
|
||||
# Simple but use multi-word SHELLFLAGS
|
||||
|
||||
run_make_test(q!
|
||||
if ($multi_ok) {
|
||||
run_make_test(q!
|
||||
.ONESHELL:
|
||||
.SHELLFLAGS = -e -c
|
||||
all:
|
||||
@@ -29,6 +34,7 @@ all:
|
||||
'', 'a=$$
|
||||
[ 0"$a" -eq "$$" ] || echo fail
|
||||
');
|
||||
}
|
||||
|
||||
# Again, but this time with inner prefix chars
|
||||
|
||||
|
||||
@@ -23,4 +23,20 @@ all: ; @echo $(MAKEFLAGS)
|
||||
echo erR --trace --no-print-directory
|
||||
erR --trace --no-print-directory");
|
||||
|
||||
# Verify that re-exec / recursion doesn't duplicate flags from GNUMAKEFLAGS
|
||||
|
||||
unlink('x.mk');
|
||||
|
||||
$extraENV{GNUMAKEFLAGS} = '-Itst/bad -Oline';
|
||||
|
||||
run_make_test(q!
|
||||
recurse: ; @echo $@; echo MAKEFLAGS = $$MAKEFLAGS; echo GNUMAKEFLAGS = $$GNUMAKEFLAGS; #MAKEPATH# -f #MAKEFILE# all
|
||||
all: ; @echo $@; echo MAKEFLAGS = $$MAKEFLAGS; echo GNUMAKEFLAGS = $$GNUMAKEFLAGS
|
||||
-include x.mk
|
||||
x.mk: ; @echo $@; echo MAKEFLAGS = $$MAKEFLAGS; echo GNUMAKEFLAGS = $$GNUMAKEFLAGS; echo > $@
|
||||
!,
|
||||
"", "x.mk\nMAKEFLAGS = -Itst/bad -Oline\nGNUMAKEFLAGS =\nrecurse\nMAKEFLAGS = -Itst/bad -Oline\nGNUMAKEFLAGS =\n#MAKE#[1]: Entering directory '#PWD#'\nall\nMAKEFLAGS = w -Itst/bad -Oline\nGNUMAKEFLAGS =\n#MAKE#[1]: Leaving directory '#PWD#'\n");
|
||||
|
||||
unlink('x.mk');
|
||||
|
||||
1;
|
||||
|
||||
@@ -71,12 +71,20 @@ all: ; \@$script
|
||||
'', $out);
|
||||
|
||||
# Do it again but add spaces to SHELLFLAGS
|
||||
$flags = '-x -c';
|
||||
run_make_test(qq!
|
||||
|
||||
# Some shells (*shakes fist at Solaris*) cannot handle multiple flags in
|
||||
# separate arguments.
|
||||
my $t = `/bin/sh -e -c true 2>/dev/null`;
|
||||
my $multi_ok = $? == 0;
|
||||
|
||||
if ($multi_ok) {
|
||||
$flags = '-x -c';
|
||||
run_make_test(qq!
|
||||
.SHELLFLAGS = $flags
|
||||
all: ; \@$script
|
||||
!,
|
||||
'', $out);
|
||||
}
|
||||
|
||||
# We can't just use "false" because on different systems it provides a
|
||||
# different exit code--once again Solaris: false exits with 255 not 1
|
||||
|
||||
@@ -220,7 +220,7 @@ sub toplevel
|
||||
print "s" unless $total_tests_failed == 1;
|
||||
print " in $categories_failed Categor";
|
||||
print ($categories_failed == 1 ? "y" : "ies");
|
||||
print " Failed (See .$diffext files in $workdir dir for details) :-(\n\n";
|
||||
print " Failed (See .$diffext* files in $workdir dir for details) :-(\n\n";
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
@@ -752,6 +752,7 @@ sub attach_default_output
|
||||
open($dup, '>&', STDOUT) or error("ado: $! duping STDOUT\n", 1);
|
||||
push @OUTSTACK, $dup;
|
||||
|
||||
$dup = undef;
|
||||
open($dup, '>&', STDERR) or error("ado: $! duping STDERR\n", 1);
|
||||
push @ERRSTACK, $dup;
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -26,7 +26,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
#include "makeint.h"
|
||||
#include "job.h"
|
||||
|
||||
#ifdef OUTPUT_SYNC
|
||||
#ifndef NO_OUTPUT_SYNC
|
||||
/* Support for OUTPUT_SYNC and related functionality. */
|
||||
|
||||
/* Emulation of fcntl that supports only F_GETFD and F_SETLKW. */
|
||||
@@ -229,7 +229,7 @@ same_stream (FILE *f1, FILE *f2)
|
||||
/* Each process on Windows can have at most 1 console,
|
||||
so if both handles are for the console device, they
|
||||
are the same. We also compare the console mode to
|
||||
distinguish between tsdin and stdout/stderr. */
|
||||
distinguish between stdin and stdout/stderr. */
|
||||
if (GetConsoleMode (fh1, &conmode1)
|
||||
&& GetConsoleMode (fh2, &conmode2)
|
||||
&& conmode1 == conmode2)
|
||||
@@ -257,7 +257,7 @@ same_stream (FILE *f1, FILE *f2)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* OUTPUT_SYNC */
|
||||
#endif /* !NO_OUTPUT_SYNC */
|
||||
|
||||
#if MAKE_LOAD
|
||||
|
||||
|
||||
Reference in New Issue
Block a user