mirror of
https://git.savannah.gnu.org/git/make.git
synced 2025-06-22 00:00:29 -04:00
Compare commits
285 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
d523661ce2 | ||
|
f12a4fddce | ||
|
186522e480 | ||
|
aa8626ce09 | ||
|
93704dd565 | ||
|
101bf5636f | ||
|
9251546bac | ||
|
7dc23aff30 | ||
|
0267eb64fa | ||
|
bba4427b5d | ||
|
c23a7e6232 | ||
|
4d3bf7838f | ||
|
8c8c7fc226 | ||
|
9fee98f843 | ||
|
f800f8bae3 | ||
|
39a4c81062 | ||
|
d97e048b08 | ||
|
c63a5bc6a2 | ||
|
bc979e4949 | ||
|
6970561de0 | ||
|
f0db5e321f | ||
|
8653c25fcf | ||
|
4d883c414d | ||
|
034f862361 | ||
|
49b955a50d | ||
|
69038e62e0 | ||
|
a9e3eb1eec | ||
|
e3f938caf8 | ||
|
40664fef1f | ||
|
f7985ab827 | ||
|
8339232a2f | ||
|
949952258e | ||
|
479c54f6ed | ||
|
033330e34c | ||
|
61ee4578f5 | ||
|
f289ece6cf | ||
|
d791fb4139 | ||
|
0b91f42f58 | ||
|
882d59c672 | ||
|
5fc62f8295 | ||
|
3d4f3e0627 | ||
|
242603fa46 | ||
|
b8a2a4424b | ||
|
bfbf169b63 | ||
|
21a538ce8f | ||
|
3176b60566 | ||
|
07187db947 | ||
|
a493d9ab6c | ||
|
a382ac6cd1 | ||
|
63b602e74f | ||
|
ec348f51d0 | ||
|
51e56a028e | ||
|
1eff20f6f6 | ||
|
82708b3a3a | ||
|
828906b6dc | ||
|
b936970956 | ||
|
1e43a5d104 | ||
|
25049fef16 | ||
|
31036e648f | ||
|
1ff728bff4 | ||
|
1161779ef8 | ||
|
a80670ad41 | ||
|
d86448fe5f | ||
|
33932663b0 | ||
|
89bea82af3 | ||
|
dd1980426e | ||
|
2ce7e40822 | ||
|
b1e240c554 | ||
|
7fa40eb4fc | ||
|
8817efe46a | ||
|
66adfb7c6f | ||
|
9af3e60f4d | ||
|
8061929963 | ||
|
cd33c9a1e9 | ||
|
c4ecd9d9eb | ||
|
6b7f35cb0b | ||
|
1000374759 | ||
|
8d76fb8778 | ||
|
ee366afbf1 | ||
|
b686980c66 | ||
|
8e5c96c318 | ||
|
363bdaef8c | ||
|
b2bf660abc | ||
|
04f4c2b8d9 | ||
|
347316fdf6 | ||
|
1a03888afa | ||
|
07fcee35f0 | ||
|
c85b71a396 | ||
|
032f784601 | ||
|
78e6a89b19 | ||
|
1748e66414 | ||
|
8e0e6c678f | ||
|
3f28ec2f58 | ||
|
24a84f99bb | ||
|
05c86bfcb2 | ||
|
06c75a35b9 | ||
|
ebe0a1c9f1 | ||
|
0880e5c86a | ||
|
0e06c75889 | ||
|
5340a3d5d1 | ||
|
fec72ea308 | ||
|
6cf6311332 | ||
|
c4329fb953 | ||
|
971b02d58e | ||
|
fdd61fc068 | ||
|
80727d709c | ||
|
cd46baab90 | ||
|
54b3202f8d | ||
|
5111087e12 | ||
|
0552b0abc8 | ||
|
c2792d6129 | ||
|
a0d1e76d60 | ||
|
03ecd94488 | ||
|
2611e1991f | ||
|
9db74434cd | ||
|
23f70b0cb8 | ||
|
78c8c44326 | ||
|
caf1d4c28f | ||
|
f99d083418 | ||
|
a367c0640f | ||
|
3088e3e698 | ||
|
bf7f690202 | ||
|
5d1fe2b16d | ||
|
8285852e55 | ||
|
9b9f3351d1 | ||
|
6f3e9e9b84 | ||
|
6128c3e266 | ||
|
ceb52b5d1b | ||
|
d4692df20d | ||
|
e6bd61d949 | ||
|
fcefae5ec9 | ||
|
d66a65ad5a | ||
|
8093e2eee3 | ||
|
74dab224b3 | ||
|
8b8cc3a825 | ||
|
9b6fedef1c | ||
|
8ddb628927 | ||
|
e9dd614d73 | ||
|
f5dc17ac2d | ||
|
ac159491da | ||
|
4436655568 | ||
|
549fc56102 | ||
|
37e0010743 | ||
|
536c3e2b37 | ||
|
4c9b922560 | ||
|
2449ef3c88 | ||
|
fbf8c940e5 | ||
|
62194015fa | ||
|
c85f68c4e9 | ||
|
ffa28f3914 | ||
|
8f03e69af0 | ||
|
e819fc2022 | ||
|
f21cd822a3 | ||
|
2f336608d8 | ||
|
faedfdb0af | ||
|
9709d273b2 | ||
|
eb0bd1aaec | ||
|
d2bf740e77 | ||
|
a8890796a4 | ||
|
be6bb0fd68 | ||
|
db351fe85b | ||
|
8a0d7fd4ef | ||
|
f51fc130cc | ||
|
b99b6cdf3c | ||
|
36f955b0e8 | ||
|
a275f4e9ab | ||
|
11444fb001 | ||
|
0de7a0d3bf | ||
|
1656cd051c | ||
|
31a1337c23 | ||
|
5ae02ff8c1 | ||
|
1ceeb8c64b | ||
|
8791d2b38e | ||
|
f91b8bbb34 | ||
|
8dc66b6c31 | ||
|
ccbaf3861d | ||
|
c4fbfe8b5e | ||
|
e7ce3a655e | ||
|
c580ebae8d | ||
|
56d2978141 | ||
|
c91b269f66 | ||
|
29f453739f | ||
|
937e9aa32d | ||
|
8e9c7db1e1 | ||
|
15dfad96d7 | ||
|
76d2e5d98d | ||
|
a581146562 | ||
|
b2c7446023 | ||
|
89427039c3 | ||
|
7d8756a4a3 | ||
|
8e805c7ba6 | ||
|
132528b266 | ||
|
8f9e7722ff | ||
|
95c2db7b8d | ||
|
5d1b757517 | ||
|
c0023150f1 | ||
|
a89eef87e6 | ||
|
6164608900 | ||
|
a99183ed2b | ||
|
dc2d963989 | ||
|
53b8f6a5da | ||
|
6c1a6dd77c | ||
|
1b51ba1f5d | ||
|
4c9d87f4ae | ||
|
bb5df35133 | ||
|
92ab2e642d | ||
|
deb4ff272a | ||
|
e80ce6fc90 | ||
|
d71c0bb0ce | ||
|
090d99dd2d | ||
|
6b45f89adb | ||
|
11f7198f64 | ||
|
4321c5e562 | ||
|
ed493f6c91 | ||
|
7c3260bbdd | ||
|
38b19976f5 | ||
|
1dd52ab472 | ||
|
92789aa2e7 | ||
|
4e18732a1d | ||
|
11f9da227e | ||
|
b92340a1ea | ||
|
8064aee4f9 | ||
|
cf78e65fda | ||
|
04f0d8427f | ||
|
f8401ad28b | ||
|
e4b3bf7f97 | ||
|
d18a87d0a4 | ||
|
41c35f2ffe | ||
|
deb4a42c3e | ||
|
252c26bd20 | ||
|
6f8da5f4b8 | ||
|
c46b5a9e0e | ||
|
b4157d2ff4 | ||
|
f364e0d8d6 | ||
|
bb0c05a7f0 | ||
|
f987d181c4 | ||
|
cad3ddd165 | ||
|
54214176b1 | ||
|
c2f92c980f | ||
|
5b1ca277ca | ||
|
7c71df5695 | ||
|
a0956c1803 | ||
|
4ec74e568d | ||
|
d9fc1ac5d2 | ||
|
9f55e9fd13 | ||
|
7bb7bb4ba4 | ||
|
b79791533b | ||
|
9d24d41801 | ||
|
2d943d3d2e | ||
|
b16913a67e | ||
|
72ee43c473 | ||
|
e5e538fb7a | ||
|
c453f898a0 | ||
|
18c4b508ef | ||
|
383eb3a923 | ||
|
01b1d4f401 | ||
|
bf2d71498c | ||
|
3e20e376b7 | ||
|
7ddfc42ee3 | ||
|
ca92d83cde | ||
|
ae80eefe65 | ||
|
01142a53c9 | ||
|
dee6af912a | ||
|
7296991d6c | ||
|
d51ac70122 | ||
|
3cb84fe933 | ||
|
ad84ec2fdc | ||
|
26b9f30714 | ||
|
5ac80176a3 | ||
|
c801a7fb67 | ||
|
c2eddf9be2 | ||
|
f8852311cc | ||
|
a99378ebe4 | ||
|
6c87f3fb85 | ||
|
38116baee9 | ||
|
614033f8c6 | ||
|
f3640ecf4f | ||
|
c4e232e44f | ||
|
aa99e810a9 | ||
|
8f49029561 | ||
|
f7ed583675 | ||
|
cf7f7de7ae | ||
|
d4cb7ae6d4 | ||
|
387d349dc8 | ||
|
caad0e2181 |
4
.ccls
4
.ccls
@ -4,7 +4,6 @@ clang
|
||||
-Isrc
|
||||
-Ilib
|
||||
-DLIBDIR="/usr/local/lib"
|
||||
-DINCLUDEDIR="/usr/local/include"
|
||||
-DLOCALEDIR="/usr/local/share/locale"
|
||||
-DMAKE_MAINTAINER_MODE
|
||||
-pthread
|
||||
@ -13,7 +12,6 @@ clang
|
||||
-Wall
|
||||
-Wextra
|
||||
-Werror
|
||||
-Wno-address
|
||||
-Wwrite-strings
|
||||
-Wshadow
|
||||
-Wdeclaration-after-statement
|
||||
@ -26,3 +24,5 @@ clang
|
||||
-Wignored-qualifiers
|
||||
-Wformat-signedness
|
||||
-Wduplicated-cond
|
||||
-Wno-address
|
||||
-Wno-string-compare
|
||||
|
14
.clangd
Normal file
14
.clangd
Normal file
@ -0,0 +1,14 @@
|
||||
CompileFlags:
|
||||
Add: [-xc, -DHAVE_CONFIG_H, -DMAKE_MAINTAINER_MODE, -DLIBDIR="/usr/local/lib", -DLOCALEDIR="/usr/local/share/locale", -I../src, -Isrc, -I../lib, -Ilib, -Wall, -Wextra, -Wwrite-strings, -Wshadow, -Wdeclaration-after-statement, -Wbad-function-cast, -Wformat-security, -Wtype-limits, -Wunused-but-set-parameter, -Wlogical-op, -Wpointer-arith, -Wignored-qualifiers, -Wformat-signedness, -Wduplicated-cond, -Wno-string-compare, -Wno-unused-includes]
|
||||
|
||||
---
|
||||
If:
|
||||
PathMatch: .*\.h
|
||||
CompileFlags:
|
||||
Add: [-xc-header, --include=makeint.h]
|
||||
|
||||
---
|
||||
If:
|
||||
PathMatch: .*/makeint\.h
|
||||
Diagnostics:
|
||||
UnusedIncludes: None
|
@ -1,5 +1,5 @@
|
||||
(
|
||||
(nil . ((bug-reference-bug-regexp . "\\(\\)\\bSV[- ]\\([0-9]+\\)")
|
||||
(nil . ((bug-reference-bug-regexp . "\\(\\bSV[- ]\\([0-9]+\\)\\)")
|
||||
(bug-reference-url-format . "https://savannah.gnu.org/bugs/?%s")
|
||||
(ccls-initialization-options
|
||||
. (:index (:threads 6
|
||||
|
18
.gitignore
vendored
18
.gitignore
vendored
@ -34,10 +34,10 @@ config.log
|
||||
config.status
|
||||
configure
|
||||
/mk/Posix.mk
|
||||
stamp-h1
|
||||
stamp-*
|
||||
.dirstamp
|
||||
gnulib
|
||||
convert.sed
|
||||
*.sed
|
||||
|
||||
# Build artifacts
|
||||
.deps/
|
||||
@ -59,20 +59,20 @@ WinDebug/
|
||||
WinRel/
|
||||
GccDebug/
|
||||
GccRel/
|
||||
TccDebug/
|
||||
TccRel/
|
||||
|
||||
# Test artifacts
|
||||
makeerror-*
|
||||
test-suite.log
|
||||
|
||||
# Distribution artifacts
|
||||
.dep_segment
|
||||
.check-git-HEAD
|
||||
ChangeLog
|
||||
README
|
||||
README.DOS
|
||||
README.OS2
|
||||
README.W32
|
||||
build.cfg
|
||||
config.ami
|
||||
config.h-vms
|
||||
config.h.W32
|
||||
configh.dos
|
||||
mkconfig.h
|
||||
make-[0-9]*/
|
||||
make-[0-9]*.tar.*
|
||||
checkcfg.*.log
|
||||
|
37
AUTHORS
37
AUTHORS
@ -1,15 +1,17 @@
|
||||
-----------------------------------
|
||||
|
||||
GNU make development up to version 3.75 by:
|
||||
Roland McGrath <roland@gnu.org>
|
||||
|
||||
|
||||
Development starting with GNU make 3.76 by:
|
||||
GNU Make development starting with GNU Make 3.76 by:
|
||||
Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
Additional development starting with GNU make 3.81 by:
|
||||
Additional development starting with GNU Make 4.3 by:
|
||||
Dmitry Goncharov <dgoncharov@users.sf.net>
|
||||
|
||||
Additional development starting with GNU Make 3.81 by:
|
||||
Boris Kolpackov <boris@kolpackov.net>
|
||||
|
||||
GNU Make development up to version 3.75 by:
|
||||
Roland McGrath <roland@gnu.org>
|
||||
|
||||
GNU Make User's Manual
|
||||
Written by:
|
||||
Richard M. Stallman <rms@gnu.org>
|
||||
@ -21,7 +23,7 @@ GNU Make User's Manual
|
||||
Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
-----------------------------------
|
||||
GNU make porting efforts:
|
||||
GNU Make porting efforts:
|
||||
|
||||
Port to VMS by:
|
||||
Klaus Kaempf <kkaempf@progis.de>
|
||||
@ -30,9 +32,6 @@ GNU make porting efforts:
|
||||
John W. Eaton <jwe@bevo.che.wisc.edu>
|
||||
Martin Zinser <zinser@decus.decus.de>
|
||||
|
||||
Port to Amiga by:
|
||||
Aaron Digulla <digulla@fh-konstanz.de>
|
||||
|
||||
Port to MS-Windows (native/MinGW) maintained by:
|
||||
Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
@ -44,11 +43,17 @@ GNU make porting efforts:
|
||||
Andreas Beuning <andreas.buening@nexgo.de>
|
||||
Earnie Boyd <earnie@uses.sf.net>
|
||||
Troy Runkel <Troy.Runkel@mathworks.com>
|
||||
Juan M. Guerrero <juan.guerrero@gmx.de>
|
||||
KO Myung-Hun <komh78@gmail.com>
|
||||
|
||||
Port to z/OS by:
|
||||
Igor Todorovski <itodorov@ca.ibm.com>
|
||||
|
||||
-----------------------------------
|
||||
Other contributors:
|
||||
|
||||
Luke Allardyce <lukeallardyce@gmail.com>
|
||||
Costas Argyris <costas.argyris@gmail.com>
|
||||
Aron Barath <baratharon@caesar.elte.hu>
|
||||
David Boyce <dsb@boyski.com>
|
||||
Kevin Buettner <kevinb@redhat.com>
|
||||
@ -58,12 +63,14 @@ Other contributors:
|
||||
Joe Crayne <oh.hello.joe@gmail.com>
|
||||
Jeremy Devenport <jeremy.devenport@gmail.com>
|
||||
Pete Dietl <petedietl@gmail.com>
|
||||
Aaron Digulla <digulla@fh-konstanz.de>
|
||||
Hannes Domani <ssbssa@yahoo.de>
|
||||
Martin Dorey <martin.dorey@hds.com>
|
||||
Christian Eggers <ceggers@arri.de>
|
||||
Paul Eggert <eggert@twinsun.com>
|
||||
Mike Frysinger <vapier@gentoo.org>
|
||||
Ramon Garcia Fernandez <ramon.garcia.f@gmail.com>
|
||||
Dmitry Goncharov <dgoncharov@users.sf.net>
|
||||
Noah Goldstein <goldstein.w.n@gmail.com>
|
||||
Mike Haboustak <haboustak@gmail.com>
|
||||
Frank Heckenbach <f.heckenbach@fh-soft.de>
|
||||
Klaus Heinz <kamar@ease.rhein-main.de>
|
||||
@ -85,12 +92,14 @@ Other contributors:
|
||||
Thomas Riedl <thomas.riedl@siemens.com>
|
||||
Jaak Ristioja <jaak@ristioja.ee>
|
||||
Christoph Schulz <develop@kristov.de>
|
||||
Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
|
||||
Andreas Schwab <schwab@suse.de>
|
||||
spagoveanu <spagoveanu@gmail.com>
|
||||
Carl Staelin (Princeton University)
|
||||
Ian Stewartson (Data Logic Limited)
|
||||
Tobias Stoeckmann <tobias@stoeckmann.org>
|
||||
Torbjörn Svensson <torbjorn.svensson@foss.st.com>
|
||||
Sergei Trofimovich <siarheit@google.com>
|
||||
Justine Tunney <jtunney@gmail.com>
|
||||
Marc Ullman <marc@mathworks.com>
|
||||
Christof Warlich <cwarlich@gmx.de>
|
||||
Florian Weimer <fweimer@redhat.com>
|
||||
@ -103,7 +112,7 @@ With suggestions/comments/bug reports from a cast of ... well ...
|
||||
hundreds, anyway :)
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 1997-2022 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997-2024 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
@ -116,4 +125,4 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
@ -1,16 +1,16 @@
|
||||
# Basic GNU -*-Makefile-*- to build GNU make
|
||||
# Basic GNU -*-Makefile-*- to build GNU Make
|
||||
#
|
||||
# NOTE:
|
||||
# If you have no 'make' program at all to process this makefile:
|
||||
# * On Windows, run ".\buildw32.bat" to bootstrap one.
|
||||
# * On Windows, run ".\build_w32.bat" to bootstrap one.
|
||||
# * On MS-DOS, run ".\builddos.bat" to bootstrap one.
|
||||
#
|
||||
# Once you have a GNU make program created, you can use it with this makefile
|
||||
# Once you have a GNU Make program created, you can use it with this makefile
|
||||
# to keep it up to date if you make changes, as:
|
||||
#
|
||||
# make.exe -f Basic.mk
|
||||
#
|
||||
# Copyright (C) 2017-2022 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2017-2024 Free Software Foundation, Inc.
|
||||
# This file is part of GNU Make.
|
||||
#
|
||||
# GNU Make is free software; you can redistribute it and/or modify it under
|
||||
@ -24,7 +24,7 @@
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
# this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
all:
|
||||
|
||||
@ -37,9 +37,7 @@ loadavg_SOURCES = %loadavg_SOURCES%
|
||||
alloca_SOURCES = %alloca_SOURCES%
|
||||
w32_SOURCES = %w32_SOURCES%
|
||||
vms_SOURCES = %vms_SOURCES%
|
||||
amiga_SOURCES = %amiga_SOURCES%
|
||||
|
||||
posix_SOURCES = $(src)posixos.c
|
||||
remote_SOURCES = $(src)remote-stub.c
|
||||
|
||||
OUTDIR =
|
||||
@ -61,6 +59,8 @@ BUILT_SOURCES =
|
||||
|
||||
OBJECTS = $(patsubst %.c,$(OUTDIR)%.$(OBJEXT),$(prog_SOURCES))
|
||||
|
||||
RESOURCE_OBJECTS =
|
||||
|
||||
OBJDIRS = $(addsuffix .,$(sort $(dir $(OBJECTS))))
|
||||
|
||||
# Use the default value of CC
|
||||
@ -101,18 +101,16 @@ RM.cmd = rm -f $1
|
||||
# $(call CP.cmd,<from>,<to>)
|
||||
CP.cmd = cp $1 $2
|
||||
|
||||
CLEANSPACE = $(call RM.cmd,$(OBJECTS) $(PROG) $(BUILT_SOURCES))
|
||||
CLEANSPACE = $(call RM.cmd,$(OBJECTS) $(RESOURCE_OBJECTS) $(PROG) $(BUILT_SOURCES))
|
||||
|
||||
# Load overrides for the above variables.
|
||||
include $(firstword $(wildcard $(SRCDIR)/mk/$(lastword $(subst -, ,$(MAKE_HOST)).mk) $(OUTDIR)mk/Posix.mk $(SRCDIR)/mk/Posix.mk))
|
||||
|
||||
VERSION = %VERSION%
|
||||
include $(firstword $(wildcard $(SRCDIR)/mk/$(lastword $(subst -, ,$(MAKE_HOST)).mk)))
|
||||
|
||||
VPATH = $(SRCDIR)
|
||||
|
||||
all: $(PROG)
|
||||
|
||||
$(PROG): $(OBJECTS)
|
||||
$(PROG): $(OBJECTS) $(RESOURCE_OBJECTS)
|
||||
$(call LINK.cmd,$^)
|
||||
|
||||
$(OBJECTS): $(OUTDIR)%.$(OBJEXT): %.c
|
||||
|
@ -4994,4 +4994,4 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
@ -1322,7 +1322,7 @@
|
||||
non-standard versions of free() don't like it.
|
||||
|
||||
* configure.in (--enable-dmalloc): Install some support for using
|
||||
dmalloc (http://www.dmalloc.com/) with make. Use --enable-dmalloc
|
||||
dmalloc (https://www.dmalloc.com/) with make. Use --enable-dmalloc
|
||||
with configure to enable it.
|
||||
|
||||
* function.c (function_table_entry): Whoops! The function.c
|
||||
@ -6632,7 +6632,7 @@ Fri Nov 1 19:34:28 1991 Roland McGrath (roland@churchy.gnu.ai.mit.edu)
|
||||
|
||||
See ChangeLog.1, available in the Git repository at:
|
||||
|
||||
http://git.savannah.gnu.org/cgit/make.git/tree/
|
||||
https://git.savannah.gnu.org/cgit/make.git/tree/
|
||||
|
||||
for earlier changes.
|
||||
|
||||
@ -6650,4 +6650,4 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
10
ChangeLog.3
10
ChangeLog.3
@ -664,7 +664,7 @@
|
||||
characters in its name, pass NULL as the first argument to
|
||||
CreateProcess. This avoids weird failures due to buggy quoting by
|
||||
CreateProcess. For the details, see the discussion starting at
|
||||
http://lists.gnu.org/archive/html/make-w32/2013-04/msg00008.html.
|
||||
https://lists.gnu.org/archive/html/make-w32/2013-04/msg00008.html.
|
||||
|
||||
* load.c (load_object, load_file): Accept an additional argument
|
||||
DLP and return in it a pointer that can be used to unload the
|
||||
@ -706,7 +706,7 @@
|
||||
(construct_command_argv_internal): Don't treat a backslash as an
|
||||
escape character before whitespace, if the shell is not a Posix
|
||||
shell. For the description of the problem, see
|
||||
http://lists.gnu.org/archive/html/make-w32/2013-04/msg00014.html.
|
||||
https://lists.gnu.org/archive/html/make-w32/2013-04/msg00014.html.
|
||||
|
||||
2013-05-01 Paul Smith <psmith@gnu.org>
|
||||
|
||||
@ -1392,7 +1392,7 @@
|
||||
2011-09-16 Paul Smith <psmith@gnu.org>
|
||||
|
||||
* maintMakefile (do-po-update): Apparently we have to avoid
|
||||
certificate checks on the http://translationproject.org site now.
|
||||
certificate checks on the https://translationproject.org site now.
|
||||
|
||||
2011-09-12 Paul Smith <psmith@gnu.org>
|
||||
|
||||
@ -5612,7 +5612,7 @@
|
||||
|
||||
See ChangeLog.2, available in the Git repository at:
|
||||
|
||||
http://git.savannah.gnu.org/cgit/make.git/tree/
|
||||
https://git.savannah.gnu.org/cgit/make.git/tree/
|
||||
|
||||
for earlier changes.
|
||||
|
||||
@ -5630,4 +5630,4 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
84
Makefile.am
84
Makefile.am
@ -1,6 +1,6 @@
|
||||
# This is a -*-Makefile-*-, or close enough
|
||||
#
|
||||
# Copyright (C) 1997-2022 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1997-2024 Free Software Foundation, Inc.
|
||||
# This file is part of GNU Make.
|
||||
#
|
||||
# GNU Make is free software; you can redistribute it and/or modify it under
|
||||
@ -14,7 +14,7 @@
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
# this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
AUTOMAKE_OPTIONS = dist-lzip silent-rules std-options subdir-objects nostdinc
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
@ -34,10 +34,10 @@ make_SRCS = src/ar.c src/arscan.c src/commands.c src/commands.h \
|
||||
src/getopt.h src/getopt1.c src/gettext.h src/guile.c \
|
||||
src/hash.c src/hash.h src/implicit.c src/job.c src/job.h \
|
||||
src/load.c src/loadapi.c src/main.c src/makeint.h src/misc.c \
|
||||
src/os.h src/output.c src/output.h src/read.c src/remake.c \
|
||||
src/rule.c src/rule.h src/shuffle.h src/shuffle.c \
|
||||
src/mkcustom.h src/os.h src/output.c src/output.h src/read.c \
|
||||
src/remake.c src/rule.c src/rule.h src/shuffle.h src/shuffle.c \
|
||||
src/signame.c src/strcache.c src/variable.c src/variable.h \
|
||||
src/version.c src/vpath.c
|
||||
src/version.c src/vpath.c src/warning.c src/warning.h
|
||||
|
||||
w32_SRCS = src/w32/pathstuff.c src/w32/w32os.c src/w32/compat/dirent.c \
|
||||
src/w32/compat/posixfcn.c src/w32/include/dirent.h \
|
||||
@ -46,11 +46,11 @@ w32_SRCS = src/w32/pathstuff.c src/w32/w32os.c src/w32/compat/dirent.c \
|
||||
src/w32/subproc/misc.c src/w32/subproc/proc.h \
|
||||
src/w32/subproc/sub_proc.c src/w32/subproc/w32err.c
|
||||
|
||||
w32_utf8_SRCS = src/w32/utf8.rc src/w32/utf8.manifest
|
||||
|
||||
vms_SRCS = src/vms_exit.c src/vms_export_symbol.c src/vms_progname.c \
|
||||
src/vmsdir.h src/vmsfunctions.c src/vmsify.c
|
||||
|
||||
amiga_SRCS = src/amiga.c src/amiga.h
|
||||
|
||||
glob_SRCS = lib/fnmatch.c lib/fnmatch.h lib/glob.c lib/glob.h
|
||||
|
||||
alloca_SRCS = lib/alloca.c
|
||||
@ -58,7 +58,7 @@ alloca_SRCS = lib/alloca.c
|
||||
loadavg_SRCS = lib/getloadavg.c
|
||||
|
||||
make_SOURCES = $(make_SRCS)
|
||||
EXTRA_make_SOURCES = $(amiga_SRCS) $(vms_SRCS)
|
||||
EXTRA_make_SOURCES = $(vms_SRCS)
|
||||
|
||||
if HAVE_GUILE
|
||||
_GUILE_CFLAGS = $(GUILE_CFLAGS)
|
||||
@ -90,6 +90,15 @@ else
|
||||
make_SOURCES += src/posixos.c
|
||||
endif
|
||||
|
||||
UTF8OBJ = src/w32/utf8.$(OBJEXT)
|
||||
|
||||
if HAVE_WINDRES
|
||||
make_LDADD += $(UTF8OBJ)
|
||||
endif
|
||||
|
||||
$(UTF8OBJ) : $(w32_utf8_SRCS)
|
||||
$(WINDRES) -o $@ -i $<
|
||||
|
||||
if USE_CUSTOMS
|
||||
make_SOURCES += src/remote-cstms.c
|
||||
else
|
||||
@ -98,7 +107,7 @@ endif
|
||||
|
||||
# Extra stuff to include in the distribution.
|
||||
|
||||
mk_FILES = Basic.mk mk/msdosdjgpp.mk mk/Amiga.mk mk/VMS.mk mk/Windows32.mk
|
||||
mk_FILES = Basic.mk mk/msdosdjgpp.mk mk/VMS.mk mk/Windows32.mk
|
||||
# We don't need this, since the standard automake output will do.
|
||||
#mk/Posix.mk.in
|
||||
|
||||
@ -112,14 +121,13 @@ test_FILES = tests/run_make_tests tests/run_make_tests.bat \
|
||||
# test/scripts are added via dist-hook below.
|
||||
|
||||
EXTRA_DIST = ChangeLog INSTALL README build.sh build.cfg.in $(man_MANS) \
|
||||
README.customs README.OS2 \
|
||||
README.Amiga SCOPTIONS src/config.ami \
|
||||
src/mkconfig.h README.customs README.OS2 README.zOS \
|
||||
README.DOS builddos.bat src/configh.dos \
|
||||
README.W32 build_w32.bat src/config.h.W32 \
|
||||
README.VMS makefile.com src/config.h-vms src/vmsjobs.c \
|
||||
vms_export_symbol_test.com \
|
||||
src/gmk-default.scm src/gmk-default.h \
|
||||
$(mk_FILES) $(m4_FILES) $(test_FILES)
|
||||
$(mk_FILES) $(m4_FILES) $(test_FILES) $(w32_utf8_SRCS)
|
||||
|
||||
# --------------- Generate the Guile default module content
|
||||
|
||||
@ -137,14 +145,14 @@ src/gmk-default.h: $(top_srcdir)/src/gmk-default.scm
|
||||
dist-hook:
|
||||
(cd $(top_srcdir); \
|
||||
sub=`find tests/scripts -follow \( -name .git -o -name .deps -o -name work -o -name .gitignore -o -name \*.orig -o -name \*.rej -o -name \*~ -o -name \*.out -o -name Makefile \) -prune -o -type f -print`; \
|
||||
tar chf - $$sub) \
|
||||
| (cd $(distdir); tar xfBp -)
|
||||
$(AMTAR) chf - $$sub) \
|
||||
| (cd $(distdir); $(AMTAR) xfBp -)
|
||||
|
||||
|
||||
# --------------- Local CHECK Section
|
||||
|
||||
check-local: check-regression
|
||||
@banner=" Regression PASSED: GNU Make $(VERSION) ($(MAKE_HOST)) built with $(CC) "; \
|
||||
@banner=" Regression PASSED: $(PACKAGE_STRING) ($(MAKE_HOST)) built with $(CC) "; \
|
||||
dashes=`echo "$$banner" | sed s/./=/g`; \
|
||||
echo; \
|
||||
echo "$$dashes"; \
|
||||
@ -155,34 +163,50 @@ check-local: check-regression
|
||||
# > check-regression
|
||||
#
|
||||
# Look for the make test suite, and run it if found and we can find perl.
|
||||
# If we're building outside the tree, we use symlinks to make a local copy of
|
||||
# the test suite. Unfortunately the test suite itself isn't localizable yet.
|
||||
#
|
||||
MAKETESTFLAGS =
|
||||
|
||||
.PHONY: check-regression
|
||||
|
||||
GMK_OUTDIR=..
|
||||
GMK_OUTDIR = ..
|
||||
|
||||
testlog = test-suite.log
|
||||
testresult = tests/.test-result
|
||||
errorpre = makeerror-$(PACKAGE_VERSION)-$(host_triplet)
|
||||
|
||||
testfiles = $(testlog) $(testresult) $(errorfile)
|
||||
MOSTLYCLEANFILES = $(testfiles)
|
||||
|
||||
errordetails = config.status config.log src/config.h src/mkconfig.h \
|
||||
$(testlog) tests/work
|
||||
|
||||
# Create a 4-letter random sequence
|
||||
rand_value = c = "abcdefghijklmnopqrstuvwxyz0123456789"
|
||||
rand_char = substr(c,int(rand()*36),1)
|
||||
rand_string = $(AWK) 'BEGIN{srand(); $(rand_value); print $(rand_char) "" $(rand_char) "" $(rand_char) "" $(rand_char);}'
|
||||
|
||||
check-regression: tests/config-flags.pm
|
||||
@if test -f '$(top_srcdir)/tests/run_make_tests'; then \
|
||||
$(AM_V_at) rm -f $(testfiles)
|
||||
$(AM_V_at) if test -f '$(top_srcdir)/tests/run_make_tests.pl'; then \
|
||||
ulimit -n 128; \
|
||||
if $(PERL) -v >/dev/null 2>&1; then \
|
||||
case `cd '$(top_srcdir)'; pwd` in `pwd`) : ;; \
|
||||
*) test -d tests || mkdir tests; \
|
||||
rm -f srctests; \
|
||||
if ln -s '$(top_srcdir)/tests' srctests; then \
|
||||
for f in run_make_tests run_make_tests.pl test_driver.pl scripts thelp.pl; do \
|
||||
rm -f tests/$$f; ln -s ../srctests/$$f tests; \
|
||||
done; fi ;; \
|
||||
esac; \
|
||||
echo "cd tests && $(PERL) $(PERLFLAGS) ./run_make_tests.pl -srcdir $(abs_top_srcdir) -make $(GMK_OUTDIR)/make$(EXEEXT) $(MAKETESTFLAGS)"; \
|
||||
cd tests && $(PERL) $(PERLFLAGS) ./run_make_tests.pl -srcdir '$(abs_top_srcdir)' -make '$(GMK_OUTDIR)/make$(EXEEXT)' $(MAKETESTFLAGS); \
|
||||
echo "cd tests && $(PERL) $(PERLFLAGS) $(abs_top_srcdir)/tests/run_make_tests.pl -make $(GMK_OUTDIR)/make$(EXEEXT) $(MAKETESTFLAGS)"; \
|
||||
(cd tests && $(PERL) $(PERLFLAGS) '$(abs_top_srcdir)/tests/run_make_tests.pl' -make '$(GMK_OUTDIR)/make$(EXEEXT)' $(MAKETESTFLAGS); echo $$? >.test-result) 2>&1 | tee $(testlog); \
|
||||
export TAR_OPTIONS='$(filter-out --sort%,$(TAR_OPTIONS))'; \
|
||||
er=$$(cat $(testresult)); if test "$$er" -ne 0; then \
|
||||
dirnm="$(errorpre)-$$($(rand_string))"; fnm="$$dirnm.tar.gz"; \
|
||||
rm -rf "$$dirnm"; mkdir "$$dirnm"; \
|
||||
$(AMTAR) chf - $(errordetails) | (cd "$$dirnm"; $(AMTAR) xf -); \
|
||||
$(AMTAR) chf - "$$dirnm" | eval GZIP= gzip $(GZIP_ENV) -c >"$$fnm"; \
|
||||
echo "*** Testing FAILED! Details: $$fnm"; \
|
||||
echo '*** Please report to <$(PACKAGE_BUGREPORT)>'; echo; \
|
||||
exit $$er; \
|
||||
fi; \
|
||||
else \
|
||||
echo "Can't find a working Perl ($(PERL)); the test suite requires Perl."; \
|
||||
fi; \
|
||||
else \
|
||||
echo "Can't find the GNU Make test suite ($(top_srcdir)/tests)."; \
|
||||
echo "Can't find the $(PACKAGE_NAME) test suite ($(top_srcdir)/tests)."; \
|
||||
fi
|
||||
|
||||
|
||||
|
340
NEWS
340
NEWS
@ -1,20 +1,186 @@
|
||||
GNU make NEWS -*-indented-text-*-
|
||||
GNU Make NEWS -*-indented-text-*-
|
||||
History of user-visible changes.
|
||||
20 September 2022
|
||||
26 February 2023
|
||||
|
||||
See the end of this file for copyrights and conditions.
|
||||
|
||||
All user-visible changes are more fully described in the GNU make manual,
|
||||
All user-visible changes are more fully described in the GNU Make manual,
|
||||
which is contained in this distribution as the file doc/make.texi.
|
||||
See the README file and the GNU make manual for instructions for
|
||||
See the README file and the GNU Make manual for instructions for
|
||||
reporting bugs.
|
||||
|
||||
|
||||
Version 4.3.90 (20 Sep 2022)
|
||||
Version 4.4.90 (26 Feb 2023)
|
||||
|
||||
A complete list of bugs fixed in this version is available here:
|
||||
|
||||
https://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=111&set=custom
|
||||
|
||||
* WARNING: Removed AmigaOS support!
|
||||
This version of GNU Make no longer supports AmigaOS. If you need support
|
||||
for AmigaOS please use one of the older versions of GNU Make.
|
||||
|
||||
* WARNING: Loaded Object ABI incompatibility!
|
||||
This release changes the loaded object feature from "technology preview" to
|
||||
fully-supported feature. However, it introduces an ABI incompatibility with
|
||||
previous releases: the setup function now takes an ABI version as its first
|
||||
argument. At compile time you can test the GMK_ABI_VERSION constant to
|
||||
detect which ABI should be used. At runtime your initialization function
|
||||
can check the provided ABI version to verify it's being loaded correctly.
|
||||
|
||||
* WARNING: Backward-incompatibility!
|
||||
Parsing of the first argument in ifeq/ifneq with () has been cleaned up.
|
||||
When locating the separating "," any variable reference (single char as well
|
||||
as using $() or ${}) is skipped. However parentheses that are not part of
|
||||
or contained in variable references will not be counted. This means that
|
||||
things like "ifeq ((foo,bar),)" are now syntax errors. Use a variable to
|
||||
hide the comma if needed: "COMMA = ," / "ifeq ((foo$(COMMA)bar),)".
|
||||
See https://savannah.gnu.org/bugs/index.php?64402
|
||||
|
||||
* WARNING: Backward-incompatibility!
|
||||
If -e is given all environment variables will now have an origin of
|
||||
"environment override" even if they are not otherwise set in the makefile.
|
||||
See https://savannah.gnu.org/bugs/index.php?64803
|
||||
|
||||
* WARNING: Backward-incompatibility!
|
||||
The behavior of appending to pattern-specific variables has been clarified
|
||||
when combined with command-line settings or -e overrides.
|
||||
See https://savannah.gnu.org/bugs/index.php?64822
|
||||
|
||||
* NOTE: Deprecated behavior.
|
||||
The check in GNU Make 4.3 for suffix rules with prerequisites didn't check
|
||||
single-suffix rules, only double-suffix rules. Add the missing check.
|
||||
|
||||
* New feature: Any assignment operator can be made conditional
|
||||
GNU Make has long supported the conditional operator "?=" which creates a
|
||||
recursive variable set to a value if and only if the variable is not already
|
||||
defined. In this release, the "?" can precede any assignment operator to
|
||||
make it conditional. For example, "?:=" creates a simply-expanded variable
|
||||
and expands the right-hand side if and only if the variable is not already
|
||||
defined. The constructs "?::=", "?:::=", and "?!=" also behave as expected.
|
||||
|
||||
* New feature: Unload function for loaded objects
|
||||
When a loaded object needs to be unloaded by GNU Make, it will invoke an
|
||||
unload function (if one is defined) beforehand that allows the object to
|
||||
perform cleanup operations.
|
||||
Original idea and implementation: Dmitry Goncharov <dgoncharov@users.sf.net>
|
||||
|
||||
* New feature: Makefile warning reporting control
|
||||
A new option "--warn" controls reporting of warnings for makefiles. Actions
|
||||
can be set to "ignore", "warn", or "error". Two new warnings are reported:
|
||||
assigning to invalid variable names, and referencing invalid variable names
|
||||
(both set to "warn" by default), in addition to the existing warning for
|
||||
undefined variables (defaults to "ignore"). "--warn-undefined-variables" is
|
||||
deprecated, and is translated to "--warn=undefined-vars" internally.
|
||||
|
||||
* New feature: Control warnings with the .WARNINGS variable
|
||||
In addition to --warn from the command line, which takes effect for make
|
||||
invoked recursively, warnings can be controlled only for the current
|
||||
instance of make using the .WARNINGS variable.
|
||||
|
||||
* New feature: Printing targets defined by the makefile
|
||||
A new option "--print-targets" will print all explicit, non-special targets
|
||||
defined in the makefiles, one per line, then exit with success. No recipes
|
||||
are invoked and no makefiles are re-built.
|
||||
|
||||
* Warnings for detecting circular dependencies are controllable via warning
|
||||
reporting, with the name "circular-dep".
|
||||
|
||||
* 'make --print-data-base' (or 'make -p') now outputs time of day
|
||||
using the same form as for file timestamps, e.g., "2023-05-10
|
||||
10:43:57.570558743". Previously it used the form "Wed May 10
|
||||
10:43:57 2023", which has less detail and is harder to compare.
|
||||
|
||||
* Conditional statements starting with the recipe prefix were sometimes
|
||||
interpreted in previous versions. As per the documentation, lines starting
|
||||
with the recipe prefix are now never considered conditional statements.
|
||||
|
||||
* Tests in the regression test suite now are run in their own directory to
|
||||
avoid cross-contamination and allow cleanup if the tests are interrupted.
|
||||
More information is printed about failing tests.
|
||||
|
||||
|
||||
Version 4.4.1 (26 Feb 2023)
|
||||
|
||||
This release is primarily a bug-fix release.
|
||||
A complete list of bugs fixed in this version is available here:
|
||||
|
||||
https://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=110&set=custom
|
||||
|
||||
* WARNING: Backward-incompatibility!
|
||||
In previous releases it was not well-defined when updates to MAKEFLAGS made
|
||||
inside a makefile would be visible. This release ensures they are visible
|
||||
immediately, even when invoking $(shell ...) functions. Also, command line
|
||||
variable assignments are now always present in MAKEFLAGS, even when parsing
|
||||
makefiles.
|
||||
Implementation provided by Dmitry Goncharov <dgoncharov@users.sf.net>
|
||||
|
||||
* New feature: Parallel builds of archives
|
||||
Previously it was not possible to use parallel builds with archives. It is
|
||||
still not possible using the built-in rules, however you can now override
|
||||
the built-in rules with a slightly different set of rules and use parallel
|
||||
builds with archive creation. See the "Dangers When Using Archives" section
|
||||
of the GNU Make manual, and https://savannah.gnu.org/bugs/index.php?14927
|
||||
|
||||
* Previously target-specific variables would inherit their "export" capability
|
||||
from parent target-specific variables even if they were marked private. Now
|
||||
private parent target-specific variables have no affect. For more details
|
||||
see https://savannah.gnu.org/bugs/index.php?61463
|
||||
|
||||
* Disable FIFO jobserver on GNU/Hurd and Cygwin
|
||||
Experimentation shows that the new FIFO-based jobserver doesn't work well on
|
||||
GNU/Hurd or Cygwin: revert these systems to use the pipe-based jobserver.
|
||||
|
||||
* Updates to allow building on OS/2
|
||||
Provided by KO Myung-Hun <komh78@gmail.com>
|
||||
|
||||
* New platform: GNU Make is supported on z/OS
|
||||
Thanks to Igor Todorovski <itodorov@ca.ibm.com> for the patches and testing
|
||||
assistance.
|
||||
|
||||
|
||||
Version 4.4 (31 Oct 2022)
|
||||
|
||||
A complete list of bugs fixed in this version is available here:
|
||||
|
||||
https://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=109&set=custom
|
||||
|
||||
* WARNING: Deprecation!
|
||||
The following systems are deprecated in this release:
|
||||
- OS/2 (EMX)
|
||||
- AmigaOS
|
||||
- Xenix
|
||||
- Cray
|
||||
In the NEXT release of GNU Make, support for these systems will be removed.
|
||||
If you want to see them continue to be supported, contact <bug-make@gnu.org>.
|
||||
|
||||
* WARNING: Future backward-incompatibility!
|
||||
In the NEXT release of GNU Make, pattern rules will implement the same
|
||||
behavior change for multiple targets as explicit grouped targets, below: if
|
||||
any target of the rule is needed by the build, the recipe will be invoked if
|
||||
any target of the rule is missing or out of date. During testing some
|
||||
makefiles were found to contain pattern rules that do not build all targets;
|
||||
this can cause issues so we are delaying this change for one release cycle
|
||||
to allow these makefiles to be updated. GNU Make shows a warning if it
|
||||
detects this situation: "pattern recipe did not update peer target".
|
||||
|
||||
* WARNING: Backward-incompatibility!
|
||||
GNU Make now uses temporary files in more situations than previous releases.
|
||||
If your build system sets TMPDIR (or TMP or TEMP on Windows) and deletes the
|
||||
contents during the build, or uses restrictive permissions, this may cause
|
||||
problems. You can choose an alternative temporary directory only for use by
|
||||
GNU Make by setting the new MAKE_TMPDIR environment variable before invoking
|
||||
make. Note that this value CANNOT be set inside the makefile, since make
|
||||
needs to find its temporary directory before the makefiles are parsed.
|
||||
|
||||
* WARNING: Backward-incompatibility!
|
||||
Previously each target in a explicit grouped target rule was considered
|
||||
individually: if the targets needed by the build were not out of date the
|
||||
recipe was not run even if other targets in the group were out of date. Now
|
||||
if any of the grouped targets are needed by the build, then if any of the
|
||||
grouped targets are out of date the recipe is run and all targets in the
|
||||
group are considered updated.
|
||||
|
||||
* WARNING: Backward-incompatibility!
|
||||
Previously if --no-print-directory was seen anywhere in the environment or
|
||||
command line it would take precedence over any --print-directory. Now, the
|
||||
@ -26,7 +192,7 @@ https://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=109&se
|
||||
stated, but it was (roughly) the inverse of the order in which they were
|
||||
processed by make. In this release, the order in which makefiles are
|
||||
rebuilt is the same order in which make processed them, and this is defined
|
||||
to be true in the GNU make manual.
|
||||
to be true in the GNU Make manual.
|
||||
|
||||
* WARNING: Backward-incompatibility!
|
||||
Previously only simple (one-letter) options were added to the MAKEFLAGS
|
||||
@ -43,14 +209,14 @@ https://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=109&se
|
||||
To detect this change search for 'shell-export' in the .FEATURES variable.
|
||||
|
||||
* WARNING: New build requirement
|
||||
GNU make utilizes facilities from GNU Gnulib: Gnulib requires certain C99
|
||||
features in the C compiler and so these features are required by GNU make:
|
||||
GNU Make utilizes facilities from GNU Gnulib: Gnulib requires certain C99
|
||||
features in the C compiler and so these features are required by GNU Make:
|
||||
https://www.gnu.org/software/gnulib/manual/html_node/C99-features-assumed.html
|
||||
The configure script should verify the compiler has these features.
|
||||
|
||||
* New feature: The .WAIT special target
|
||||
If the .WAIT target appears between two prerequisites of a target, then
|
||||
GNU make will wait for all of the targets to the left of .WAIT in the list
|
||||
GNU Make will wait for all of the targets to the left of .WAIT in the list
|
||||
to complete before starting any of the targets to the right of .WAIT.
|
||||
This feature is available in some other versions of make, and it will be
|
||||
required by an upcoming version of the POSIX standard for make.
|
||||
@ -64,7 +230,7 @@ https://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=109&se
|
||||
each prerequisite).
|
||||
|
||||
* New feature: The .NOTINTERMEDIATE special target
|
||||
.NOTINTERMEDIATE Disables intermediate behavior for specific files, for all
|
||||
.NOTINTERMEDIATE disables intermediate behavior for specific files, for all
|
||||
files built using a pattern, or for the entire makefile.
|
||||
Implementation provided by Dmitry Goncharov <dgoncharov@users.sf.net>
|
||||
|
||||
@ -80,7 +246,7 @@ https://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=109&se
|
||||
Implementation provided by Jouke Witteveen <j.witteveen@gmail.com>
|
||||
|
||||
* New feature: Improved support for -l / --load-average
|
||||
On systems that provide /proc/loadavg (Linux), GNU make will use it to
|
||||
On systems that provide /proc/loadavg (Linux), GNU Make will use it to
|
||||
determine the number of runnable jobs and use this as the current load,
|
||||
avoiding the need for heuristics.
|
||||
Implementation provided by Sven C. Dack <sdack@gmx.com>
|
||||
@ -95,24 +261,16 @@ https://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=109&se
|
||||
* New feature: The --jobserver-style command line option and named pipes
|
||||
A new jobserver method is used on systems where mkfifo(3) is supported.
|
||||
This solves a number of obscure issues related to using the jobserver
|
||||
and recursive invocations of GNU make. This change means that sub-makes
|
||||
and recursive invocations of GNU Make. This change means that sub-makes
|
||||
will connect to the jobserver even if they are not marked as recursive.
|
||||
It also means that other tools that want to participate in the jobserver
|
||||
will need to be enhanced as described in the GNU make manual.
|
||||
You can force GNU make to use the simple pipe-based jobserver (perhaps if
|
||||
you are integrating with other tools or older versions of GNU make) by
|
||||
will need to be enhanced as described in the GNU Make manual.
|
||||
You can force GNU Make to use the simple pipe-based jobserver (perhaps if
|
||||
you are integrating with other tools or older versions of GNU Make) by
|
||||
adding the '--jobserver-style=pipe' option to the command line of the
|
||||
top-level invocation of GNU make, or via MAKEFLAGS or GNUMAKEFLAGS.
|
||||
top-level invocation of GNU Make, or via MAKEFLAGS or GNUMAKEFLAGS.
|
||||
To detect this change search for 'jobserver-fifo' in the .FEATURES variable.
|
||||
|
||||
* New feature: The MAKE_TMPDIR environment variable
|
||||
If you prefer that GNU make place temporary files in a different directory
|
||||
than the standard TMPDIR (or TMP or TEMP on Windows), set the MAKE_TMPDIR
|
||||
environment variable before starting make (this value CANNOT be set inside
|
||||
the makefile, since make needs to find its temporary directory before the
|
||||
makefiles are parsed). This is useful for build systems which reset TMPDIR
|
||||
and clean it out during the build process.
|
||||
|
||||
* Some POSIX systems (*BSD) do not allow locks to be taken on pipes, which
|
||||
caused the output sync feature to not work properly there. Also multiple
|
||||
invocations of make redirecting to the same output file (e.g., /dev/null)
|
||||
@ -120,16 +278,16 @@ https://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=109&se
|
||||
performance characteristics, but is not portable) create a temporary file
|
||||
and lock that. Windows continues to use a mutex as before.
|
||||
|
||||
* GNU make has sometimes chosen unexpected, and sub-optimal, chains of
|
||||
* GNU Make has sometimes chosen unexpected, and sub-optimal, chains of
|
||||
implicit rules due to the definition of "ought to exist" in the implicit
|
||||
rule search algorithm, which considered any prerequisite mentioned in the
|
||||
makefile as "ought to exist". This algorithm has been modified to prefer
|
||||
prerequisites mentioned explicitly in the target being built and only if
|
||||
that results in no matching rule, will GNU make consider prerequisites
|
||||
that results in no matching rule, will GNU Make consider prerequisites
|
||||
mentioned in other targets as "ought to exist".
|
||||
Implementation provided by Dmitry Goncharov <dgoncharov@users.sf.net>
|
||||
|
||||
* GNU make was performing secondary expansion of all targets, even targets
|
||||
* GNU Make was performing secondary expansion of all targets, even targets
|
||||
which didn't need to be considered during the build. In this release
|
||||
only targets which are considered will be secondarily expanded.
|
||||
Implementation provided by Dmitry Goncharov <dgoncharov@users.sf.net>
|
||||
@ -141,7 +299,7 @@ https://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=109&se
|
||||
|
||||
* The -I option accepts an argument "-" (e.g., "-I-") which means "reset the
|
||||
list of search directories to empty". Among other things this can be used
|
||||
to prevent GNU make from searching in its default list of directories.
|
||||
to prevent GNU Make from searching in its default list of directories.
|
||||
|
||||
* New debug option "print" will show the recipe to be run, even when silent
|
||||
mode is set, and new debug option "why" will show why a target is rebuilt
|
||||
@ -158,9 +316,9 @@ https://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=109&se
|
||||
* Special targets like .POSIX are detected upon definition, ensuring that any
|
||||
change in behavior takes effect immediately, before the next line is parsed.
|
||||
|
||||
* When the jobserver is enabled and GNU make decides it is invoking a non-make
|
||||
sub-process and closes the jobserver pipes, it will now add a new option to
|
||||
the MAKEFLAGS environment variable that disables the jobserver.
|
||||
* When the pipe-based jobserver is enabled and GNU Make decides it is invoking
|
||||
a non-make sub-process and closes the jobserver pipes, it will now add a new
|
||||
option to the MAKEFLAGS environment variable that disables the jobserver.
|
||||
This prevents sub-processes that invoke make from accidentally using other
|
||||
open file descriptors as jobserver pipes. For more information see
|
||||
https://savannah.gnu.org/bugs/?57242 and https://savannah.gnu.org/bugs/?62397
|
||||
@ -217,7 +375,7 @@ https://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=108&se
|
||||
warning about this behavior is generated:
|
||||
warning: ignoring prerequisites on suffix rule definition
|
||||
The POSIX behavior will be adopted as the only behavior in a future release
|
||||
of GNU make so please resolve any warnings.
|
||||
of GNU Make so please resolve any warnings.
|
||||
|
||||
* New feature: Grouped explicit targets
|
||||
Pattern rules have always had the ability to generate multiple targets with
|
||||
@ -238,7 +396,7 @@ https://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=108&se
|
||||
* Makefiles can now specify the '-j' option in their MAKEFLAGS variable and
|
||||
this will cause make to enable that parallelism mode.
|
||||
|
||||
* GNU make will now use posix_spawn() on systems where it is available.
|
||||
* GNU Make will now use posix_spawn() on systems where it is available.
|
||||
If you prefer to use fork/exec even on systems where posix_spawn() is
|
||||
present, you can use the --disable-posix-spawn option to configure.
|
||||
Implementation contributed by Aron Barath <baratharon@caesar.elte.hu>
|
||||
@ -255,17 +413,17 @@ https://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=108&se
|
||||
|
||||
* A new option -E has been added as a short alias for --eval.
|
||||
|
||||
* All wildcard expansion within GNU make, including $(wildcard ...), will sort
|
||||
* All wildcard expansion within GNU Make, including $(wildcard ...), will sort
|
||||
the results. See https://savannah.gnu.org/bugs/index.php?52076
|
||||
|
||||
* Interoperate with newer GNU libc and musl C runtime libraries.
|
||||
|
||||
* Performance improvements provided by Paolo Bonzini <pbonzini@redhat.com>
|
||||
|
||||
GNU make Developer News
|
||||
GNU Make Developer News
|
||||
|
||||
* Import the GNU standard bootstrap script to replace the hand-rolled
|
||||
"make update" method for building code from a GNU make Git repository.
|
||||
"make update" method for building code from a GNU Make Git repository.
|
||||
|
||||
* Rework the source distribution to move source files into the src/*
|
||||
subdirectory. This aligns with modern best practices in GNU.
|
||||
@ -299,11 +457,11 @@ https://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=106&se
|
||||
The function is expanded to the contents of the file. The contents are
|
||||
expanded verbatim except that the final newline, if any, is stripped.
|
||||
|
||||
* The makefile line numbers shown by GNU make now point directly to the
|
||||
* The makefile line numbers shown by GNU Make now point directly to the
|
||||
specific line in the recipe where the failure or warning occurred.
|
||||
Sample changes suggested by Brian Vandenberg <phantall@gmail.com>
|
||||
|
||||
* The interface to GNU make's "jobserver" is stable as documented in the
|
||||
* The interface to GNU Make's "jobserver" is stable as documented in the
|
||||
manual, for tools which may want to access it.
|
||||
|
||||
WARNING: Backward-incompatibility! The internal-only command line option
|
||||
@ -338,7 +496,7 @@ https://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=105&se
|
||||
requested mode, then closed again.
|
||||
|
||||
* Change the fatal error for mixed explicit and implicit rules, that was
|
||||
introduced in GNU make 3.82, to a non-fatal error. However, this syntax is
|
||||
introduced in GNU Make 3.82, to a non-fatal error. However, this syntax is
|
||||
still deprecated and may return to being illegal in a future version of GNU
|
||||
make. Makefiles that rely on this syntax should be fixed.
|
||||
See https://savannah.gnu.org/bugs/?33034
|
||||
@ -386,7 +544,7 @@ https://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=101&se
|
||||
single space
|
||||
|
||||
* New feature: GNU Guile integration
|
||||
This version of GNU make can be compiled with 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
|
||||
@ -418,20 +576,20 @@ https://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=101&se
|
||||
* 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.
|
||||
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
|
||||
between the "!" and "=": "variable! = value"
|
||||
|
||||
* New feature: "::=" simple assignment operator as defined by POSIX in 2012.
|
||||
This operator has identical functionality to ":=" in GNU make, but will be
|
||||
This operator has identical functionality to ":=" in GNU Make, but will be
|
||||
portable to any implementation of make conforming to a sufficiently new
|
||||
version of POSIX (see http://austingroupbugs.net/view.php?id=330). It is
|
||||
version of POSIX (see https://austingroupbugs.net/view.php?id=330). It is
|
||||
not necessary to define the .POSIX target to access this operator.
|
||||
|
||||
* New feature: Loadable objects
|
||||
This version of GNU make contains a "technology preview": the ability to
|
||||
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
|
||||
the user and can add extended functionality, usable by makefiles.
|
||||
|
||||
@ -439,8 +597,8 @@ https://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=101&se
|
||||
|
||||
* 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. Once this variable is parsed, GNU make will set it to the
|
||||
GNU Make-specific flags to allow your makefile to be portable to other
|
||||
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
|
||||
@ -481,7 +639,7 @@ A complete list of bugs fixed in this version is available here:
|
||||
|
||||
https://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=104&set=custom
|
||||
|
||||
* Compiling GNU make now requires a conforming ISO C 1989 compiler and
|
||||
* Compiling GNU Make now requires a conforming ISO C 1989 compiler and
|
||||
standard runtime library.
|
||||
|
||||
* WARNING: Backward-incompatibility!
|
||||
@ -489,7 +647,7 @@ https://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=104&se
|
||||
fundamentally incompatible way: make is required to invoke the shell as if
|
||||
the '-e' flag were provided. Because this would break many makefiles that
|
||||
have been written to conform to the original text of the standard, the
|
||||
default behavior of GNU make remains to invoke the shell with simply '-c'.
|
||||
default behavior of GNU Make remains to invoke the shell with simply '-c'.
|
||||
However, any makefile specifying the .POSIX special target will follow the
|
||||
new POSIX standard and pass '-e' to the shell. See also .SHELLFLAGS
|
||||
below.
|
||||
@ -598,9 +756,9 @@ https://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=104&se
|
||||
* A note on appending the redirected output. With this change, a simple
|
||||
mechanism is implemented to make ">>" work in action lines. In VMS
|
||||
there is no simple feature like ">>" to have DCL command or program
|
||||
output redirected and appended to a file. GNU make for VMS already
|
||||
output redirected and appended to a file. GNU Make for VMS already
|
||||
implements the redirection of output. If such a redirection is detected,
|
||||
an ">" on the action line, GNU make creates a DCL command procedure to
|
||||
an ">" on the action line, GNU Make creates a DCL command procedure to
|
||||
execute the action and to redirect its output. Based on that, now ">>"
|
||||
is also recognized and a similar but different command procedure is
|
||||
created to implement the append. The main idea here is to create a
|
||||
@ -609,7 +767,7 @@ https://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=104&se
|
||||
in the command procedure to keep changes in make small and simple. This
|
||||
obviously has some limitations but it seems good enough compared with
|
||||
the current ">" implementation. (And in my opinion, redirection is not
|
||||
really what GNU make has to do.) With this approach, it may happen that
|
||||
really what GNU Make has to do.) With this approach, it may happen that
|
||||
the temporary file is not yet appended and is left in SYS$SCRATCH.
|
||||
The temporary file names look like "CMDxxxxx.". Any time the created
|
||||
command procedure can not complete, this happens. Pressing Ctrl+Y to
|
||||
@ -632,9 +790,9 @@ https://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=104&se
|
||||
|
||||
Version 3.81 (01 Apr 2006)
|
||||
|
||||
* GNU make is ported to OS/2.
|
||||
* GNU Make is ported to OS/2.
|
||||
|
||||
* GNU make is ported to MinGW. The MinGW build is only supported by
|
||||
* GNU Make is ported to MinGW. The MinGW build is only supported by
|
||||
the build_w32.bat batch file; see the file README.W32 for more
|
||||
details.
|
||||
|
||||
@ -642,12 +800,12 @@ Version 3.81 (01 Apr 2006)
|
||||
Up to and including this release, the '$?' variable does not contain
|
||||
any prerequisite that does not exist, even though that prerequisite
|
||||
might have caused the target to rebuild. Starting with the _next_
|
||||
release of GNU make, '$?' will contain all prerequisites that caused
|
||||
release of GNU Make, '$?' will contain all prerequisites that caused
|
||||
the target to be considered out of date.
|
||||
See https://savannah.gnu.org/bugs/?16051
|
||||
|
||||
* WARNING: Backward-incompatibility!
|
||||
GNU make now implements a generic "second expansion" feature on the
|
||||
GNU Make now implements a generic "second expansion" feature on the
|
||||
prerequisites of both explicit and implicit (pattern) rules. In order
|
||||
to enable this feature, the special target '.SECONDEXPANSION' must be
|
||||
defined before the first target which takes advantage of it. If this
|
||||
@ -665,23 +823,23 @@ Version 3.81 (01 Apr 2006)
|
||||
of this SysV feature you will need to update them.
|
||||
|
||||
* WARNING: Backward-incompatibility!
|
||||
In order to comply with POSIX, the way in which GNU make processes
|
||||
In order to comply with POSIX, the way in which GNU Make processes
|
||||
backslash-newline sequences in recipes has changed. If your makefiles
|
||||
use backslash-newline sequences inside of single-quoted strings in
|
||||
recipes you will be impacted by this change. See the GNU make manual
|
||||
recipes you will be impacted by this change. See the GNU Make manual
|
||||
subsection "Splitting Recipe Lines" (node "Splitting Lines"), in
|
||||
section "Recipe Syntax", chapter "Writing Recipe in Rules", for
|
||||
details.
|
||||
|
||||
* WARNING: Backward-incompatibility!
|
||||
Some previous versions of GNU make had a bug where "#" in a function
|
||||
Some previous versions of GNU Make had a bug where "#" in a function
|
||||
invocation such as $(shell ...) was treated as a make comment. A
|
||||
workaround was to escape these with backslashes. This bug has been
|
||||
fixed: if your makefile uses "\#" in a function invocation the
|
||||
backslash is now preserved, so you'll need to remove it.
|
||||
|
||||
* New command line option: -L (--check-symlink-times). On systems that
|
||||
support symbolic links, if this option is given then GNU make will
|
||||
support symbolic links, if this option is given then GNU Make will
|
||||
use the most recent modification time of any symbolic links that are
|
||||
used to resolve target files. The default behavior remains as it
|
||||
always has: use the modification time of the actual target file only.
|
||||
@ -701,16 +859,16 @@ Version 3.81 (01 Apr 2006)
|
||||
call are now masked in the context of the inner call.
|
||||
|
||||
* Implemented a solution for the "thundering herd" problem with "-j -l".
|
||||
This version of GNU make uses an algorithm suggested by Thomas Riedl
|
||||
This version of GNU Make uses an algorithm suggested by Thomas Riedl
|
||||
<thomas.riedl@siemens.com> to track the number of jobs started in the
|
||||
last second and artificially adjust GNU make's view of the system's
|
||||
last second and artificially adjust GNU Make's view of the system's
|
||||
load average accordingly.
|
||||
|
||||
* New special variables available in this release:
|
||||
- .INCLUDE_DIRS: Expands to a list of directories that make searches
|
||||
for included makefiles.
|
||||
- .FEATURES: Contains a list of special features available in this
|
||||
version of GNU make.
|
||||
version of GNU Make.
|
||||
- .DEFAULT_GOAL: Set the name of the default goal make will
|
||||
use if no goals are provided on the command line.
|
||||
- MAKE_RESTARTS: If set, then this is the number of times this
|
||||
@ -748,7 +906,7 @@ Version 3.81 (01 Apr 2006)
|
||||
it will be set in the environment, just as before.
|
||||
|
||||
* On MS Windows systems, explicitly setting SHELL to a pathname ending
|
||||
in "cmd" or "cmd.exe" (case-insensitive) will force GNU make to use
|
||||
in "cmd" or "cmd.exe" (case-insensitive) will force GNU Make to use
|
||||
the DOS command interpreter in batch mode even if a UNIX-like shell
|
||||
could be found on the system.
|
||||
|
||||
@ -780,7 +938,7 @@ Version 3.80 (03 Oct 2002)
|
||||
requiring that target A will always be rebuilt if target B is updated.
|
||||
Patch for this feature provided by Greg McGary <greg@mcgary.org>.
|
||||
|
||||
* For compatibility with SysV make, GNU make now supports the peculiar
|
||||
* For compatibility with SysV make, GNU Make now supports the peculiar
|
||||
syntax $$@, $$(@D), and $$(@F) in the prerequisites list of a rule.
|
||||
This syntax is only valid within explicit and static pattern rules: it
|
||||
cannot be used in implicit (suffix or pattern) rules. Edouard G. Parmelan
|
||||
@ -805,7 +963,7 @@ Version 3.80 (03 Oct 2002)
|
||||
useful here.
|
||||
|
||||
* A new built-in variable is defined, $(MAKEFILE_LIST). It contains a
|
||||
list of each makefile GNU make has read, or started to read, in the
|
||||
list of each makefile GNU Make has read, or started to read, in the
|
||||
order in which they were encountered. So, the last filename in the
|
||||
list when a makefile is just being read (before any includes) is the
|
||||
name of the current makefile.
|
||||
@ -815,7 +973,7 @@ Version 3.80 (03 Oct 2002)
|
||||
makefiles at that moment.
|
||||
|
||||
* A new command line option is defined, -B or --always-make. If
|
||||
specified GNU make will consider all targets out-of-date even if they
|
||||
specified GNU Make will consider all targets out-of-date even if they
|
||||
would otherwise not be.
|
||||
|
||||
* The arguments to $(call ...) functions were being stored in $1, $2,
|
||||
@ -840,7 +998,7 @@ Version 3.80 (03 Oct 2002)
|
||||
Turkish.
|
||||
|
||||
* Updated internationalization support to Gettext 0.11.5.
|
||||
GNU make now uses Gettext's "external" feature, and does not include
|
||||
GNU Make now uses Gettext's "external" feature, and does not include
|
||||
any internationalization code itself. Configure will search your
|
||||
system for an existing implementation of GNU Gettext (only GNU Gettext
|
||||
is acceptable) and use it if it exists. If not, NLS will be disabled.
|
||||
@ -857,7 +1015,7 @@ Version 3.80 (03 Oct 2002)
|
||||
* This is the VMS port of GNU Make done by Hartmut.Becker@compaq.com.
|
||||
|
||||
It is based on the specific version 3.77k and on 3.78.1. 3.77k was done
|
||||
by Klaus Kämpf <kkaempf@rmi.de>, the code was based on the VMS port of
|
||||
by Klaus Kämpf <kkaempf@rmi.de>, the code was based on the VMS port of
|
||||
GNU Make 3.60 by Mike Moretti.
|
||||
|
||||
It was ported on OpenVMS/Alpha V7.1, DECC V5.7-006. It was re-build and
|
||||
@ -872,7 +1030,7 @@ Version 3.80 (03 Oct 2002)
|
||||
available ECOs for VMS V7.1 and newer versions. It is fixed in versions
|
||||
shipped with newer VMS versions and all ECO kits after October 1999. It
|
||||
only shows up during the daylight saving time period (DST): stat()
|
||||
returns a modification time 1 hour ahead. This results in GNU make
|
||||
returns a modification time 1 hour ahead. This results in GNU Make
|
||||
warning messages. For a just created source you will see:
|
||||
|
||||
$ gmake x.exe
|
||||
@ -900,11 +1058,11 @@ Version 3.79.1 (23 Jun 2000)
|
||||
|
||||
Version 3.79 (04 Apr 2000)
|
||||
|
||||
* GNU make optionally supports internationalization and locales via the
|
||||
* GNU Make optionally supports internationalization and locales via the
|
||||
GNU gettext (or local gettext if suitable) package. See the ABOUT-NLS
|
||||
file for more information on configuring GNU make for NLS.
|
||||
file for more information on configuring GNU Make for NLS.
|
||||
|
||||
* Previously, GNU make quoted variables such as MAKEFLAGS and
|
||||
* Previously, GNU Make quoted variables such as MAKEFLAGS and
|
||||
MAKEOVERRIDES for proper parsing by the shell. This allowed them to
|
||||
be used within make build scripts. However, using them there is not
|
||||
proper behavior: they are meant to be passed to subshells via the
|
||||
@ -938,12 +1096,12 @@ Version 3.79 (04 Apr 2000)
|
||||
value is greater than the "end" value. If that's true, nothing is
|
||||
returned.
|
||||
|
||||
* Hartmut Becker provided many updates for the VMS port of GNU make.
|
||||
* Hartmut Becker provided many updates for the VMS port of GNU Make.
|
||||
See the README.VMS file for more details.
|
||||
|
||||
* VMS-specific changes:
|
||||
|
||||
* Fix a problem with automatically remaking makefiles. GNU make uses an
|
||||
* Fix a problem with automatically remaking makefiles. GNU Make uses an
|
||||
execve to restart itself after a successful remake of the makefile. On
|
||||
UNIX systems execve replaces the running program with a new one and
|
||||
resets all signal handling to the default. On VMS execve creates a child
|
||||
@ -1021,7 +1179,7 @@ Version 3.78 (22 Sep 1999)
|
||||
|
||||
* A "job server" feature, suggested by Howard Chu <hyc@highlandsun.com>.
|
||||
|
||||
On systems that support POSIX pipe(2) semantics, GNU make can now pass
|
||||
On systems that support POSIX pipe(2) semantics, GNU Make can now pass
|
||||
-jN options to submakes rather than forcing them all to use -j1. The
|
||||
top make and all its sub-make processes use a pipe to communicate with
|
||||
each other to ensure that no more than N jobs are started across all
|
||||
@ -1029,20 +1187,20 @@ Version 3.78 (22 Sep 1999)
|
||||
with the --disable-job-server option.
|
||||
|
||||
* The confusing term "dependency" has been replaced by the more accurate
|
||||
and standard term "prerequisite", both in the manual and in all GNU make
|
||||
and standard term "prerequisite", both in the manual and in all GNU Make
|
||||
output.
|
||||
|
||||
* GNU make supports the "big archive" library format introduced in AIX 4.3.
|
||||
* GNU Make supports the "big archive" library format introduced in AIX 4.3.
|
||||
|
||||
* GNU make supports large files on AIX, HP-UX, and IRIX. These changes
|
||||
* GNU Make supports large files on AIX, HP-UX, and IRIX. These changes
|
||||
were provided by Paul Eggert <eggert@twinsun.com>. (Large file
|
||||
support for Solaris and Linux was introduced in 3.77, but the
|
||||
configuration had issues: these have also been resolved).
|
||||
|
||||
* The Windows 95/98/NT (W32) version of GNU make now has native support
|
||||
* The Windows 95/98/NT (W32) version of GNU Make now has native support
|
||||
for the Cygnus Cygwin release B20.1 shell (bash).
|
||||
|
||||
* The GNU make regression test suite, long available separately "under
|
||||
* The GNU Make regression test suite, long available separately "under
|
||||
the table", has been integrated into the release. You can invoke it
|
||||
by running "make check" in the distribution. Note that it requires
|
||||
Perl (either Perl 4 or Perl 5) to run.
|
||||
@ -1085,10 +1243,10 @@ Version 3.77 (28 Jul 1998)
|
||||
you'll have to escape both of them: "foo : bar\\\=baz".
|
||||
|
||||
* A new appendix listing the most common error and warning messages
|
||||
generated by GNU make, with some explanation, has been added to the
|
||||
GNU make User's Manual.
|
||||
generated by GNU Make, with some explanation, has been added to the
|
||||
GNU Make User's Manual.
|
||||
|
||||
* Updates to the GNU make Customs library support (see README.customs).
|
||||
* Updates to the GNU Make Customs library support (see README.customs).
|
||||
|
||||
* Updates to the Windows 95/NT port from Rob Tulloh (see README.W32),
|
||||
and to the DOS port from Eli Zaretski (see README.DOS).
|
||||
@ -1097,10 +1255,10 @@ Version 3.77 (28 Jul 1998)
|
||||
|
||||
* This is the VMS port of GNU Make.
|
||||
It is based on the VMS port of GNU Make 3.60 by Mike Moretti.
|
||||
This port was done by Klaus Kämpf <kkaempf@rmi.de>
|
||||
This port was done by Klaus Kämpf <kkaempf@rmi.de>
|
||||
|
||||
* There is first-level support available from proGIS Software, Germany.
|
||||
Visit their web-site at http://www.progis.de to get information
|
||||
Visit their web-site at https://www.progis.de to get information
|
||||
about other vms software and forthcoming updates to gnu make.
|
||||
|
||||
* /bin/sh style I/O redirection is supported. You can now write lines like
|
||||
@ -1138,7 +1296,7 @@ Version 3.76.1 (19 Sep 1997)
|
||||
|
||||
Version 3.76 (16 Sep 1997)
|
||||
|
||||
* GNU make now uses automake to control Makefile.in generation. This
|
||||
* GNU Make now uses automake to control Makefile.in generation. This
|
||||
should make it more consistent with the GNU standards.
|
||||
|
||||
* VPATH functionality has been changed to incorporate the VPATH+ patch,
|
||||
@ -1153,7 +1311,7 @@ Version 3.76 (16 Sep 1997)
|
||||
list of words from number S to number E (inclusive) of TEXT.
|
||||
|
||||
* Instead of an error, detection of future modification times gives a
|
||||
warning and continues. The warning is repeated just before GNU make
|
||||
warning and continues. The warning is repeated just before GNU Make
|
||||
exits, so it is less likely to be lost.
|
||||
|
||||
* Fix the $(basename) and $(suffix) functions so they only operate on
|
||||
@ -1308,9 +1466,9 @@ Version 3.71 (21 May 1994)
|
||||
There is no longer a separate distribution containing Info and DVI files.
|
||||
|
||||
* You can now set the variables `binprefix' and/or `manprefix' in
|
||||
Makefile.in (or on the command line when installing) to install GNU make
|
||||
Makefile.in (or on the command line when installing) to install GNU Make
|
||||
under a name other than `make' (i.e., ``make binprefix=g install''
|
||||
installs GNU make as `gmake').
|
||||
installs GNU Make as `gmake').
|
||||
|
||||
* The built-in Texinfo rules use the new variables `TEXI2DVI_FLAGS' for
|
||||
flags to the `texi2dvi' script, and `MAKEINFO_FLAGS' for flags to the
|
||||
@ -1790,7 +1948,7 @@ Version 3.05
|
||||
(Changes from versions 1 through 3.05 were never recorded. Sorry.)
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 1988-2022 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988-2024 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
@ -1803,4 +1961,4 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
80
README.Amiga
80
README.Amiga
@ -1,80 +0,0 @@
|
||||
Short: Port of GNU make with SAS/C (no ixemul.library required)
|
||||
Author: GNU, Amiga port by Aaron "Optimizer" Digulla
|
||||
Uploader: Aaron "Optimizer" Digulla (digulla@fh-konstanz.de)
|
||||
Type: dev/c
|
||||
|
||||
This is a pure Amiga port of GNU make. It needs no extra libraries or
|
||||
anything. It has the following features (in addition to any features of
|
||||
GNU make):
|
||||
|
||||
- Runs Amiga-Commands with SystemTags() (Execute)
|
||||
- Can run multi-line statements
|
||||
- Allows to use Device-Names in targets:
|
||||
|
||||
c:make : make.o
|
||||
|
||||
is ok. To distinguish between device-names and target : or ::, MAKE
|
||||
looks for spaces. If there are any around :, it's taken as a target
|
||||
delimiter, if there are none, it's taken as the name of a device. Note
|
||||
that "make:make.o" tries to create "make.o" on the device "make:".
|
||||
- Replaces @@ by a newline in any command line:
|
||||
|
||||
if exists make @@\
|
||||
delete make.bak quiet @@\
|
||||
rename make make.bak @@\
|
||||
endif @@\
|
||||
$(CC) Link Make.o To make
|
||||
|
||||
works. Note that the @@ must stand alone (i.e., "make@@\" is illegal).
|
||||
Also be careful that there is a space after the "\" (i.e., at the
|
||||
beginning of the next line).
|
||||
- Can be made resident to save space and time
|
||||
- Amiga specific wildcards can be used in $(wildcard ...)
|
||||
|
||||
BUGS:
|
||||
- The line
|
||||
|
||||
dummy.h : src/*.c
|
||||
|
||||
tries to make dummy.h from "src/*.c" (i.e., no wildcard-expansion takes
|
||||
place). You have to use "$(wildcard src/*.c)" instead.
|
||||
|
||||
COMPILING FROM SCRATCH
|
||||
----------------------
|
||||
|
||||
To recompile, you need SAS/C 6.51.
|
||||
|
||||
As of GNU make 4.3, the build environment has been cleaned up and alternate
|
||||
make files (including smakefiles) have been removed. If you have an existing
|
||||
version of GNU make available you _should_ be able to run:
|
||||
|
||||
make -f Basic.mk
|
||||
|
||||
However this is untested.
|
||||
|
||||
If you have an Amiga system and would like to collaborate on getting
|
||||
bootstrapping to work properly please contact bug-make@gnu.org.
|
||||
|
||||
INSTALLATION
|
||||
|
||||
Copy make somewhere in your search path (e.g., sc:c or sc:bin).
|
||||
If you plan to use recursive makes, install make resident:
|
||||
|
||||
Resident make Add
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 1995-2022 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>.
|
@ -79,7 +79,7 @@ To build from sources:
|
||||
|
||||
6. To install copy make.exe to the preferred location.
|
||||
|
||||
Since GNU make 4.3, support for customized platform installations
|
||||
Since GNU Make 4.3, support for customized platform installations
|
||||
has been removed. If you'd like to collaborate on reinstating
|
||||
these capabilities, contact bug-make@gnu.org.
|
||||
|
||||
@ -280,7 +280,7 @@ Bug reports:
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 1996-2022 Free Software Foundation, Inc.
|
||||
Copyright (C) 1996-2024 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
@ -293,4 +293,4 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
this program. If not, see <https://www.gnu.org/licenses/>.
|
@ -1,6 +1,6 @@
|
||||
Port of GNU make to OS/2.
|
||||
Port of GNU Make to OS/2.
|
||||
|
||||
Features of GNU make that do not work under OS/2:
|
||||
Features of GNU Make that do not work under OS/2:
|
||||
- remote job execution
|
||||
- dynamic load balancing
|
||||
|
||||
@ -9,7 +9,7 @@ Special features of the OS/2 version:
|
||||
|
||||
Due to the fact that some people might want to use sh syntax in
|
||||
Makefiles while others might want to use OS/2's native shell cmd.exe,
|
||||
GNU make supports both shell types. The following list defines the order
|
||||
GNU Make supports both shell types. The following list defines the order
|
||||
that is used to determine the shell:
|
||||
|
||||
1. The shell specified by the environment variable MAKESHELL.
|
||||
@ -37,7 +37,7 @@ I. ***** SPECIAL OPTIONS *****
|
||||
cmd or by specifying SHELL=cmd in your Makefile.
|
||||
|
||||
- At compile time you can set CPPFLAGS="-DNO_CHDIR2" to turn off that
|
||||
GNU make prints drive letters. This is necessary if you want to run
|
||||
GNU Make prints drive letters. This is necessary if you want to run
|
||||
the testsuite.
|
||||
|
||||
|
||||
@ -49,7 +49,7 @@ A standard Unix like build environment:
|
||||
release 2)
|
||||
If you use pdksh it is recommended to update to 5.2.14 release 2. Older
|
||||
versions may not work! You can get this version at
|
||||
http://www.math.ohio-state.edu/~ilya/software/os2/pdksh-5.2.14-bin-2.zip
|
||||
https://www.math.ohio-state.edu/~ilya/software/os2/pdksh-5.2.14-bin-2.zip
|
||||
- GNU file utilities (make sure that install.exe from the file utilities
|
||||
is in front of your PATH before X:\OS2\INSTALL\INSTALL.EXE. I recommend
|
||||
also to change the filename to ginstall.exe instead of install.exe
|
||||
@ -59,7 +59,7 @@ A standard Unix like build environment:
|
||||
- gawk
|
||||
- grep
|
||||
- sed
|
||||
- GNU make 3.79.1 (special OS/2 patched version) or higher
|
||||
- GNU Make 3.79.1 (special OS/2 patched version) or higher
|
||||
- perl 5.005 or higher
|
||||
- GNU texinfo (you can use 3.1 (gnuinfo.zip), but I recommend 4.0)
|
||||
|
||||
@ -73,7 +73,7 @@ III. ***** COMPILATION AND INSTALLATION *****
|
||||
To recreate the configuration files use:
|
||||
|
||||
export EMXSHELL=ksh
|
||||
aclocal -I config
|
||||
aclocal -I m4
|
||||
automake
|
||||
autoconf
|
||||
autoheader
|
||||
@ -93,7 +93,7 @@ Recommended environment variables and installation options:
|
||||
export CFLAGS="-O2 -Zomf -Zmt"
|
||||
export LDFLAGS="-Zcrtdll -Zlinker /exepack:2 -Zlinker /pm:vio -Zstack 0x6000"
|
||||
export RANLIB="echo"
|
||||
./configure --prefix=x:/usr --infodir=x:/usr/share/info --mandir=x:/usr/share/man --without-included-gettext
|
||||
./configure --prefix=x:/usr --infodir=x:/usr/share/info --mandir=x:/usr/share/man
|
||||
make AR=emxomfar
|
||||
make install
|
||||
|
||||
@ -102,18 +102,21 @@ Note: If you use gcc 2.9.x I recommend to set also LIBS="-lgcc"
|
||||
Note: You can add -DNO_CMD_DEFAULT and -DNO_CHDIR2 to CPPFLAGS.
|
||||
See section I. for details.
|
||||
|
||||
Note: If you use Open Watcom Linker instead of IBM Linker, remove
|
||||
'-Zlinker /exepack:2' from LDFLAGS.
|
||||
|
||||
|
||||
IV. ***** NLS support *****
|
||||
|
||||
GNU make has NLS (National Language Support), with the following
|
||||
GNU Make has NLS (National Language Support), with the following
|
||||
caveats:
|
||||
|
||||
a) It will only work with GNU gettext, and
|
||||
b) GNU gettext support is not included in the GNU make package.
|
||||
b) GNU gettext support is not included in the GNU Make package.
|
||||
|
||||
Therefore, if you wish to enable the internationalization features of
|
||||
GNU make you must install GNU gettext on your system before configuring
|
||||
GNU make.
|
||||
GNU Make you must install GNU gettext on your system before configuring
|
||||
GNU Make.
|
||||
|
||||
You can choose the languages to be installed. To install support for
|
||||
English, German and French only enter:
|
||||
@ -160,7 +163,7 @@ from the make source tree.
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2003-2022 Free Software Foundation, Inc.
|
||||
Copyright (C) 2003-2024 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
@ -173,4 +176,4 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
this program. If not, see <https://www.gnu.org/licenses/>.
|
20
README.VMS
20
README.VMS
@ -1,7 +1,7 @@
|
||||
Overview: -*-text-mode-*-
|
||||
---------
|
||||
|
||||
This version of GNU make has been tested on:
|
||||
This version of GNU Make has been tested on:
|
||||
OpenVMS V8.3/V8.4 (Alpha) and V8.4 (Integrity) AND V7.3 (VAX)
|
||||
|
||||
This version of GNU Make is intended to be run from DCL to run
|
||||
@ -14,7 +14,7 @@ Overview: -*-text-mode-*-
|
||||
detect that it is running under a POSIX shell and then operate as close to
|
||||
GNU Make on Unix as possible.
|
||||
|
||||
The descriptions below are for running GNU make from DCL or equivalent.
|
||||
The descriptions below are for running GNU Make from DCL or equivalent.
|
||||
|
||||
Recipe differences:
|
||||
-------------------
|
||||
@ -84,7 +84,7 @@ Recipe differences:
|
||||
|
||||
The format for recipes are a combination of Unix macros, a subset of
|
||||
simulated UNIX commands, some shell emulation, and OpenVMS commands.
|
||||
This makes the resulting makefiles unique to the OpenVMS port of GNU make.
|
||||
This makes the resulting makefiles unique to the OpenVMS port of GNU Make.
|
||||
|
||||
If you are creating a OpenVMS specific makefile from scratch, you should also
|
||||
look at MMK (Madgoat Make) available at https://github.com/endlesssoftware/mmk
|
||||
@ -177,7 +177,7 @@ Recipe differences:
|
||||
Since the OpenVMS utilities generally expect OpenVMS format paths, you will
|
||||
usually have to use OpenVMS format paths for rules and targets.
|
||||
BUG: Relative OpenVMS paths may not work in targets, especially combined
|
||||
with vpaths. This is because GNU make will just concatenate the directories
|
||||
with vpaths. This is because GNU Make will just concatenate the directories
|
||||
as it does on Unix.
|
||||
|
||||
The variables $^ and $@ separate files with commas instead of spaces.
|
||||
@ -211,9 +211,9 @@ foo: $(addsuffix .3,$(subs $(comma),$(space),$^)
|
||||
shows them as "environment override". On POSIX the test scripts indicate
|
||||
that they should show up just as "environment".
|
||||
|
||||
When GNU make reads in a symbol or logical name into the environment, it
|
||||
When GNU Make reads in a symbol or logical name into the environment, it
|
||||
converts any dollar signs found to double dollar signs for convenience in
|
||||
using DCL symbols and logical names in recipes. When GNU make exports a
|
||||
using DCL symbols and logical names in recipes. When GNU Make exports a
|
||||
DCL symbol for a child process, if the first dollar sign found is followed
|
||||
by second dollar sign, then all double dollar signs will be converted to
|
||||
single dollar signs.
|
||||
@ -284,7 +284,7 @@ Runtime issues:
|
||||
|
||||
MAKE_FAILURE has a POSIX value of 2 and an OpenVMS status of %x1035a012.
|
||||
|
||||
Output from GNU make may have single quotes around some values where on
|
||||
Output from GNU Make may have single quotes around some values where on
|
||||
other platforms it does not. Also output that would be in double quotes
|
||||
on some platforms may show up as single quotes on VMS.
|
||||
|
||||
@ -353,7 +353,7 @@ Unix compatibility features:
|
||||
A note on appending the redirected output. A simple mechanism is
|
||||
implemented to make ">>" work in action lines. In OpenVMS there is no simple
|
||||
feature like ">>" to have DCL command or program output redirected and
|
||||
appended to a file. GNU make for OpenVMS implements the redirection
|
||||
appended to a file. GNU Make for OpenVMS implements the redirection
|
||||
of ">>" by using a command procedure.
|
||||
|
||||
The current algorithm creates the output file if it does not exist and
|
||||
@ -409,7 +409,7 @@ Unimplemented functionality:
|
||||
The new feature "Loadable objects" is not yet supported. If you need it,
|
||||
please send a change request or submit a bug report.
|
||||
|
||||
The new option --output-sync (-O) is accepted but has no effect: GNU make
|
||||
The new option --output-sync (-O) is accepted but has no effect: GNU Make
|
||||
for OpenVMS does not support running multiple commands simultaneously.
|
||||
|
||||
|
||||
@ -421,7 +421,7 @@ Self test failures and todos:
|
||||
Need to find a way to set the VMS features before running make as a
|
||||
child.
|
||||
|
||||
GNU make was not currently translating the OpenVMS encoded POSIX values
|
||||
GNU Make was not currently translating the OpenVMS encoded POSIX values
|
||||
returned to it back to the POSIX values. I have temporarily modified the
|
||||
Perl test script to compensate for it. This should be being handled
|
||||
internally to Make.
|
||||
|
@ -1,5 +1,5 @@
|
||||
This version of GNU make has been tested on:
|
||||
Microsoft Windows 2000/XP/2003/Vista/7/8/10
|
||||
This version of GNU Make has been tested on:
|
||||
Microsoft Windows 2000/XP/2003/Vista/7/8/10/11
|
||||
It has also been used on Windows 95/98/NT, and on OS/2.
|
||||
|
||||
It builds with the MinGW port of GCC (tested with GCC 3.4.2, 4.8.1,
|
||||
@ -15,7 +15,7 @@ which compilation and link switches and libraries need to be mentioned
|
||||
on the compiler command lines to correctly link with Guile. A Windows
|
||||
port of pkg-config can be found on ezwinports site:
|
||||
|
||||
http://sourceforge.net/projects/ezwinports/
|
||||
https://sourceforge.net/projects/ezwinports/
|
||||
|
||||
The libraries on which Guile depends can vary depending on your
|
||||
version and build of Guile. At the very least, the Boehm's GC library
|
||||
@ -25,7 +25,7 @@ also provide you with these dependencies or a URL where to download
|
||||
them. A precompiled 32-bit Windows build of Guile is available from
|
||||
the ezwinports site mentioned above.
|
||||
|
||||
The Windows port of GNU make is maintained jointly by various people.
|
||||
The Windows port of GNU Make is maintained jointly by various people.
|
||||
It was originally made by Rob Tulloh.
|
||||
It is currently maintained by Eli Zaretskii.
|
||||
|
||||
@ -33,12 +33,14 @@ It is currently maintained by Eli Zaretskii.
|
||||
Do this first, regardless of the build method you choose:
|
||||
---------------------------------------------------------
|
||||
|
||||
1. Edit config.h.W32 to your liking (especially the few shell-related
|
||||
defines near the end, or HAVE_CASE_INSENSITIVE_FS which corresponds
|
||||
to './configure --enable-case-insensitive-file-system'). (We don't
|
||||
recommend to define HAVE_CASE_INSENSITIVE_FS, but you may wish to
|
||||
consider that if you have a lot of files whose names are in upper
|
||||
case, while Makefile rules are written for lower-case versions.)
|
||||
1. If you have special requirements, edit config.h.W32 to your liking
|
||||
(especially the shell-related defines, or HAVE_CASE_INSENSITIVE_FS which
|
||||
corresponds to './configure --enable-case-insensitive-file-system'). We
|
||||
don't recommend to define HAVE_CASE_INSENSITIVE_FS, but you may wish to
|
||||
consider that if you have a lot of files whose names are in upper case,
|
||||
while Makefile rules are written for lower-case versions.
|
||||
|
||||
If you don't have special requirements no changes are needed.
|
||||
|
||||
|
||||
Building with (MinGW-)GCC using build_w32.bat
|
||||
@ -51,7 +53,7 @@ Building with (MinGW-)GCC using build_w32.bat
|
||||
|
||||
This produces gnumake.exe in the GccRel directory.
|
||||
|
||||
If you want a version of GNU make built with debugging enabled,
|
||||
If you want a version of GNU Make built with debugging enabled,
|
||||
add the --debug option. Output goes into the GccDebug directory.
|
||||
|
||||
The batch file will probe for Guile installation, and will build
|
||||
@ -73,21 +75,21 @@ Building with (MSVC++-)cl using build_w32.bat
|
||||
file will probe your system and choose the newest MSVC version it can
|
||||
find.
|
||||
|
||||
If you want a 32bit version of GNU make, add the --x86 option.
|
||||
If you want a 32bit version of GNU Make, add the --x86 option.
|
||||
|
||||
If you want a Debug build of GNU make, add the --debug option. Output
|
||||
If you want a Debug build of GNU Make, add the --debug option. Output
|
||||
will go into the .\WinDebug directory.
|
||||
|
||||
The batch file will probe for Guile installation, and will build
|
||||
gnumake.exe with Guile if it finds it. If Guile is installed,
|
||||
but you prefer to build GNU make without Guile support, add the
|
||||
but you prefer to build GNU Make without Guile support, add the
|
||||
--without-guile option.
|
||||
|
||||
|
||||
Building with (MinGW-)GCC using GNU make
|
||||
Building with (MinGW-)GCC using GNU Make
|
||||
----------------------------------------
|
||||
|
||||
2. If you already have a version of GNU make available you can use it
|
||||
2. If you already have a version of GNU Make available you can use it
|
||||
to build this version. Open a W32 command prompt for your installed
|
||||
(MinGW-)GCC, setup a correct PATH and other environment variables
|
||||
for it, then execute ...
|
||||
@ -95,7 +97,7 @@ Building with (MinGW-)GCC using GNU make
|
||||
make -f Basic.mk TOOLCHAIN=gcc
|
||||
|
||||
This produces GccRel\gnumake.exe.
|
||||
If you want a version of GNU make built with debugging enabled,
|
||||
If you want a version of GNU Make built with debugging enabled,
|
||||
add the TARGET_TYPE=debug option:
|
||||
|
||||
make -f Basic.mk TOOLCHAIN=gcc TARGET_TYPE=debug
|
||||
@ -104,10 +106,10 @@ Building with (MinGW-)GCC using GNU make
|
||||
if you want to build with Guile support.
|
||||
|
||||
|
||||
Building with (MSVC++-)cl using GNU make
|
||||
Building with (MSVC++-)cl using GNU Make
|
||||
----------------------------------------
|
||||
|
||||
2. If you already have a version of GNU make available you can use it
|
||||
2. If you already have a version of GNU Make available you can use it
|
||||
to build this version. Open a W32 command prompt for your installed
|
||||
(MSVC++-)cl, setup a correct PATH and other environment variables
|
||||
for it (usually via executing vcvars32.bat or vsvars32.bat from the
|
||||
@ -117,7 +119,7 @@ Building with (MSVC++-)cl using GNU make
|
||||
make -f Basic.mk
|
||||
|
||||
This produces an optimized WinRel/gnumake.exe.
|
||||
If you want a version of GNU make built with debugging enabled,
|
||||
If you want a version of GNU Make built with debugging enabled,
|
||||
add the TARGET_TYPE=debug option:
|
||||
|
||||
make -f Basic.mk TARGET_TYPE=debug
|
||||
@ -132,7 +134,7 @@ Running the test suite
|
||||
3. You will need an installation of Perl. Be sure to use a relatively
|
||||
modern version: older versions will sometimes throw spurious errors.
|
||||
|
||||
To run the suite after building using GNU make, use:
|
||||
To run the suite after building using GNU Make, use:
|
||||
|
||||
make -f Basic.mk check
|
||||
|
||||
@ -156,7 +158,7 @@ Running the test suite
|
||||
-- Notes/Caveats --
|
||||
-------------------
|
||||
|
||||
GNU make on Windows 32-bit platforms:
|
||||
GNU Make on Windows 32-bit platforms:
|
||||
|
||||
This version of make is ported natively to Windows32 platforms
|
||||
(Windows NT 3.51, Windows NT 4.0, Windows 2000, Windows XP,
|
||||
@ -166,11 +168,11 @@ GNU make on Windows 32-bit platforms:
|
||||
officially are the MinGW port of GNU GCC, and the various
|
||||
versions of the Microsoft C compiler.
|
||||
|
||||
Do not confuse this port of GNU make with other Windows32 projects
|
||||
which provide a GNU make binary. These are separate projects
|
||||
Do not confuse this port of GNU Make with other Windows32 projects
|
||||
which provide a GNU Make binary. These are separate projects
|
||||
and are not connected to this port effort.
|
||||
|
||||
GNU make and sh.exe:
|
||||
GNU Make and sh.exe:
|
||||
|
||||
This port prefers if you have a working sh.exe somewhere on
|
||||
your system. If you don't have sh.exe, the port falls back to
|
||||
@ -180,12 +182,12 @@ GNU make and sh.exe:
|
||||
|
||||
There are very few true ports of Bourne shell for NT right now.
|
||||
There is a version of GNU bash available from Cygnus "Cygwin"
|
||||
porting effort (http://www.cygwin.com/).
|
||||
porting effort (https://www.cygwin.com/).
|
||||
Other possibilities are the MKS version of sh.exe, or building
|
||||
your own with a package like NutCracker (DataFocus) or Portage
|
||||
(Consensys). Also MinGW includes sh (http://mingw.org/).
|
||||
(Consensys). Also MinGW includes sh.
|
||||
|
||||
GNU make and brain-dead shells (BATCH_MODE_ONLY_SHELL):
|
||||
GNU Make and brain-dead shells (BATCH_MODE_ONLY_SHELL):
|
||||
|
||||
Some versions of Bourne shell do not behave well when invoked
|
||||
as 'sh -c' from CreateProcess(). The main problem is they seem
|
||||
@ -211,21 +213,21 @@ Support for parallel builds
|
||||
Parallel builds (-jN) are supported in this port. The number of
|
||||
concurrent processes has a hard limit of 4095.
|
||||
|
||||
GNU make and Cygnus GNU Windows32 tools:
|
||||
GNU Make and Cygnus GNU Windows32 tools:
|
||||
|
||||
Good news! Make now has native support for Cygwin sh. To enable,
|
||||
define the HAVE_CYGWIN_SHELL in config.h and rebuild make
|
||||
from scratch. This version of make tested with B20.1 of Cygwin.
|
||||
Do not define BATCH_MODE_ONLY_SHELL if you use HAVE_CYGWIN_SHELL.
|
||||
|
||||
GNU make and the MKS shell:
|
||||
GNU Make and the MKS shell:
|
||||
|
||||
There is now semi-official support for the MKS shell. To turn this
|
||||
support on, define HAVE_MKS_SHELL in the config.h.W32 before you
|
||||
build make. Do not define BATCH_MODE_ONLY_SHELL if you turn
|
||||
on HAVE_MKS_SHELL.
|
||||
|
||||
GNU make handling of drive letters in pathnames (PATH, vpath, VPATH):
|
||||
GNU Make handling of drive letters in pathnames (PATH, vpath, VPATH):
|
||||
|
||||
There is a caveat that should be noted with respect to handling
|
||||
single character pathnames on Windows systems. When colon is
|
||||
@ -291,7 +293,7 @@ Pathnames and Case insensitivity:
|
||||
the file with other case permutations will succeed (i.e. opening a
|
||||
file named "target" or "TARGET" will open the file "Target").
|
||||
|
||||
By default, GNU make retains its case sensitivity when comparing
|
||||
By default, GNU Make retains its case sensitivity when comparing
|
||||
target names and existing files or directories. It can be
|
||||
configured, however, into a case preserving and case insensitive
|
||||
mode by adding a define for HAVE_CASE_INSENSITIVE_FS to
|
||||
@ -309,10 +311,10 @@ Pathnames and Case insensitivity:
|
||||
SUBDIR/DepTarget: SubDir/TARGET
|
||||
cp $^ $@
|
||||
|
||||
Reliance on this behavior also eliminates the ability of GNU make
|
||||
Reliance on this behavior also eliminates the ability of GNU Make
|
||||
to use case in comparison of matching rules. For example, it is
|
||||
not possible to set up a C++ rule using %.C that is different
|
||||
than a C rule using %.c. GNU make will consider these to be the
|
||||
than a C rule using %.c. GNU Make will consider these to be the
|
||||
same rule and will issue a warning.
|
||||
|
||||
SAMBA/NTFS/VFAT:
|
||||
@ -342,10 +344,10 @@ FAT:
|
||||
Bug reports:
|
||||
|
||||
Please submit bugs via the normal bug reporting mechanism which
|
||||
is described in the GNU make manual and the base README.
|
||||
is described in the GNU Make manual and the base README.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 1996-2022 Free Software Foundation, Inc.
|
||||
Copyright (C) 1996-2024 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
@ -358,4 +360,4 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
this program. If not, see <https://www.gnu.org/licenses/>.
|
@ -1,6 +1,6 @@
|
||||
-*-indented-text-*-
|
||||
|
||||
GNU make can utilize the Customs library, distributed with Pmake, to
|
||||
GNU Make can utilize the Customs library, distributed with Pmake, to
|
||||
provide builds distributed across multiple hosts.
|
||||
|
||||
In order to utilize this capability, you must first download and build
|
||||
@ -21,11 +21,11 @@ please see the pmake and Customs documentation for details. The best
|
||||
place to look for instructions is in the pmake-2.1.33/INSTALL file.
|
||||
|
||||
Note that the 2.1.33 Pmake distribution comes with a set of patches to
|
||||
GNU make, distributed in the pmake-2.1.33/etc/gnumake/ directory. These
|
||||
patches are based on GNU make 3.75 (there are patches for earlier
|
||||
versions of GNU make, also). The parts of this patchfile which relate
|
||||
GNU Make, distributed in the pmake-2.1.33/etc/gnumake/ directory. These
|
||||
patches are based on GNU Make 3.75 (there are patches for earlier
|
||||
versions of GNU Make, also). The parts of this patchfile which relate
|
||||
directly to Customs support have already been incorporated into this
|
||||
version of GNU make, so you should _NOT_ apply the patch file.
|
||||
version of GNU Make, so you should _NOT_ apply the patch file.
|
||||
|
||||
However, there are a few non-Customs specific (as far as I could tell)
|
||||
changes here which are not incorporated (for example, the modification
|
||||
@ -42,14 +42,14 @@ install' there directly).
|
||||
BUILDING GNU MAKE
|
||||
-----------------
|
||||
|
||||
Once you've installed Customs, you can build GNU make to use it. When
|
||||
configuring GNU make, merely use the '--with-customs=DIR' option.
|
||||
Once you've installed Customs, you can build GNU Make to use it. When
|
||||
configuring GNU Make, merely use the '--with-customs=DIR' option.
|
||||
Provide the directory containing the 'lib' and 'include/customs'
|
||||
subdirectories as DIR. For example, if you installed the customs
|
||||
library in /usr/local/lib and the headers in /usr/local/include/customs,
|
||||
then you'd pass '--with-customs=/usr/local' as an option to configure.
|
||||
|
||||
Run make (or use build.sh) normally to build GNU make as described in
|
||||
Run make (or use build.sh) normally to build GNU Make as described in
|
||||
the INSTALL file.
|
||||
|
||||
See the documentation for Customs for information on starting and
|
||||
@ -83,7 +83,7 @@ PROBLEMS
|
||||
|
||||
SunOS 4.1.x:
|
||||
The customs/sprite.h header file #includes the <malloc.h> header
|
||||
files; this conflicts with GNU make's configuration so you'll get a
|
||||
files; this conflicts with GNU Make's configuration so you'll get a
|
||||
compile error if you use GCC (or any other ANSI-capable C compiler).
|
||||
|
||||
I commented out the #include in sprite.h:107:
|
||||
@ -96,7 +96,7 @@ SunOS 4.1.x:
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 1998-2022 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998-2024 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
@ -109,4 +109,4 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
261
README.git
261
README.git
@ -1,7 +1,7 @@
|
||||
-*-text-*-
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2002-2022 Free Software Foundation, Inc.
|
||||
Copyright (C) 2002-2024 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
@ -31,13 +31,13 @@ make source code via Git from the FSF's Savannah project
|
||||
Changes using Git
|
||||
-----------------
|
||||
|
||||
If you do not have push privileges to the GNU make Git repository, see the
|
||||
If you do not have push privileges to the GNU Make Git repository, see the
|
||||
README file section "Submitting Patches" for information.
|
||||
|
||||
If you have push privileges to the GNU make Git repository keep this
|
||||
If you have push privileges to the GNU Make Git repository keep this
|
||||
information in mind:
|
||||
|
||||
Starting with GNU make 4.0 we no longer keep a separate ChangeLog file in
|
||||
Starting with GNU Make 4.0 we no longer keep a separate ChangeLog file in
|
||||
source control. We use the Gnulib git-to-changelog conversion script to
|
||||
convert the Git comments into ChangeLog-style entries for release. As a
|
||||
result, please format your Git comments carefully so they will look clean
|
||||
@ -48,8 +48,8 @@ your commit messages (sans the leading TAB of course).
|
||||
|
||||
Rule #1: Don't rewrite pushed history on master (no "git push --force").
|
||||
Rule #2: Feel free to rewrite pushed history on personal branches.
|
||||
Rule #3: Prefer to squash-merge or rebase + merge --ff-only, rather than
|
||||
merging from personal branches into master.
|
||||
Rule #3: Squash-merge or rebase + merge --ff-only, rather than merging from
|
||||
personal branches into master.
|
||||
|
||||
Typical simple workflow might be:
|
||||
|
||||
@ -70,12 +70,12 @@ available which helps a lot.
|
||||
Coding Standards
|
||||
----------------
|
||||
|
||||
GNU make code adheres to the GNU Coding Standards. Please use only spaces and
|
||||
GNU Make code adheres to the GNU Coding Standards. Please use only spaces and
|
||||
no TAB characters in source code.
|
||||
|
||||
Additionally, GNU make is a foundational bootstrap package for the GNU
|
||||
Additionally, GNU Make is a foundational bootstrap package for the GNU
|
||||
project; as such it is conservative about language features it expects.
|
||||
However, GNU make does rely on the Gnulib portability library, and Gnulib
|
||||
However, GNU Make does rely on the Gnulib portability library, and Gnulib
|
||||
currently requires a ISO C99 compiler. So features in ISO C99 can be
|
||||
assumed.
|
||||
|
||||
@ -83,25 +83,28 @@ assumed.
|
||||
Building From Git for POSIX
|
||||
---------------------------
|
||||
|
||||
To build GNU make from Git on POSIX systems such as GNU/Linux, you will
|
||||
To build GNU Make from Git on POSIX systems such as GNU/Linux, you will
|
||||
need to install the following extra software:
|
||||
|
||||
* autoconf >= 2.69
|
||||
* automake >= 1.16.1
|
||||
* gettext
|
||||
* autopoint
|
||||
* pkg-config
|
||||
* texinfo (for makeinfo)
|
||||
* gettext
|
||||
* pkg-config
|
||||
* GCC
|
||||
* GNU make (POSIX make is not sufficient)
|
||||
* GNU Make (POSIX make is not sufficient)
|
||||
|
||||
And any tools that those utilities require (GNU m4, etc.)
|
||||
|
||||
To run the tests you must install Perl.
|
||||
|
||||
To build a release you'll need to install lzip.
|
||||
To create dist files you will additionally need:
|
||||
|
||||
GNU make requires Gnulib to provide some facilities. If you want to maintain
|
||||
* lzip (to create tar.lz dist files)
|
||||
* texlive (or some other TeX package)
|
||||
|
||||
GNU Make requires Gnulib to provide some facilities. If you want to maintain
|
||||
a local installation of gnulib you can set GNULIB_SRCDIR to point to it.
|
||||
Otherwise, ./bootstrap will obtain a clone for you.
|
||||
|
||||
@ -125,11 +128,11 @@ After checking out the code, you will need to run the bootstrap script:
|
||||
|
||||
Alternatively you can just pull content from remote locations with:
|
||||
|
||||
$ ./autopull.sh
|
||||
$ ./bootstrap --pull
|
||||
|
||||
And/or just re-generate auto-generatable files with:
|
||||
|
||||
$ ./autogen.sh
|
||||
$ ./bootstrap --gen
|
||||
|
||||
(Running ./bootstrap does both in one step.)
|
||||
|
||||
@ -141,10 +144,10 @@ That is, you can just run:
|
||||
$ ./configure
|
||||
$ make check
|
||||
|
||||
to build and test GNU make.
|
||||
to build and test GNU Make.
|
||||
|
||||
NOTE! This method builds GNU make in "maintainer mode". Make programs built
|
||||
in this mode it will be slower, possibly MUCH slower: there are various
|
||||
NOTE! This method builds GNU Make in "maintainer mode". Make programs built
|
||||
in this mode will be slower, possibly MUCH slower: there are various
|
||||
sanity checks enabled. Further this mode assumes a modern GCC, GNU
|
||||
libc, and well-formed system headers and enables a high level of
|
||||
warnings AND enables -Werror to turn warnings into failures.
|
||||
@ -152,7 +155,8 @@ NOTE! This method builds GNU make in "maintainer mode". Make programs built
|
||||
If you want to build from Git with "maintainer mode" disabled, add
|
||||
"MAKE_MAINTAINER_MODE=" to the make command line. If you want to turn
|
||||
off the extra warning flags, add "MAKE_CFLAGS=" to the make command
|
||||
line.
|
||||
line. If you want to keep the warnings but not fail, add
|
||||
"EXTRA_CFLAGS=-Wno-error" to the make command line.
|
||||
|
||||
For example:
|
||||
$ ./configure
|
||||
@ -163,22 +167,24 @@ NOTE! This method builds GNU make in "maintainer mode". Make programs built
|
||||
Building From Git for Windows
|
||||
-----------------------------
|
||||
|
||||
If you have a UNIX emulation like CYGWIN you can opt to run the general
|
||||
build procedure above; it will work. Consult README.W32.template for
|
||||
information on options you might want to use when running ./configure.
|
||||
If you have a UNIX emulation like CYGWIN you can opt to run the general build
|
||||
procedure above; it will work. Consult README.W32 for information on options
|
||||
you might want to use when running ./configure.
|
||||
|
||||
If you can't or don't want to do that, then first run the .\bootstrap.bat
|
||||
script to prime your Git workspace:
|
||||
script to "prime" your Git workspace:
|
||||
|
||||
> .\bootstrap.bat
|
||||
|
||||
Next, rename the file README.W32.template to README.W32 and follow those
|
||||
instructions.
|
||||
Next, follow the instructions in the README.W32 file.
|
||||
|
||||
Note, neither of these methods are tested regularly by the GNU make
|
||||
Note, neither of these methods are tested regularly by the GNU Make
|
||||
maintainers. Building for Windows from a distribution tarball IS tested
|
||||
regularly.
|
||||
|
||||
NOTE! "Maintainer mode" (see above) IS ENABLED when building from Git using
|
||||
the build_w32.bat file.
|
||||
|
||||
|
||||
Debugging and Testing
|
||||
---------------------
|
||||
@ -204,7 +210,14 @@ work on non-GNU systems (Windows, MacOS, etc.)
|
||||
|
||||
make clean
|
||||
make -j8 CFLAGS='-ggdb3 -fsanitize=address' LDFLAGS='-ggdb3 -fsanitize=address'
|
||||
(cd tests && ./run_make_tests -make ../make)
|
||||
|
||||
Then to check for corruption only but not memory leaks run:
|
||||
|
||||
ASAN_OPTIONS='detect_stack_after_use_return=true:detect_leaks=false' make check
|
||||
|
||||
To check for leaks too run:
|
||||
|
||||
make check
|
||||
|
||||
Note that ASAN is reporting many more errors than valgrind. I don't know
|
||||
which one is wrong: I haven't looked at them closely.
|
||||
@ -214,7 +227,7 @@ Creating a Package
|
||||
------------------
|
||||
|
||||
Once you have performed the above steps (including the configuration and
|
||||
build) you can create a GNU make package. This is very simple, just
|
||||
build) you can create a GNU Make package. This is very simple, just
|
||||
run:
|
||||
|
||||
$ make dist-gzip
|
||||
@ -246,38 +259,128 @@ consistent (that's why we don't finalize the Git tag, etc. until the end).
|
||||
|
||||
* Update the configure.ac file with the new release number.
|
||||
* Update the EDITION value in the doc/make.texi file.
|
||||
* Update the doc/make.1 file with the release date.
|
||||
* Update the NEWS file with the release number and date.
|
||||
* Ensure the Savannah bug list URL in the NEWS file uses the correct
|
||||
"Fixed Release" ID number.
|
||||
* Run "make distcheck" to be sure it all works.
|
||||
* Run "make check-alt-config" to be sure alternative configurations work
|
||||
* Run "make update-makeweb" to get a copy of the GNU make web pages
|
||||
* Run "make update-gnuweb" to get a copy of the GNU website boilerplate pages
|
||||
* Update the web page boilerplate if necessary:
|
||||
../gnu-www/www/server/standards/patch-from-parent ../make-web/make.html \
|
||||
../gnu-www/www/server/standards/boilerplate.html
|
||||
* Run "make gendocs" (requires gnulib) to generate the manual files for
|
||||
the GNU make web pages.
|
||||
* Follow the directions from gendocs for the web page repository
|
||||
* run "make tag-release" to create a Git tag for the release
|
||||
* Push everything:
|
||||
git push --tags origin master
|
||||
|
||||
Manage the Savannah project for GNU make:
|
||||
The safest thing is to create an entirely new repository and build the final
|
||||
package from there:
|
||||
|
||||
>>> This is only for real releases, not release candidate builds <<<
|
||||
git clone git://git.savannah.gnu.org/make.git make-release
|
||||
cd make-release
|
||||
|
||||
* In Savannah modify the "Value", "Rank", and "Description" values for the
|
||||
current "SCM" entry in both "Component Version" and "Fix Release" fields
|
||||
to refer to the new release. The "Rank" field should be 10 less than the
|
||||
previous release so it orders properly.
|
||||
* In Savannah create a new entry for the "Component Version" and "Fix
|
||||
Release" fields:
|
||||
If you don't want to create a new repository then run "git clean -fdx".
|
||||
Then:
|
||||
|
||||
./bootstrap
|
||||
./configure
|
||||
make distcheck
|
||||
|
||||
Perform test builds on whichever systems you have access to.
|
||||
|
||||
Use a previous announcement as a template to create an announcement in a text
|
||||
file then sign it with GPG:
|
||||
|
||||
gpg --clearsign <announcement.txt>
|
||||
|
||||
Or, use your mail client's PGP/GPG signing capabilities.
|
||||
|
||||
NOTE! In order to publish a package on the FSF FTP site you need to have my
|
||||
GPG private key, and my passphrase to unlock it.
|
||||
|
||||
Depending on your distribution (whether GnuPG is integrated with your
|
||||
keyring etc.) the upload operation will either pop up a window asking
|
||||
for the GPG key passphrase one time, or else it will use the CLI to ask
|
||||
for the GPG passphrase _THREE_ times. Sigh.
|
||||
|
||||
|
||||
Publishing a Release Candidate
|
||||
------------------------------
|
||||
|
||||
Usually I publish one or two release candidates for people to test before
|
||||
making an official release. Release candidates use a GNU numbering scheme,
|
||||
which add a ".9x" release number to the PREVIOUS major release. So the first
|
||||
release candidate for GNU Make 4.4 would be GNU Make 4.3.90, the second
|
||||
release candidate would be 4.3.91, etc.
|
||||
|
||||
Upload a release candidate using:
|
||||
|
||||
make upload-alpha
|
||||
|
||||
Announce a release candidate to these mailing lists:
|
||||
|
||||
To: bug-make@gnu.org
|
||||
BCC: help-make@gnu.org, make-w32@gnu.org, make-alpha@gnu.org
|
||||
|
||||
You will have to approve the BCC's on the mailing list admin sites. Send
|
||||
separate copies to (don't use CC as replies will go to these lists):
|
||||
|
||||
* coordinator@translationproject.org
|
||||
* platform-testers@gnu.org
|
||||
|
||||
|
||||
Publishing a Release
|
||||
--------------------
|
||||
|
||||
When publishing a final release there are extra steps that need to be taken:
|
||||
|
||||
* Run "make update-makeweb" to get a copy of the GNU Make web pages
|
||||
* Run "make update-gnuweb" to get a copy of the GNU website boilerplate pages
|
||||
* Update the web page boilerplate if necessary:
|
||||
( cd ~/src/make/make-web \
|
||||
&& ~/src/gnu-www/www/server/standards/patch-from-parent \
|
||||
make.html \
|
||||
~/src/gnu-www/www/server/standards/boilerplate.html )
|
||||
* Run "make gendocs" (requires gnulib) to generate the manual files for
|
||||
the GNU Make web pages.
|
||||
* Follow the directions from gendocs for the web page repository
|
||||
|
||||
Manage the Savannah project for GNU Make:
|
||||
|
||||
* In Savannah edit the "Component Version" field and choose the "SCM" entry.
|
||||
Modify the "Value", "Rank", and "Description" values for the to refer to
|
||||
the new release. The "Rank" field should be 10 less than the previous
|
||||
release so it orders properly.
|
||||
|
||||
* In Savannah edit the "Fixed Release" field and choose the "SCM" entry.
|
||||
Modify the "Value", "Rank", and "Description" values for the to refer to
|
||||
the new release. The "Rank" field should be 10 less than the previous
|
||||
release so it orders properly.
|
||||
|
||||
* In Savannah create a new entry for the "Component Version" field:
|
||||
- Value: SCM
|
||||
- Rank: 20
|
||||
- Descr: Issues found in code retrieved from Source Code Management (Git), rather than a distributed version. Please include the SHA you are working with.
|
||||
|
||||
- Descr: Fixed in Source Code Management (Git). The fix will be included in the next release of GNU make.
|
||||
* In Savannah create a new entry for the "Fix Release" field:
|
||||
- Value: SCM
|
||||
- Rank: 20
|
||||
- Descr: Fixed in Source Code Management (Git). The fix will be included in the next release of GNU Make.
|
||||
|
||||
Upload a release using:
|
||||
|
||||
make upload-ftp
|
||||
|
||||
Announce a release to these mailing lists:
|
||||
|
||||
To: info-gnu@gnu.org, bug-make@gnu.org
|
||||
BCC: help-make@gnu.org, make-w32@gnu.org, make-alpha@gnu.org
|
||||
|
||||
You will have to approve the BCC's on the mailing list admin sites. Send
|
||||
separate copies to (don't use CC as replies will go to these lists):
|
||||
|
||||
* coordinator@translationproject.org
|
||||
* platform-testers@gnu.org
|
||||
|
||||
Announce on Savannah:
|
||||
|
||||
* Add a news item to the Savannah project site.
|
||||
|
||||
Start the next release:
|
||||
|
||||
@ -286,71 +389,11 @@ Start the next release:
|
||||
* Update the Savannah URL for the bugs fixed in the NEWS section.
|
||||
|
||||
|
||||
Publishing a Package
|
||||
--------------------
|
||||
|
||||
In order to publish a package on the FSF FTP site, either the release
|
||||
site ftp://ftp.gnu.org, or the prerelease site ftp://alpha.gnu.org, you
|
||||
first need to have my GPG private key and my passphrase to unlock it.
|
||||
And, you can't have them! So there! But, just so I remember here's
|
||||
what to do:
|
||||
|
||||
Make sure the "Steps to Release" are complete and committed and tagged.
|
||||
|
||||
git clone git://git.savannah.gnu.org/make.git make-release
|
||||
|
||||
cd make-release
|
||||
|
||||
<run the commands above to build the release>
|
||||
|
||||
make upload-alpha # for alpha.gnu.org (pre-releases)
|
||||
-OR-
|
||||
make upload-ftp # for ftp.gnu.org (official releases)
|
||||
|
||||
Depending on your distribution (whether GnuPG is integrated with your keyring
|
||||
etc.) it will either pop up a window asking for your GPG key passphrase one
|
||||
time, or else it will use the CLI to ask for the GPG passphrase _THREE_ times.
|
||||
Sigh.
|
||||
|
||||
|
||||
For both final releases and pre-releases, send an email with the URL of
|
||||
the package to the GNU translation robot to allow the translators to
|
||||
work on it:
|
||||
|
||||
<coordinator@translationproject.org>
|
||||
|
||||
|
||||
Where to Announce
|
||||
-----------------
|
||||
|
||||
Create the announcement in a text file, using 'git shortlog',
|
||||
then sign it with GPG:
|
||||
|
||||
gpg --clearsign <announcement.txt>
|
||||
|
||||
Or, use your mail client's PGP/GPG signing capabilities.
|
||||
|
||||
Announce the release:
|
||||
|
||||
* For release candidate builds:
|
||||
To: bug-make@gnu.org
|
||||
CC: coordinator@translationproject.org
|
||||
BCC: help-make@gnu.org, make-w32@gnu.org, make-alpha@gnu.org
|
||||
|
||||
* For release builds
|
||||
To: info-gnu@gnu.org, bug-make@gnu.org
|
||||
CC: coordinator@translationproject.org
|
||||
BCC: help-make@gnu.org, make-w32@gnu.org, make-alpha@gnu.org
|
||||
|
||||
* Add a news item to the Savannah project site.
|
||||
* Add an update to freecode.com (nee freshmeat.net)
|
||||
|
||||
|
||||
Appendix A - For The Brave
|
||||
--------------------------
|
||||
|
||||
For those of you who trust me implicitly, or are just brave (or
|
||||
foolhardy), here is a canned sequence of commands to build a GNU make
|
||||
foolhardy), here is a canned sequence of commands to build a GNU Make
|
||||
distribution package from a virgin Git source checkout (assuming all the
|
||||
prerequisites are available of course).
|
||||
|
||||
@ -361,6 +404,6 @@ For a debugging version:
|
||||
|
||||
./bootstrap && ./configure CFLAGS=-g && make check
|
||||
|
||||
For a release version
|
||||
For an optimized version
|
||||
|
||||
./bootstrap && ./configure && make check
|
||||
|
@ -1,13 +1,17 @@
|
||||
This directory contains the %VERSION% release of GNU Make.
|
||||
This directory contains the @PACKAGE_VERSION@ release of @PACKAGE_NAME@.
|
||||
|
||||
See the file NEWS for the user-visible changes from previous releases.
|
||||
In addition, there have been bugs fixed.
|
||||
|
||||
>> If you are trying to build GNU Make from a Git clone rather than a
|
||||
>> downloaded source distribution, see the README.git file for instructions.
|
||||
|
||||
Please check the system-specific notes below for any caveats related to your
|
||||
operating system.
|
||||
|
||||
If you are trying to build GNU make from a Git clone rather than a downloaded
|
||||
source distribution, see the README.git file for instructions.
|
||||
This README assumes you are building on a POSIX-based operating system.
|
||||
For ports to other operating systems please see the system-specific README
|
||||
files, as described in the "Ports" section below.
|
||||
|
||||
For source distribution building and installation instructions, see the file
|
||||
INSTALL.
|
||||
@ -15,12 +19,12 @@ INSTALL.
|
||||
If you need to build GNU Make and have no other 'make' program to use, you can
|
||||
use the shell script 'build.sh' instead. To do this, first run 'configure' as
|
||||
described in INSTALL. Then, instead of typing 'make' to build the program,
|
||||
type 'sh build.sh'. This should compile the program in the current directory.
|
||||
Then you will have a Make program that you can use for './make install', or
|
||||
type 'sh build.sh'. This will compile the program in the current directory.
|
||||
Then you will have a 'make' program that you can use for './make install', or
|
||||
whatever else.
|
||||
|
||||
Some systems' Make programs cannot process the Makefile for GNU Make. If you
|
||||
get errors from your system's Make when building GNU Make, try using
|
||||
Some systems' 'make' programs cannot process the Makefile for GNU Make.
|
||||
If you get errors from your system's 'make' when building GNU Make, try using
|
||||
'build.sh' instead.
|
||||
|
||||
|
||||
@ -29,6 +33,7 @@ GNU Make is copyright by the Free Software Foundation. Copyright notices
|
||||
condense sequential years into a range; e.g. "1987-1994" means all years
|
||||
from 1987 to 1994 inclusive.
|
||||
|
||||
|
||||
Downloading
|
||||
-----------
|
||||
|
||||
@ -40,10 +45,10 @@ GNU Make can be obtained in many different ways. See a description here:
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
GNU make is fully documented in the GNU Make manual, which is contained
|
||||
in this distribution as the file make.texinfo. You can also find
|
||||
on-line and preformatted (PostScript and DVI) versions at the FSF's web
|
||||
site. There is information there about ordering hardcopy documentation.
|
||||
GNU Make is fully documented in the GNU Make manual, which is contained in
|
||||
this distribution as the file make.texi. You can also find on-line and
|
||||
preformatted (PostScript and DVI) versions at the FSF's web site. There is
|
||||
information there about ordering hardcopy documentation.
|
||||
|
||||
https://www.gnu.org/
|
||||
https://www.gnu.org/doc/doc.html
|
||||
@ -66,30 +71,43 @@ You can find most information concerning the development of GNU Make at
|
||||
this site.
|
||||
|
||||
|
||||
Regression Tests
|
||||
----------------
|
||||
|
||||
GNU Make contains a suite of regression tests. To run them use "make check"
|
||||
after building GNU Make. If they fail a tar package will be created
|
||||
containing useful information, which can be emailed (as an attachment) to
|
||||
the <bug-make@gnu.org> mailing list.
|
||||
|
||||
Please note that since these tests rely on known-good-output comparisons,
|
||||
they can show spurious failures on some systems (particularly non-POSIX systems
|
||||
such as Windows).
|
||||
|
||||
|
||||
Bug Reporting
|
||||
-------------
|
||||
|
||||
You can send GNU make bug reports to <bug-make@gnu.org>. Please see the
|
||||
section of the GNU make manual entitled 'Problems and Bugs' for
|
||||
information on submitting useful and complete bug reports.
|
||||
If you need help using GNU Make, try asking on <help-make@gnu.org>.
|
||||
|
||||
If you found a bug, you can send a bug reports to <bug-make@gnu.org>.
|
||||
Please see the section of the GNU Make manual entitled 'Problems and Bugs'
|
||||
for information on submitting useful and complete bug reports.
|
||||
|
||||
You do not need to subscribe to these lists first.
|
||||
|
||||
You can also use the online bug tracking system in the Savannah GNU Make
|
||||
project to submit new problem reports or search for existing ones:
|
||||
|
||||
https://savannah.gnu.org/bugs/?group=make
|
||||
|
||||
If you need help using GNU make, try these forums:
|
||||
|
||||
help-make@gnu.org
|
||||
help-utils@gnu.org
|
||||
news:gnu.utils.help
|
||||
news:gnu.utils.bug
|
||||
We prefer to use the bug tracking system ONLY for bugs or enhancements,
|
||||
not for help requests: please use the mailing lists to get help.
|
||||
|
||||
|
||||
Submitting Patches
|
||||
------------------
|
||||
|
||||
If you'd like to propose a change to GNU make, you can provide a patch with
|
||||
If you'd like to propose a change to GNU Make, you can provide a patch with
|
||||
your changes. If you are making your changes in a Git workspace you can run
|
||||
"git format-patch" to create a patch file. If not, you can use the diff(1)
|
||||
utility to create a patch file; please use "diff -u".
|
||||
@ -102,24 +120,23 @@ Once you have a patch you can submit it in any of these ways:
|
||||
* Send the patch via email to <bug-make@gnu.org>: be sure to add it as an
|
||||
attachment to avoid interference by email processors.
|
||||
|
||||
Be aware that all non-trivial changes proposed for GNU make require FSF
|
||||
copyright paperwork to be completed before they can be accepted. Contact
|
||||
<bug-make@gnu.org> for help.
|
||||
All non-trivial changes require FSF copyright paperwork to be completed
|
||||
before they can be accepted. Contact <bug-make@gnu.org> for help.
|
||||
|
||||
|
||||
Git Access
|
||||
----------
|
||||
|
||||
The GNU make source repository is available via Git from the GNU Savannah Git
|
||||
The GNU Make source repository is available via Git from the GNU Savannah Git
|
||||
server; look here for details:
|
||||
|
||||
https://savannah.gnu.org/git/?group=make
|
||||
|
||||
Please note: you won't be able to build GNU make from Git without installing
|
||||
Please note: you won't be able to build GNU Make from Git without installing
|
||||
appropriate maintainer's tools, such as GNU m4, automake, autoconf, Perl, GNU
|
||||
make, and GCC.
|
||||
|
||||
See the README.git file for instructions on how to build GNU make once these
|
||||
See the README.git file for instructions on how to build GNU Make once these
|
||||
tools are available. We make no guarantees about the contents or quality of
|
||||
the latest code in the Git repository: it is not unheard of for code that is
|
||||
known to be broken to be checked in. Use at your own risk.
|
||||
@ -128,21 +145,11 @@ known to be broken to be checked in. Use at your own risk.
|
||||
System-specific Notes
|
||||
---------------------
|
||||
|
||||
It has been reported that the XLC 1.2 compiler on AIX 3.2 is buggy such
|
||||
that if you compile make with 'cc -O' on AIX 3.2, it will not work
|
||||
correctly. It is said that using 'cc' without '-O' does work.
|
||||
|
||||
The standard /bin/sh on SunOS 4.1.3_U1 and 4.1.4 is broken and cannot be
|
||||
used to configure GNU make. Please install a different shell such as
|
||||
bash or pdksh in order to run "configure". See this message for more
|
||||
information:
|
||||
https://mail.gnu.org/archive/html/bug-autoconf/2003-10/msg00190.html
|
||||
|
||||
One area that is often a problem in configuration and porting is the code
|
||||
to check the system's current load average. To make it easier to test and
|
||||
debug this code, you can do 'make check-loadavg' to see if it works
|
||||
properly on your system. (You must run 'configure' beforehand, but you
|
||||
need not build Make itself to run this test.)
|
||||
need not build 'make' itself to run this test.)
|
||||
|
||||
Another potential source of porting problems is the support for large
|
||||
files (LFS) in configure for those operating systems that provide it.
|
||||
@ -151,7 +158,7 @@ difficulties, then as a workaround you should be able to disable LFS by
|
||||
adding the '--disable-largefile' option to the 'configure' script.
|
||||
|
||||
On systems that support micro- and nano-second timestamp values and
|
||||
where stat(2) provides this information, GNU make will use it when
|
||||
where stat(2) provides this information, GNU Make will use it when
|
||||
comparing timestamps to get the most accurate possible result. However,
|
||||
note that many current implementations of tools that *set* timestamps do
|
||||
not preserve micro- or nano-second granularity. This means that "cp -p"
|
||||
@ -165,12 +172,12 @@ force make to treat them properly. See the manual for details.
|
||||
Ports
|
||||
-----
|
||||
|
||||
- See README.customs for details on integrating GNU make with the
|
||||
- See README.customs for details on integrating GNU Make with the
|
||||
Customs distributed build environment from the Pmake distribution.
|
||||
|
||||
- See README.VMS for details about GNU Make on OpenVMS.
|
||||
|
||||
- See README.Amiga for details about GNU Make on AmigaDOS.
|
||||
- See README.zOS for details about GNU Make on z/OS.
|
||||
|
||||
- See README.W32 for details about GNU Make on Windows NT, 95, or 98.
|
||||
|
||||
@ -181,19 +188,19 @@ Ports
|
||||
of DJGPP; see the WWW page https://www.delorie.com/djgpp/ for more
|
||||
information.
|
||||
|
||||
The Cygwin project maintains its own port of GNU make. That port may have
|
||||
The Cygwin project maintains its own port of GNU Make. That port may have
|
||||
patches which are not present in this version. If you are using Cygwin
|
||||
you should use their version of GNU make, and if you have questions about
|
||||
you should use their version of GNU Make, and if you have questions about
|
||||
it you should start by asking on those mailing lists and forums.
|
||||
|
||||
Please note there are two _separate_ ports of GNU make for Microsoft
|
||||
systems: a native Windows tool built with (for example) MSVC or Cygwin,
|
||||
and a DOS-based tool built with DJGPP. Please be sure you are looking
|
||||
Please note there are two _separate_ ports of GNU Make for Microsoft
|
||||
systems: a native Windows port built with (for example) MSVC or MinGW,
|
||||
and a DOS-based port built with DJGPP. Please be sure you are looking
|
||||
at the right README!
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 1988-2022 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988-2024 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
83
README.zOS
Normal file
83
README.zOS
Normal file
@ -0,0 +1,83 @@
|
||||
-*-text-*-
|
||||
GNU Make has been ported to z/OS, tested on z/OS V2R4.
|
||||
|
||||
|
||||
PREREQUISITES
|
||||
-------------
|
||||
Building GNU Make requires certain tools be installed on your z/OS system.
|
||||
These tools can be downloaded from: https://github.com/ZOSOpenTools
|
||||
For detailed instructions on how to set up these tools, visit
|
||||
https://zosopentools.github.io/meta/#/Guides/Pre-req
|
||||
|
||||
You will need curl, tar, and gzip to download and unpack the GNU Make release
|
||||
package, but presumably you've already worked this out if you're reading this
|
||||
document!
|
||||
|
||||
You will need the IBM C/C++ compiler. You can download a web deliverable
|
||||
add-on feature to your XL C/C++ compiler here:
|
||||
https://www-40.ibm.com/servers/resourcelink/svc00100.nsf/pages/xlCC++V241ForZOsV24
|
||||
|
||||
Alternatively, you can install and manage C/C++ for Open Enterprise Languages
|
||||
on z/OS using RedHat OpenShift Container Platform and IBM Z and Cloud
|
||||
Modernization Stack.
|
||||
|
||||
GNU Make has a dependency on the ZOSLIB library, which is documented here:
|
||||
https://zosopentools.github.io/meta/#/Guides/Zoslib.
|
||||
|
||||
To obtain the latest release of zoslib, you can download it from here:
|
||||
https://github.com/ZOSOpenTools/zoslibport/releases.
|
||||
|
||||
|
||||
BUILDING
|
||||
--------
|
||||
If you are trying to build from a checked-out Git workspace, see README.git.
|
||||
|
||||
Before building GNU Make, you will need to ensure that the following
|
||||
environment variables are set, to turn on z/OS enhanced ASCII support:
|
||||
|
||||
export _BPXK_AUTOCVT=ON
|
||||
export _CEE_RUNOPTS="$_CEE_RUNOPTS FILETAG(AUTOCVT,AUTOTAG) POSIX(ON)"
|
||||
export _TAG_REDIR_ERR=txt
|
||||
export _TAG_REDIR_IN=txt
|
||||
export _TAG_REDIR_OUT=txt
|
||||
|
||||
To ensure proper functioning of xlclang, set the following environment
|
||||
variables before building:
|
||||
|
||||
export _CC_CCMODE=1
|
||||
export _C89_CCMODE=1
|
||||
export _CXX_CCMODE=1
|
||||
|
||||
Set PATH_TO_ZOSLIB to the location of your zoslib installation; e.g.:
|
||||
|
||||
PATH_TO_ZOSLIB=$HOME/zopen/prod/zoslib
|
||||
|
||||
Invoke ./configure as follows:
|
||||
|
||||
./configure \
|
||||
CC=xlclang \
|
||||
CPPFLAGS="-DNSIG=42 -D_XOPEN_SOURCE=600 -D_ALL_SOURCE -D_OPEN_SYS_FILE_EXT=1 -D_AE_BIMODAL=1 -D_ENHANCED_ASCII_EXT=0xFFFFFFF -DZOSLIB_OVERRIDE_CLIB=1" \
|
||||
CFLAGS="-qascii -std=gnu11 -qnocsect -qenum=int -I$PATH_TO_ZOSLIB/include" \
|
||||
LDFLAGS="-L$PATH_TO_ZOSLIB/lib" \
|
||||
LIBS="-lzoslib $PATH_TO_ZOSLIB/lib/CXXRT64.x"
|
||||
|
||||
If you have an instance of make already available you can build with:
|
||||
|
||||
make
|
||||
|
||||
If not, you can build with:
|
||||
|
||||
./build.sh
|
||||
|
||||
|
||||
TESTING
|
||||
-------
|
||||
To run the regression tests you'll need to install Perl and enable it.
|
||||
Then you can run:
|
||||
|
||||
./make check
|
||||
|
||||
|
||||
INSTALLING
|
||||
----------
|
||||
Copy the "make" program to wherever you want it to be installed, on your PATH.
|
13
SCOPTIONS
13
SCOPTIONS
@ -1,13 +0,0 @@
|
||||
ERRORREXX
|
||||
OPTIMIZE
|
||||
NOVERSION
|
||||
OPTIMIZERTIME
|
||||
OPTIMIZERALIAS
|
||||
DEFINE HAVE_CONFIG_H
|
||||
DEFINE INCLUDEDIR="include:"
|
||||
DEFINE LIBDIR="lib:"
|
||||
DEFINE NO_ALLOCA
|
||||
DEFINE NO_ARCHIVES
|
||||
IGNORE=161
|
||||
IGNORE=100
|
||||
STARTUP=cres
|
@ -101,7 +101,7 @@ The Rest of the List
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 1997-2022 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997-2024 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
@ -114,4 +114,4 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
451
autogen.sh
451
autogen.sh
@ -4,7 +4,7 @@
|
||||
# also regenerates all aclocal.m4, config.h.in, Makefile.in, configure files
|
||||
# with new versions of autoconf or automake.
|
||||
|
||||
# Copyright (C) 2003-2022 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2003-2024 Free Software Foundation, Inc.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@ -30,457 +30,10 @@
|
||||
# Alternatively, you can use an autogen.sh script that is specific
|
||||
# to your package.
|
||||
|
||||
scriptversion=2022-07-24.15; # UTC
|
||||
|
||||
me="$0"
|
||||
medir=`dirname "$me"`
|
||||
|
||||
# Read the function library and the configuration.
|
||||
. "$medir"/bootstrap-funclib.sh
|
||||
|
||||
# Ensure that CDPATH is not set. Otherwise, the output from cd
|
||||
# would cause trouble in at least one use below.
|
||||
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
|
||||
|
||||
# Environment variables that may be set by the user.
|
||||
: "${AUTOPOINT=autopoint}"
|
||||
: "${AUTORECONF=autoreconf}"
|
||||
|
||||
if test "$vc_ignore" = auto; then
|
||||
vc_ignore=
|
||||
test -d .git && vc_ignore=.gitignore
|
||||
test -d CVS && vc_ignore="$vc_ignore .cvsignore"
|
||||
fi
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: $me [OPTION]...
|
||||
Bootstrap this package from the checked-out sources.
|
||||
|
||||
Optional environment variables:
|
||||
GNULIB_SRCDIR Specifies the local directory where gnulib
|
||||
sources reside. Use this if you already
|
||||
have gnulib sources on your machine, and
|
||||
you want to use these sources.
|
||||
|
||||
Options:
|
||||
--copy copy files instead of creating symbolic links
|
||||
--force attempt to bootstrap even if the sources seem
|
||||
not to have been checked out
|
||||
EOF
|
||||
bootstrap_print_option_usage_hook
|
||||
cat <<EOF
|
||||
If the file bootstrap.conf exists in the same directory as this script, its
|
||||
contents are read as shell variables to configure the bootstrap.
|
||||
|
||||
For build prerequisites, environment variables like \$AUTOCONF and \$AMTAR
|
||||
are honored.
|
||||
|
||||
Gnulib sources are assumed to be present:
|
||||
* in \$GNULIB_SRCDIR, if that environment variable is set,
|
||||
* otherwise, in the 'gnulib' submodule, if such a submodule is configured,
|
||||
* otherwise, in the 'gnulib' subdirectory.
|
||||
|
||||
Running without arguments will suffice in most cases.
|
||||
EOF
|
||||
}
|
||||
|
||||
# Parse options.
|
||||
|
||||
# Whether to use copies instead of symlinks.
|
||||
copy=false
|
||||
|
||||
for option
|
||||
do
|
||||
case $option in
|
||||
--help)
|
||||
usage
|
||||
exit;;
|
||||
--version)
|
||||
set -e
|
||||
echo "autogen.sh $scriptversion"
|
||||
echo "$copyright"
|
||||
exit 0
|
||||
;;
|
||||
--force)
|
||||
checkout_only_file=;;
|
||||
--copy)
|
||||
copy=true;;
|
||||
*)
|
||||
bootstrap_option_hook $option || die "$option: unknown option";;
|
||||
esac
|
||||
done
|
||||
|
||||
test -z "$GNULIB_SRCDIR" || test -d "$GNULIB_SRCDIR" \
|
||||
|| die "Error: \$GNULIB_SRCDIR environment variable or --gnulib-srcdir option is specified, but does not denote a directory"
|
||||
|
||||
if test -n "$checkout_only_file" && test ! -r "$checkout_only_file"; then
|
||||
die "Running this script from a non-checked-out distribution is risky."
|
||||
fi
|
||||
|
||||
if $use_gnulib; then
|
||||
if test -z "$GNULIB_SRCDIR"; then
|
||||
gnulib_path=$(test -f .gitmodules && git config --file .gitmodules submodule.gnulib.path)
|
||||
test -z "$gnulib_path" && gnulib_path=gnulib
|
||||
GNULIB_SRCDIR=$gnulib_path
|
||||
fi
|
||||
fi
|
||||
|
||||
version_controlled_file() {
|
||||
parent=$1
|
||||
file=$2
|
||||
if test -d .git; then
|
||||
git rm -n "$file" > /dev/null 2>&1
|
||||
elif test -d .svn; then
|
||||
svn log -r HEAD "$file" > /dev/null 2>&1
|
||||
elif test -d CVS; then
|
||||
grep -F "/${file##*/}/" "$parent/CVS/Entries" 2>/dev/null |
|
||||
grep '^/[^/]*/[0-9]' > /dev/null
|
||||
else
|
||||
warn_ "no version control for $file?"
|
||||
false
|
||||
fi
|
||||
}
|
||||
|
||||
# Strip blank and comment lines to leave significant entries.
|
||||
gitignore_entries() {
|
||||
sed '/^#/d; /^$/d' "$@"
|
||||
}
|
||||
|
||||
# If $STR is not already on a line by itself in $FILE, insert it at the start.
|
||||
# Entries are inserted at the start of the ignore list to ensure existing
|
||||
# entries starting with ! are not overridden. Such entries support
|
||||
# whitelisting exceptions after a more generic blacklist pattern.
|
||||
insert_if_absent() {
|
||||
file=$1
|
||||
str=$2
|
||||
test -f $file || touch $file
|
||||
test -r $file || die "Error: failed to read ignore file: $file"
|
||||
duplicate_entries=$(gitignore_entries $file | sort | uniq -d)
|
||||
if [ "$duplicate_entries" ] ; then
|
||||
die "Error: Duplicate entries in $file: " $duplicate_entries
|
||||
fi
|
||||
linesold=$(gitignore_entries $file | wc -l)
|
||||
linesnew=$( { echo "$str"; cat $file; } | gitignore_entries | sort -u | wc -l)
|
||||
if [ $linesold != $linesnew ] ; then
|
||||
{ echo "$str" | cat - $file > $file.bak && mv $file.bak $file; } \
|
||||
|| die "insert_if_absent $file $str: failed"
|
||||
fi
|
||||
}
|
||||
|
||||
# Adjust $PATTERN for $VC_IGNORE_FILE and insert it with
|
||||
# insert_if_absent.
|
||||
insert_vc_ignore() {
|
||||
vc_ignore_file="$1"
|
||||
pattern="$2"
|
||||
case $vc_ignore_file in
|
||||
*.gitignore)
|
||||
# A .gitignore entry that does not start with '/' applies
|
||||
# recursively to subdirectories, so prepend '/' to every
|
||||
# .gitignore entry.
|
||||
pattern=$(echo "$pattern" | sed s,^,/,);;
|
||||
esac
|
||||
insert_if_absent "$vc_ignore_file" "$pattern"
|
||||
}
|
||||
|
||||
symlink_to_dir()
|
||||
{
|
||||
src=$1/$2
|
||||
dst=${3-$2}
|
||||
|
||||
test -f "$src" && {
|
||||
|
||||
# If the destination directory doesn't exist, create it.
|
||||
# This is required at least for "lib/uniwidth/cjk.h".
|
||||
dst_dir=$(dirname "$dst")
|
||||
if ! test -d "$dst_dir"; then
|
||||
mkdir -p "$dst_dir"
|
||||
|
||||
# If we've just created a directory like lib/uniwidth,
|
||||
# tell version control system(s) it's ignorable.
|
||||
# FIXME: for now, this does only one level
|
||||
parent=$(dirname "$dst_dir")
|
||||
for dot_ig in x $vc_ignore; do
|
||||
test $dot_ig = x && continue
|
||||
ig=$parent/$dot_ig
|
||||
insert_vc_ignore $ig "${dst_dir##*/}"
|
||||
done
|
||||
fi
|
||||
|
||||
if $copy; then
|
||||
{
|
||||
test ! -h "$dst" || {
|
||||
echo "$me: rm -f $dst" &&
|
||||
rm -f "$dst"
|
||||
}
|
||||
} &&
|
||||
test -f "$dst" &&
|
||||
cmp -s "$src" "$dst" || {
|
||||
echo "$me: cp -fp $src $dst" &&
|
||||
cp -fp "$src" "$dst"
|
||||
}
|
||||
else
|
||||
# Leave any existing symlink alone, if it already points to the source,
|
||||
# so that broken build tools that care about symlink times
|
||||
# aren't confused into doing unnecessary builds. Conversely, if the
|
||||
# existing symlink's timestamp is older than the source, make it afresh,
|
||||
# so that broken tools aren't confused into skipping needed builds. See
|
||||
# <https://lists.gnu.org/r/bug-gnulib/2011-05/msg00326.html>.
|
||||
test -h "$dst" &&
|
||||
src_ls=$(ls -diL "$src" 2>/dev/null) && set $src_ls && src_i=$1 &&
|
||||
dst_ls=$(ls -diL "$dst" 2>/dev/null) && set $dst_ls && dst_i=$1 &&
|
||||
test "$src_i" = "$dst_i" &&
|
||||
both_ls=$(ls -dt "$src" "$dst") &&
|
||||
test "X$both_ls" = "X$dst$nl$src" || {
|
||||
dot_dots=
|
||||
case $src in
|
||||
/*) ;;
|
||||
*)
|
||||
case /$dst/ in
|
||||
*//* | */../* | */./* | /*/*/*/*/*/)
|
||||
die "invalid symlink calculation: $src -> $dst";;
|
||||
/*/*/*/*/) dot_dots=../../../;;
|
||||
/*/*/*/) dot_dots=../../;;
|
||||
/*/*/) dot_dots=../;;
|
||||
esac;;
|
||||
esac
|
||||
|
||||
echo "$me: ln -fs $dot_dots$src $dst" &&
|
||||
ln -fs "$dot_dots$src" "$dst"
|
||||
}
|
||||
fi
|
||||
}
|
||||
}
|
||||
|
||||
# Die if there is no AC_CONFIG_AUX_DIR($build_aux) line in configure.ac.
|
||||
found_aux_dir=no
|
||||
grep '^[ ]*AC_CONFIG_AUX_DIR(\['"$build_aux"'])' configure.ac \
|
||||
>/dev/null && found_aux_dir=yes
|
||||
grep '^[ ]*AC_CONFIG_AUX_DIR('"$build_aux"')' configure.ac \
|
||||
>/dev/null && found_aux_dir=yes
|
||||
test $found_aux_dir = yes \
|
||||
|| die "configure.ac lacks 'AC_CONFIG_AUX_DIR([$build_aux])'; add it"
|
||||
|
||||
# If $build_aux doesn't exist, create it now, otherwise some bits
|
||||
# below will malfunction. If creating it, also mark it as ignored.
|
||||
if test ! -d $build_aux; then
|
||||
mkdir $build_aux
|
||||
for dot_ig in x $vc_ignore; do
|
||||
test $dot_ig = x && continue
|
||||
insert_vc_ignore $dot_ig $build_aux
|
||||
done
|
||||
fi
|
||||
|
||||
check_build_prerequisites false
|
||||
|
||||
use_libtool=0
|
||||
# We'd like to use grep -E, to see if any of LT_INIT,
|
||||
# AC_PROG_LIBTOOL, AM_PROG_LIBTOOL is used in configure.ac,
|
||||
# but that's not portable enough (e.g., for Solaris).
|
||||
grep '^[ ]*A[CM]_PROG_LIBTOOL' configure.ac >/dev/null \
|
||||
&& use_libtool=1
|
||||
grep '^[ ]*LT_INIT' configure.ac >/dev/null \
|
||||
&& use_libtool=1
|
||||
if test $use_libtool = 1; then
|
||||
find_tool LIBTOOLIZE glibtoolize libtoolize
|
||||
fi
|
||||
|
||||
if $use_gnulib; then
|
||||
gnulib_tool=$GNULIB_SRCDIR/gnulib-tool
|
||||
<$gnulib_tool || exit $?
|
||||
fi
|
||||
|
||||
# NOTE: we have to be careful to run both autopoint and libtoolize
|
||||
# before gnulib-tool, since gnulib-tool is likely to provide newer
|
||||
# versions of files "installed" by these two programs.
|
||||
# Then, *after* gnulib-tool (see below), we have to be careful to
|
||||
# run autoreconf in such a way that it does not run either of these
|
||||
# two just-pre-run programs.
|
||||
|
||||
# Import from gettext.
|
||||
with_gettext=yes
|
||||
grep '^[ ]*AM_GNU_GETTEXT_VERSION(' configure.ac >/dev/null || \
|
||||
with_gettext=no
|
||||
|
||||
if test $with_gettext = yes || test $use_libtool = 1; then
|
||||
|
||||
tempbase=.bootstrap$$
|
||||
trap "rm -f $tempbase.0 $tempbase.1" 1 2 13 15
|
||||
|
||||
> $tempbase.0 > $tempbase.1 &&
|
||||
find . ! -type d -print | sort > $tempbase.0 || exit
|
||||
|
||||
if test $with_gettext = yes; then
|
||||
# Released autopoint has the tendency to install macros that have been
|
||||
# obsoleted in current gnulib, so run this before gnulib-tool.
|
||||
echo "$0: $AUTOPOINT --force"
|
||||
$AUTOPOINT --force || exit
|
||||
fi
|
||||
|
||||
# Autoreconf runs aclocal before libtoolize, which causes spurious
|
||||
# warnings if the initial aclocal is confused by the libtoolized
|
||||
# (or worse out-of-date) macro directory.
|
||||
# libtoolize 1.9b added the --install option; but we support back
|
||||
# to libtoolize 1.5.22, where the install action was default.
|
||||
if test $use_libtool = 1; then
|
||||
install=
|
||||
case $($LIBTOOLIZE --help) in
|
||||
*--install*) install=--install ;;
|
||||
esac
|
||||
echo "running: $LIBTOOLIZE $install --copy"
|
||||
$LIBTOOLIZE $install --copy
|
||||
fi
|
||||
|
||||
find . ! -type d -print | sort >$tempbase.1
|
||||
old_IFS=$IFS
|
||||
IFS=$nl
|
||||
for file in $(comm -13 $tempbase.0 $tempbase.1); do
|
||||
IFS=$old_IFS
|
||||
parent=${file%/*}
|
||||
version_controlled_file "$parent" "$file" || {
|
||||
for dot_ig in x $vc_ignore; do
|
||||
test $dot_ig = x && continue
|
||||
ig=$parent/$dot_ig
|
||||
insert_vc_ignore "$ig" "${file##*/}"
|
||||
done
|
||||
}
|
||||
done
|
||||
IFS=$old_IFS
|
||||
|
||||
rm -f $tempbase.0 $tempbase.1
|
||||
trap - 1 2 13 15
|
||||
fi
|
||||
|
||||
# Import from gnulib.
|
||||
|
||||
if $use_gnulib; then
|
||||
gnulib_tool_options="\
|
||||
--no-changelog\
|
||||
--aux-dir=$build_aux\
|
||||
--doc-base=$doc_base\
|
||||
--lib=$gnulib_name\
|
||||
--m4-base=$m4_base/\
|
||||
--source-base=$source_base/\
|
||||
--tests-base=$tests_base\
|
||||
--local-dir=$local_gl_dir\
|
||||
$gnulib_tool_option_extras\
|
||||
"
|
||||
if test $use_libtool = 1; then
|
||||
case "$gnulib_tool_options " in
|
||||
*' --libtool '*) ;;
|
||||
*) gnulib_tool_options="$gnulib_tool_options --libtool" ;;
|
||||
esac
|
||||
fi
|
||||
echo "$0: $gnulib_tool $gnulib_tool_options --import ..."
|
||||
$gnulib_tool $gnulib_tool_options --import $gnulib_modules \
|
||||
|| die "gnulib-tool failed"
|
||||
|
||||
for file in $gnulib_files; do
|
||||
symlink_to_dir "$GNULIB_SRCDIR" $file \
|
||||
|| die "failed to symlink $file"
|
||||
done
|
||||
fi
|
||||
|
||||
bootstrap_post_import_hook \
|
||||
|| die "bootstrap_post_import_hook failed"
|
||||
|
||||
# Remove any dangling symlink matching "*.m4" or "*.[ch]" in some
|
||||
# gnulib-populated directories. Such .m4 files would cause aclocal to fail.
|
||||
# The following requires GNU find 4.2.3 or newer. Considering the usual
|
||||
# portability constraints of this script, that may seem a very demanding
|
||||
# requirement, but it should be ok. Ignore any failure, which is fine,
|
||||
# since this is only a convenience to help developers avoid the relatively
|
||||
# unusual case in which a symlinked-to .m4 file is git-removed from gnulib
|
||||
# between successive runs of this script.
|
||||
find "$m4_base" "$source_base" \
|
||||
-depth \( -name '*.m4' -o -name '*.[ch]' \) \
|
||||
-type l -xtype l -delete > /dev/null 2>&1
|
||||
|
||||
# Invoke autoreconf with --force --install to ensure upgrades of tools
|
||||
# such as ylwrap.
|
||||
AUTORECONFFLAGS="--verbose --install --force -I $m4_base $ACLOCAL_FLAGS"
|
||||
|
||||
# Some systems (RHEL 5) are using ancient autotools, for which the
|
||||
# --no-recursive option had not been invented. Detect that lack and
|
||||
# omit the option when it's not supported. FIXME in 2017: remove this
|
||||
# hack when RHEL 5 autotools are updated, or when they become irrelevant.
|
||||
case $($AUTORECONF --help) in
|
||||
*--no-recursive*) AUTORECONFFLAGS="$AUTORECONFFLAGS --no-recursive";;
|
||||
esac
|
||||
|
||||
# Tell autoreconf not to invoke autopoint or libtoolize; they were run above.
|
||||
echo "running: AUTOPOINT=true LIBTOOLIZE=true $AUTORECONF $AUTORECONFFLAGS"
|
||||
AUTOPOINT=true LIBTOOLIZE=true $AUTORECONF $AUTORECONFFLAGS \
|
||||
|| die "autoreconf failed"
|
||||
|
||||
# Get some extra files from gnulib, overriding existing files.
|
||||
for file in $gnulib_extra_files; do
|
||||
case $file in
|
||||
*/INSTALL) dst=INSTALL;;
|
||||
build-aux/*) dst=$build_aux/${file#build-aux/};;
|
||||
*) dst=$file;;
|
||||
esac
|
||||
symlink_to_dir "$GNULIB_SRCDIR" $file $dst \
|
||||
|| die "failed to symlink $file"
|
||||
done
|
||||
|
||||
if test $with_gettext = yes; then
|
||||
# Create gettext configuration.
|
||||
echo "$0: Creating po/Makevars from po/Makevars.template ..."
|
||||
rm -f po/Makevars
|
||||
sed '
|
||||
/^EXTRA_LOCALE_CATEGORIES *=/s/=.*/= '"$EXTRA_LOCALE_CATEGORIES"'/
|
||||
/^COPYRIGHT_HOLDER *=/s/=.*/= '"$COPYRIGHT_HOLDER"'/
|
||||
/^MSGID_BUGS_ADDRESS *=/s|=.*|= '"$MSGID_BUGS_ADDRESS"'|
|
||||
/^XGETTEXT_OPTIONS *=/{
|
||||
s/$/ \\/
|
||||
a\
|
||||
'"$XGETTEXT_OPTIONS"' $${end_of_xgettext_options+}
|
||||
}
|
||||
' po/Makevars.template >po/Makevars \
|
||||
|| die 'cannot generate po/Makevars'
|
||||
|
||||
# If the 'gettext' module is in use, grab the latest Makefile.in.in.
|
||||
# If only the 'gettext-h' module is in use, assume autopoint already
|
||||
# put the correct version of this file into place.
|
||||
case $gnulib_modules in
|
||||
*gettext-h*) ;;
|
||||
*gettext*)
|
||||
cp $GNULIB_SRCDIR/build-aux/po/Makefile.in.in po/Makefile.in.in \
|
||||
|| die "cannot create po/Makefile.in.in"
|
||||
;;
|
||||
esac
|
||||
|
||||
if test -d runtime-po; then
|
||||
# Similarly for runtime-po/Makevars, but not quite the same.
|
||||
rm -f runtime-po/Makevars
|
||||
sed '
|
||||
/^DOMAIN *=.*/s/=.*/= '"$package"'-runtime/
|
||||
/^subdir *=.*/s/=.*/= runtime-po/
|
||||
/^MSGID_BUGS_ADDRESS *=/s/=.*/= bug-'"$package"'@gnu.org/
|
||||
/^XGETTEXT_OPTIONS *=/{
|
||||
s/$/ \\/
|
||||
a\
|
||||
'"$XGETTEXT_OPTIONS_RUNTIME"' $${end_of_xgettext_options+}
|
||||
}
|
||||
' po/Makevars.template >runtime-po/Makevars \
|
||||
|| die 'cannot generate runtime-po/Makevars'
|
||||
|
||||
# Copy identical files from po to runtime-po.
|
||||
(cd po && cp -p Makefile.in.in *-quot *.header *.sed *.sin ../runtime-po)
|
||||
fi
|
||||
fi
|
||||
|
||||
bootstrap_epilogue
|
||||
|
||||
echo "$0: done. Now you can run './configure'."
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# Local Variables:
|
||||
# eval: (add-hook 'before-save-hook 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC0"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
||||
autogen "$@"
|
||||
|
240
autopull.sh
240
autopull.sh
@ -2,7 +2,7 @@
|
||||
# Convenience script for fetching auxiliary files that are omitted from
|
||||
# the version control repository of this package.
|
||||
|
||||
# Copyright (C) 2003-2022 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2003-2024 Free Software Foundation, Inc.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@ -28,246 +28,10 @@
|
||||
# Alternatively, you can use an autopull.sh script that is specific
|
||||
# to your package.
|
||||
|
||||
scriptversion=2022-07-24.15; # UTC
|
||||
|
||||
me="$0"
|
||||
medir=`dirname "$me"`
|
||||
|
||||
# Read the function library and the configuration.
|
||||
. "$medir"/bootstrap-funclib.sh
|
||||
|
||||
# Ensure that CDPATH is not set. Otherwise, the output from cd
|
||||
# would cause trouble in at least one use below.
|
||||
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: $me [OPTION]...
|
||||
Bootstrap this package from the checked-out sources.
|
||||
|
||||
Optional environment variables:
|
||||
GNULIB_SRCDIR Specifies the local directory where gnulib
|
||||
sources reside. Use this if you already
|
||||
have gnulib sources on your machine, and
|
||||
you want to use these sources.
|
||||
GNULIB_REFDIR Specifies the local directory where a gnulib
|
||||
repository (with a .git subdirectory) resides.
|
||||
Use this if you already have gnulib sources
|
||||
and history on your machine, and do not want
|
||||
to waste your bandwidth downloading them again.
|
||||
GNULIB_URL Cloneable URL of the gnulib repository.
|
||||
|
||||
Options:
|
||||
--bootstrap-sync if this bootstrap script is not identical to
|
||||
the version in the local gnulib sources,
|
||||
update this script, and then restart it with
|
||||
/bin/sh or the shell \$CONFIG_SHELL
|
||||
--no-bootstrap-sync do not check whether bootstrap is out of sync
|
||||
--force attempt to bootstrap even if the sources seem
|
||||
not to have been checked out
|
||||
--no-git do not use git to update gnulib. Requires that
|
||||
\$GNULIB_SRCDIR or the --gnulib-srcdir option
|
||||
points to a gnulib repository with the correct
|
||||
revision
|
||||
--skip-po do not download po files
|
||||
EOF
|
||||
bootstrap_print_option_usage_hook
|
||||
cat <<EOF
|
||||
If the file bootstrap.conf exists in the same directory as this script, its
|
||||
contents are read as shell variables to configure the bootstrap.
|
||||
|
||||
For build prerequisites, environment variables like \$AUTOCONF and \$AMTAR
|
||||
are honored.
|
||||
|
||||
Gnulib sources can be fetched in various ways:
|
||||
|
||||
* If the environment variable GNULIB_SRCDIR is set (either as an
|
||||
environment variable or via the --gnulib-srcdir option), then sources
|
||||
are fetched from that local directory. If it is a git repository and
|
||||
the configuration variable GNULIB_REVISION is set in bootstrap.conf,
|
||||
then that revision is checked out.
|
||||
|
||||
* Otherwise, if this package is in a git repository with a 'gnulib'
|
||||
submodule configured, then that submodule is initialized and updated
|
||||
and sources are fetched from there. If GNULIB_REFDIR is set (either
|
||||
as an environment variable or via the --gnulib-refdir option) and is
|
||||
a git repository, then it is used as a reference.
|
||||
|
||||
* Otherwise, if the 'gnulib' directory does not exist, Gnulib sources
|
||||
are cloned into that directory using git from \$GNULIB_URL, defaulting
|
||||
to $default_gnulib_url.
|
||||
If the configuration variable GNULIB_REVISION is set in bootstrap.conf,
|
||||
then that revision is checked out.
|
||||
|
||||
* Otherwise, the existing Gnulib sources in the 'gnulib' directory are
|
||||
used. If it is a git repository and the configuration variable
|
||||
GNULIB_REVISION is set in bootstrap.conf, then that revision is
|
||||
checked out.
|
||||
|
||||
If you maintain a package and want to pin a particular revision of the
|
||||
Gnulib sources that has been tested with your package, then there are
|
||||
two possible approaches: either configure a 'gnulib' submodule with the
|
||||
appropriate revision, or set GNULIB_REVISION (and if necessary
|
||||
GNULIB_URL) in bootstrap.conf.
|
||||
|
||||
Running without arguments will suffice in most cases.
|
||||
EOF
|
||||
}
|
||||
|
||||
# Parse options.
|
||||
|
||||
# Use git to update gnulib sources
|
||||
use_git=true
|
||||
|
||||
for option
|
||||
do
|
||||
case $option in
|
||||
--help)
|
||||
usage
|
||||
exit;;
|
||||
--version)
|
||||
set -e
|
||||
echo "autopull.sh $scriptversion"
|
||||
echo "$copyright"
|
||||
exit 0
|
||||
;;
|
||||
--skip-po)
|
||||
SKIP_PO=t;;
|
||||
--force)
|
||||
checkout_only_file=;;
|
||||
--bootstrap-sync)
|
||||
bootstrap_sync=true;;
|
||||
--no-bootstrap-sync)
|
||||
bootstrap_sync=false;;
|
||||
--no-git)
|
||||
use_git=false;;
|
||||
*)
|
||||
bootstrap_option_hook $option || die "$option: unknown option";;
|
||||
esac
|
||||
done
|
||||
|
||||
$use_git || test -n "$GNULIB_SRCDIR" \
|
||||
|| die "Error: --no-git requires \$GNULIB_SRCDIR environment variable or --gnulib-srcdir option"
|
||||
test -z "$GNULIB_SRCDIR" || test -d "$GNULIB_SRCDIR" \
|
||||
|| die "Error: \$GNULIB_SRCDIR environment variable or --gnulib-srcdir option is specified, but does not denote a directory"
|
||||
|
||||
if test -n "$checkout_only_file" && test ! -r "$checkout_only_file"; then
|
||||
die "Running this script from a non-checked-out distribution is risky."
|
||||
fi
|
||||
|
||||
check_build_prerequisites $use_git
|
||||
|
||||
if $use_gnulib || $bootstrap_sync; then
|
||||
prepare_GNULIB_SRCDIR
|
||||
if $bootstrap_sync; then
|
||||
upgrade_bootstrap
|
||||
fi
|
||||
fi
|
||||
|
||||
# Find sha1sum, named gsha1sum on MacPorts, shasum on Mac OS X 10.6.
|
||||
# Also find the compatible sha1 utility on the BSDs
|
||||
if test x"$SKIP_PO" = x; then
|
||||
find_tool SHA1SUM sha1sum gsha1sum shasum sha1
|
||||
fi
|
||||
|
||||
# See if we can use gnulib's git-merge-changelog merge driver.
|
||||
if $use_git && test -d .git && check_exists git; then
|
||||
if git config merge.merge-changelog.driver >/dev/null ; then
|
||||
:
|
||||
elif check_exists git-merge-changelog; then
|
||||
echo "$0: initializing git-merge-changelog driver"
|
||||
git config merge.merge-changelog.name 'GNU-style ChangeLog merge driver'
|
||||
git config merge.merge-changelog.driver 'git-merge-changelog %O %A %B'
|
||||
else
|
||||
echo "$0: consider installing git-merge-changelog from gnulib"
|
||||
fi
|
||||
fi
|
||||
|
||||
# ----------------------------- Get translations. -----------------------------
|
||||
|
||||
download_po_files() {
|
||||
subdir=$1
|
||||
domain=$2
|
||||
echo "$me: getting translations into $subdir for $domain..."
|
||||
cmd=$(printf "$po_download_command_format" "$subdir" "$domain")
|
||||
eval "$cmd"
|
||||
}
|
||||
|
||||
# Mirror .po files to $po_dir/.reference and copy only the new
|
||||
# or modified ones into $po_dir. Also update $po_dir/LINGUAS.
|
||||
# Note po files that exist locally only are left in $po_dir but will
|
||||
# not be included in LINGUAS and hence will not be distributed.
|
||||
update_po_files() {
|
||||
# Directory containing primary .po files.
|
||||
# Overwrite them only when we're sure a .po file is new.
|
||||
po_dir=$1
|
||||
domain=$2
|
||||
|
||||
# Mirror *.po files into this dir.
|
||||
# Usually contains *.s1 checksum files.
|
||||
ref_po_dir="$po_dir/.reference"
|
||||
|
||||
test -d $ref_po_dir || mkdir $ref_po_dir || return
|
||||
download_po_files $ref_po_dir $domain \
|
||||
&& ls "$ref_po_dir"/*.po 2>/dev/null |
|
||||
sed 's|.*/||; s|\.po$||' > "$po_dir/LINGUAS" || return
|
||||
|
||||
langs=$(cd $ref_po_dir && echo *.po | sed 's/\.po//g')
|
||||
test "$langs" = '*' && langs=x
|
||||
for po in $langs; do
|
||||
case $po in x) continue;; esac
|
||||
new_po="$ref_po_dir/$po.po"
|
||||
cksum_file="$ref_po_dir/$po.s1"
|
||||
if ! test -f "$cksum_file" ||
|
||||
! test -f "$po_dir/$po.po" ||
|
||||
! $SHA1SUM -c "$cksum_file" < "$new_po" > /dev/null 2>&1; then
|
||||
echo "$me: updated $po_dir/$po.po..."
|
||||
cp "$new_po" "$po_dir/$po.po" \
|
||||
&& $SHA1SUM < "$new_po" > "$cksum_file" || return
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
case $SKIP_PO in
|
||||
'')
|
||||
if test -d po; then
|
||||
update_po_files po $package || exit
|
||||
fi
|
||||
|
||||
if test -d runtime-po; then
|
||||
update_po_files runtime-po $package-runtime || exit
|
||||
fi;;
|
||||
esac
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
bootstrap_post_pull_hook \
|
||||
|| die "bootstrap_post_pull_hook failed"
|
||||
|
||||
# Don't proceed if there are uninitialized submodules. In particular,
|
||||
# autogen.sh will remove dangling links, which might be links into
|
||||
# uninitialized submodules.
|
||||
# But it's OK if the 'gnulib' submodule is uninitialized, as long as
|
||||
# GNULIB_SRCDIR is set.
|
||||
if $use_git; then
|
||||
# Uninitialized submodules are listed with an initial dash.
|
||||
uninitialized=`git submodule | grep '^-' | awk '{ print $2 }'`
|
||||
if test -n "$GNULIB_SRCDIR"; then
|
||||
uninitialized=`echo "$uninitialized" | grep -v '^gnulib$'`
|
||||
fi
|
||||
if test -n "$uninitialized"; then
|
||||
die "Some git submodules are not initialized: "`echo "$uninitialized" | tr '\n' ',' | sed -e 's|,$|.|'`" Either use option '--no-git', or run 'git submodule update --init' and bootstrap again."
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "$0: done. Now you can run './autogen.sh'."
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# Local Variables:
|
||||
# eval: (add-hook 'before-save-hook 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC0"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
||||
autopull "$@"
|
||||
|
48
bootstrap
48
bootstrap
@ -1,7 +1,9 @@
|
||||
#! /bin/sh
|
||||
# Bootstrap this package from checked-out sources.
|
||||
|
||||
# Copyright (C) 2003-2022 Free Software Foundation, Inc.
|
||||
scriptversion=2022-12-27.07; # UTC
|
||||
|
||||
# Copyright (C) 2003-2023 Free Software Foundation, Inc.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@ -26,8 +28,6 @@
|
||||
|
||||
# Please report bugs or propose patches to bug-gnulib@gnu.org.
|
||||
|
||||
scriptversion=2022-07-29.23; # UTC
|
||||
|
||||
me="$0"
|
||||
medir=`dirname "$me"`
|
||||
|
||||
@ -48,6 +48,11 @@ Optional environment variables:
|
||||
GNULIB_URL Cloneable URL of the gnulib repository.
|
||||
|
||||
Options:
|
||||
|
||||
--pull Do phase 1: pull files from network
|
||||
--gen Do phase 2: generate from local files.
|
||||
(The default is to do both phases.)
|
||||
|
||||
--gnulib-srcdir=DIRNAME specify the local directory where gnulib
|
||||
sources reside. Use this if you already
|
||||
have gnulib sources on your machine, and
|
||||
@ -59,11 +64,13 @@ Options:
|
||||
and history on your machine, and do not want
|
||||
to waste your bandwidth downloading them again.
|
||||
Defaults to \$GNULIB_REFDIR
|
||||
|
||||
--bootstrap-sync if this bootstrap script is not identical to
|
||||
the version in the local gnulib sources,
|
||||
update this script, and then restart it with
|
||||
/bin/sh or the shell \$CONFIG_SHELL
|
||||
--no-bootstrap-sync do not check whether bootstrap is out of sync
|
||||
|
||||
--copy copy files instead of creating symbolic links
|
||||
--force attempt to bootstrap even if the sources seem
|
||||
not to have been checked out
|
||||
@ -118,6 +125,10 @@ EOF
|
||||
|
||||
# Parse options.
|
||||
|
||||
# Whether to pull and generate.
|
||||
pull=false
|
||||
gen=false
|
||||
|
||||
# Whether to use copies instead of symlinks.
|
||||
copy=false
|
||||
|
||||
@ -132,10 +143,14 @@ do
|
||||
exit;;
|
||||
--version)
|
||||
set -e
|
||||
echo "bootstrap $scriptversion"
|
||||
echo "bootstrap $scriptversion lib $scriptlibversion"
|
||||
echo "$copyright"
|
||||
exit 0
|
||||
;;
|
||||
--pull)
|
||||
pull=true;;
|
||||
--gen)
|
||||
gen=true;;
|
||||
--gnulib-srcdir=*)
|
||||
GNULIB_SRCDIR=${option#--gnulib-srcdir=};;
|
||||
--gnulib-refdir=*)
|
||||
@ -157,6 +172,9 @@ do
|
||||
esac
|
||||
done
|
||||
|
||||
# Default is to do both.
|
||||
$pull || $gen || pull=true gen=true
|
||||
|
||||
$use_git || test -n "$GNULIB_SRCDIR" \
|
||||
|| die "Error: --no-git requires \$GNULIB_SRCDIR environment variable or --gnulib-srcdir option"
|
||||
test -z "$GNULIB_SRCDIR" || test -d "$GNULIB_SRCDIR" \
|
||||
@ -168,12 +186,6 @@ fi
|
||||
|
||||
check_build_prerequisites $use_git
|
||||
|
||||
if ! test -f "$medir"/bootstrap-funclib.sh; then
|
||||
# We have only completed the first phase of an upgrade from a bootstrap
|
||||
# version < 2022-07-24. Need to do the second phase now.
|
||||
bootstrap_sync=true
|
||||
fi
|
||||
|
||||
if $bootstrap_sync; then
|
||||
prepare_GNULIB_SRCDIR
|
||||
upgrade_bootstrap
|
||||
@ -183,25 +195,25 @@ fi
|
||||
|
||||
echo "$0: Bootstrapping from checked-out $package sources..."
|
||||
|
||||
# Pass GNULIB_SRCDIR to autopull.sh and autogen.sh.
|
||||
# Pass GNULIB_SRCDIR and GNULIB_REFDIR to any subsidiary commands that care.
|
||||
export GNULIB_SRCDIR
|
||||
|
||||
# Pass GNULIB_REFDIR to autopull.sh.
|
||||
export GNULIB_REFDIR
|
||||
|
||||
if $use_git || test -z "$SKIP_PO"; then
|
||||
"$medir"/autopull.sh \
|
||||
if $pull && { $use_git || test -z "$SKIP_PO"; }; then
|
||||
autopull \
|
||||
`if $bootstrap_sync; then echo ' --bootstrap-sync'; else echo ' --no-bootstrap-sync'; fi` \
|
||||
`if test -z "$checkout_only_file"; then echo ' --force'; fi` \
|
||||
`if ! $use_git; then echo ' --no-git'; fi` \
|
||||
`if test -n "$SKIP_PO"; then echo ' --skip-po'; fi` \
|
||||
|| die "autopull.sh failed."
|
||||
|| die "could not fetch auxiliary files"
|
||||
fi
|
||||
|
||||
"$medir"/autogen.sh \
|
||||
if $gen; then
|
||||
autogen \
|
||||
`if $copy; then echo ' --copy'; fi` \
|
||||
`if test -z "$checkout_only_file"; then echo ' --force'; fi` \
|
||||
|| die "autogen.sh failed."
|
||||
|| die "could not generate auxiliary files"
|
||||
fi
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
# A library of shell functions for autopull.sh, autogen.sh, and bootstrap.
|
||||
|
||||
# Copyright (C) 2003-2022 Free Software Foundation, Inc.
|
||||
scriptlibversion=2022-12-27.16; # UTC
|
||||
|
||||
# Copyright (C) 2003-2024 Free Software Foundation, Inc.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@ -23,8 +25,6 @@
|
||||
# file also maintained in your version control; gnulib comes with a
|
||||
# template build-aux/bootstrap.conf to get you started.
|
||||
|
||||
scriptversion=2022-07-24.15; # UTC
|
||||
|
||||
nl='
|
||||
'
|
||||
|
||||
@ -38,7 +38,7 @@ PERL="${PERL-perl}"
|
||||
default_gnulib_url=https://git.savannah.gnu.org/git/gnulib.git
|
||||
|
||||
# Copyright year, for the --version output.
|
||||
copyright_year=`echo "$scriptversion" | sed -e 's/[^0-9].*//'`
|
||||
copyright_year=`echo "$scriptlibversion" | sed -e 's/[^0-9].*//'`
|
||||
copyright="Copyright (C) ${copyright_year} Free Software Foundation, Inc.
|
||||
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
|
||||
This is free software: you are free to change and redistribute it.
|
||||
@ -501,7 +501,7 @@ prepare_GNULIB_SRCDIR ()
|
||||
elif [ ! -d "$gnulib_path" ]; then
|
||||
echo "$0: getting gnulib files..."
|
||||
|
||||
trap cleanup_gnulib 1 2 13 15
|
||||
trap cleanup_gnulib HUP INT PIPE TERM
|
||||
|
||||
shallow=
|
||||
if test -z "$GNULIB_REVISION"; then
|
||||
@ -531,7 +531,7 @@ prepare_GNULIB_SRCDIR ()
|
||||
git -C "$gnulib_path" reset --hard FETCH_HEAD
|
||||
fi
|
||||
|
||||
trap - 1 2 13 15
|
||||
trap - HUP INT PIPE TERM
|
||||
fi
|
||||
fi
|
||||
GNULIB_SRCDIR=$gnulib_path
|
||||
@ -554,18 +554,28 @@ prepare_GNULIB_SRCDIR ()
|
||||
|
||||
upgrade_bootstrap ()
|
||||
{
|
||||
{ cmp -s "$medir"/bootstrap "$GNULIB_SRCDIR/top/bootstrap" \
|
||||
&& cmp -s "$medir"/bootstrap-funclib.sh "$GNULIB_SRCDIR/top/bootstrap-funclib.sh" \
|
||||
&& cmp -s "$medir"/autopull.sh "$GNULIB_SRCDIR/top/autopull.sh" \
|
||||
&& cmp -s "$medir"/autogen.sh "$GNULIB_SRCDIR/top/autogen.sh"; \
|
||||
} || {
|
||||
echo "$0: updating bootstrap & companions and restarting..."
|
||||
if test -f "$medir"/bootstrap-funclib.sh; then
|
||||
update_lib=true
|
||||
{ cmp -s "$medir"/bootstrap "$GNULIB_SRCDIR/top/bootstrap" \
|
||||
&& cmp -s "$medir"/bootstrap-funclib.sh "$GNULIB_SRCDIR/top/bootstrap-funclib.sh" \
|
||||
&& cmp -s "$medir"/autopull.sh "$GNULIB_SRCDIR/top/autopull.sh" \
|
||||
&& cmp -s "$medir"/autogen.sh "$GNULIB_SRCDIR/top/autogen.sh"; \
|
||||
}
|
||||
else
|
||||
update_lib=false
|
||||
cmp -s "$medir"/bootstrap "$GNULIB_SRCDIR/build-aux/bootstrap"
|
||||
fi || {
|
||||
if $update_lib; then
|
||||
echo "$0: updating bootstrap & companions and restarting..."
|
||||
else
|
||||
echo "$0: updating bootstrap and restarting..."
|
||||
fi
|
||||
case $(sh -c 'echo "$1"' -- a) in
|
||||
a) ignored=--;;
|
||||
*) ignored=ignored;;
|
||||
esac
|
||||
exec sh -c \
|
||||
'{ if test -f "$1"; then cp "$1" "$3"; else cp "$2" "$3"; fi; } && { if test -f "$4"; then cp "$4" "$5"; else rm -f "$5"; fi; } && { if test -f "$6"; then cp "$6" "$7"; else rm -f "$7"; fi; } && { if test -f "$8"; then cp "$8" "$9"; else rm -f "$9"; fi; } && shift && shift && shift && shift && shift && shift && shift && shift && shift && exec "${CONFIG_SHELL-/bin/sh}" "$@"' \
|
||||
'{ if '$update_lib' && test -f "$1"; then cp "$1" "$3"; else cp "$2" "$3"; fi; } && { if '$update_lib' && test -f "$4"; then cp "$4" "$5"; else rm -f "$5"; fi; } && { if '$update_lib' && test -f "$6"; then cp "$6" "$7"; else rm -f "$7"; fi; } && { if '$update_lib' && test -f "$8"; then cp "$8" "$9"; else rm -f "$9"; fi; } && shift && shift && shift && shift && shift && shift && shift && shift && shift && exec "${CONFIG_SHELL-/bin/sh}" "$@"' \
|
||||
$ignored \
|
||||
"$GNULIB_SRCDIR/top/bootstrap" "$GNULIB_SRCDIR/build-aux/bootstrap" "$medir/bootstrap" \
|
||||
"$GNULIB_SRCDIR/top/bootstrap-funclib.sh" "$medir/bootstrap-funclib.sh" \
|
||||
@ -583,11 +593,692 @@ else
|
||||
use_gnulib=true
|
||||
fi
|
||||
|
||||
# -------- Fetch auxiliary files from the network. --------------------------
|
||||
|
||||
autopull_usage() {
|
||||
cat <<EOF
|
||||
Usage: $me [OPTION]...
|
||||
Bootstrap this package from the checked-out sources.
|
||||
|
||||
Optional environment variables:
|
||||
GNULIB_SRCDIR Specifies the local directory where gnulib
|
||||
sources reside. Use this if you already
|
||||
have gnulib sources on your machine, and
|
||||
you want to use these sources.
|
||||
GNULIB_REFDIR Specifies the local directory where a gnulib
|
||||
repository (with a .git subdirectory) resides.
|
||||
Use this if you already have gnulib sources
|
||||
and history on your machine, and do not want
|
||||
to waste your bandwidth downloading them again.
|
||||
GNULIB_URL Cloneable URL of the gnulib repository.
|
||||
|
||||
Options:
|
||||
--bootstrap-sync if this bootstrap script is not identical to
|
||||
the version in the local gnulib sources,
|
||||
update this script, and then restart it with
|
||||
/bin/sh or the shell \$CONFIG_SHELL
|
||||
--no-bootstrap-sync do not check whether bootstrap is out of sync
|
||||
--force attempt to bootstrap even if the sources seem
|
||||
not to have been checked out
|
||||
--no-git do not use git to update gnulib. Requires that
|
||||
\$GNULIB_SRCDIR or the --gnulib-srcdir option
|
||||
points to a gnulib repository with the correct
|
||||
revision
|
||||
--skip-po do not download po files
|
||||
EOF
|
||||
bootstrap_print_option_usage_hook
|
||||
cat <<EOF
|
||||
If the file bootstrap.conf exists in the same directory as this script, its
|
||||
contents are read as shell variables to configure the bootstrap.
|
||||
|
||||
For build prerequisites, environment variables like \$AUTOCONF and \$AMTAR
|
||||
are honored.
|
||||
|
||||
Gnulib sources can be fetched in various ways:
|
||||
|
||||
* If the environment variable GNULIB_SRCDIR is set (either as an
|
||||
environment variable or via the --gnulib-srcdir option), then sources
|
||||
are fetched from that local directory. If it is a git repository and
|
||||
the configuration variable GNULIB_REVISION is set in bootstrap.conf,
|
||||
then that revision is checked out.
|
||||
|
||||
* Otherwise, if this package is in a git repository with a 'gnulib'
|
||||
submodule configured, then that submodule is initialized and updated
|
||||
and sources are fetched from there. If GNULIB_REFDIR is set (either
|
||||
as an environment variable or via the --gnulib-refdir option) and is
|
||||
a git repository, then it is used as a reference.
|
||||
|
||||
* Otherwise, if the 'gnulib' directory does not exist, Gnulib sources
|
||||
are cloned into that directory using git from \$GNULIB_URL, defaulting
|
||||
to $default_gnulib_url.
|
||||
If the configuration variable GNULIB_REVISION is set in bootstrap.conf,
|
||||
then that revision is checked out.
|
||||
|
||||
* Otherwise, the existing Gnulib sources in the 'gnulib' directory are
|
||||
used. If it is a git repository and the configuration variable
|
||||
GNULIB_REVISION is set in bootstrap.conf, then that revision is
|
||||
checked out.
|
||||
|
||||
If you maintain a package and want to pin a particular revision of the
|
||||
Gnulib sources that has been tested with your package, then there are
|
||||
two possible approaches: either configure a 'gnulib' submodule with the
|
||||
appropriate revision, or set GNULIB_REVISION (and if necessary
|
||||
GNULIB_URL) in bootstrap.conf.
|
||||
|
||||
Running without arguments will suffice in most cases.
|
||||
EOF
|
||||
}
|
||||
|
||||
# Fetch auxiliary files that are omitted from the version control
|
||||
# repository of this package.
|
||||
autopull()
|
||||
{
|
||||
# Ensure that CDPATH is not set. Otherwise, the output from cd
|
||||
# would cause trouble in at least one use below.
|
||||
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
|
||||
|
||||
# Parse options.
|
||||
|
||||
# Use git to update gnulib sources
|
||||
use_git=true
|
||||
|
||||
for option
|
||||
do
|
||||
case $option in
|
||||
--help)
|
||||
autopull_usage
|
||||
return;;
|
||||
--version)
|
||||
set -e
|
||||
echo "autopull.sh $scriptlibversion"
|
||||
echo "$copyright"
|
||||
return 0
|
||||
;;
|
||||
--skip-po)
|
||||
SKIP_PO=t;;
|
||||
--force)
|
||||
checkout_only_file=;;
|
||||
--bootstrap-sync)
|
||||
bootstrap_sync=true;;
|
||||
--no-bootstrap-sync)
|
||||
bootstrap_sync=false;;
|
||||
--no-git)
|
||||
use_git=false;;
|
||||
*)
|
||||
bootstrap_option_hook $option || die "$option: unknown option";;
|
||||
esac
|
||||
done
|
||||
|
||||
$use_git || test -n "$GNULIB_SRCDIR" \
|
||||
|| die "Error: --no-git requires \$GNULIB_SRCDIR environment variable or --gnulib-srcdir option"
|
||||
test -z "$GNULIB_SRCDIR" || test -d "$GNULIB_SRCDIR" \
|
||||
|| die "Error: \$GNULIB_SRCDIR environment variable or --gnulib-srcdir option is specified, but does not denote a directory"
|
||||
|
||||
if test -n "$checkout_only_file" && test ! -r "$checkout_only_file"; then
|
||||
die "Running this script from a non-checked-out distribution is risky."
|
||||
fi
|
||||
|
||||
check_build_prerequisites $use_git
|
||||
|
||||
if $use_gnulib || $bootstrap_sync; then
|
||||
prepare_GNULIB_SRCDIR
|
||||
if $bootstrap_sync; then
|
||||
upgrade_bootstrap
|
||||
fi
|
||||
fi
|
||||
|
||||
# Find sha1sum, named gsha1sum on MacPorts, shasum on Mac OS X 10.6.
|
||||
# Also find the compatible sha1 utility on the BSDs
|
||||
if test x"$SKIP_PO" = x; then
|
||||
find_tool SHA1SUM sha1sum gsha1sum shasum sha1
|
||||
fi
|
||||
|
||||
# See if we can use gnulib's git-merge-changelog merge driver.
|
||||
if $use_git && test -d .git && check_exists git; then
|
||||
if git config merge.merge-changelog.driver >/dev/null ; then
|
||||
:
|
||||
elif check_exists git-merge-changelog; then
|
||||
echo "$0: initializing git-merge-changelog driver"
|
||||
git config merge.merge-changelog.name 'GNU-style ChangeLog merge driver'
|
||||
git config merge.merge-changelog.driver 'git-merge-changelog %O %A %B'
|
||||
else
|
||||
echo "$0: consider installing git-merge-changelog from gnulib"
|
||||
fi
|
||||
fi
|
||||
|
||||
case $SKIP_PO in
|
||||
'')
|
||||
if test -d po; then
|
||||
update_po_files po $package || return
|
||||
fi
|
||||
|
||||
if test -d runtime-po; then
|
||||
update_po_files runtime-po $package-runtime || return
|
||||
fi;;
|
||||
esac
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
bootstrap_post_pull_hook \
|
||||
|| die "bootstrap_post_pull_hook failed"
|
||||
|
||||
# Don't proceed if there are uninitialized submodules. In particular,
|
||||
# autogen.sh will remove dangling links, which might be links into
|
||||
# uninitialized submodules.
|
||||
# But it's OK if the 'gnulib' submodule is uninitialized, as long as
|
||||
# GNULIB_SRCDIR is set.
|
||||
if $use_git; then
|
||||
# Uninitialized submodules are listed with an initial dash.
|
||||
uninitialized=`git submodule | grep '^-' | awk '{ print $2 }'`
|
||||
if test -n "$GNULIB_SRCDIR"; then
|
||||
uninitialized=`echo "$uninitialized" | grep -v '^gnulib$'`
|
||||
fi
|
||||
if test -n "$uninitialized"; then
|
||||
die "Some git submodules are not initialized: "`echo "$uninitialized" | tr '\n' ',' | sed -e 's|,$|.|'`" Either use option '--no-git', or run 'git submodule update --init' and bootstrap again."
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "$0: done. Now you can run './autogen.sh'."
|
||||
}
|
||||
|
||||
# ----------------------------- Get translations. -----------------------------
|
||||
|
||||
download_po_files() {
|
||||
subdir=$1
|
||||
domain=$2
|
||||
echo "$me: getting translations into $subdir for $domain..."
|
||||
cmd=$(printf "$po_download_command_format" "$subdir" "$domain")
|
||||
eval "$cmd"
|
||||
}
|
||||
|
||||
# Mirror .po files to $po_dir/.reference and copy only the new
|
||||
# or modified ones into $po_dir. Also update $po_dir/LINGUAS.
|
||||
# Note po files that exist locally only are left in $po_dir but will
|
||||
# not be included in LINGUAS and hence will not be distributed.
|
||||
update_po_files() {
|
||||
# Directory containing primary .po files.
|
||||
# Overwrite them only when we're sure a .po file is new.
|
||||
po_dir=$1
|
||||
domain=$2
|
||||
|
||||
# Mirror *.po files into this dir.
|
||||
# Usually contains *.s1 checksum files.
|
||||
ref_po_dir="$po_dir/.reference"
|
||||
|
||||
test -d $ref_po_dir || mkdir $ref_po_dir || return
|
||||
download_po_files $ref_po_dir $domain \
|
||||
&& ls "$ref_po_dir"/*.po 2>/dev/null |
|
||||
sed 's|.*/||; s|\.po$||' > "$po_dir/LINGUAS" || return
|
||||
|
||||
langs=$(cd $ref_po_dir && echo *.po | sed 's/\.po//g')
|
||||
test "$langs" = '*' && langs=x
|
||||
for po in $langs; do
|
||||
case $po in x) continue;; esac
|
||||
new_po="$ref_po_dir/$po.po"
|
||||
cksum_file="$ref_po_dir/$po.s1"
|
||||
if ! test -f "$cksum_file" ||
|
||||
! test -f "$po_dir/$po.po" ||
|
||||
! $SHA1SUM -c "$cksum_file" < "$new_po" > /dev/null 2>&1; then
|
||||
echo "$me: updated $po_dir/$po.po..."
|
||||
cp "$new_po" "$po_dir/$po.po" \
|
||||
&& $SHA1SUM < "$new_po" > "$cksum_file" || return
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# -------- Generate files automatically from existing sources. --------------
|
||||
|
||||
autogen_usage() {
|
||||
cat <<EOF
|
||||
Usage: $me [OPTION]...
|
||||
Bootstrap this package from the checked-out sources.
|
||||
|
||||
Optional environment variables:
|
||||
GNULIB_SRCDIR Specifies the local directory where gnulib
|
||||
sources reside. Use this if you already
|
||||
have gnulib sources on your machine, and
|
||||
you want to use these sources.
|
||||
|
||||
Options:
|
||||
--copy copy files instead of creating symbolic links
|
||||
--force attempt to bootstrap even if the sources seem
|
||||
not to have been checked out
|
||||
EOF
|
||||
bootstrap_print_option_usage_hook
|
||||
cat <<EOF
|
||||
If the file bootstrap.conf exists in the same directory as this script, its
|
||||
contents are read as shell variables to configure the bootstrap.
|
||||
|
||||
For build prerequisites, environment variables like \$AUTOCONF and \$AMTAR
|
||||
are honored.
|
||||
|
||||
Gnulib sources are assumed to be present:
|
||||
* in \$GNULIB_SRCDIR, if that environment variable is set,
|
||||
* otherwise, in the 'gnulib' submodule, if such a submodule is configured,
|
||||
* otherwise, in the 'gnulib' subdirectory.
|
||||
|
||||
Running without arguments will suffice in most cases.
|
||||
EOF
|
||||
}
|
||||
|
||||
|
||||
version_controlled_file() {
|
||||
parent=$1
|
||||
file=$2
|
||||
if test -d .git; then
|
||||
git rm -n "$file" > /dev/null 2>&1
|
||||
elif test -d .svn; then
|
||||
svn log -r HEAD "$file" > /dev/null 2>&1
|
||||
elif test -d CVS; then
|
||||
grep -F "/${file##*/}/" "$parent/CVS/Entries" 2>/dev/null |
|
||||
grep '^/[^/]*/[0-9]' > /dev/null
|
||||
else
|
||||
warn_ "no version control for $file?"
|
||||
false
|
||||
fi
|
||||
}
|
||||
|
||||
# Strip blank and comment lines to leave significant entries.
|
||||
gitignore_entries() {
|
||||
sed '/^#/d; /^$/d' "$@"
|
||||
}
|
||||
|
||||
# If $STR is not already on a line by itself in $FILE, insert it at the start.
|
||||
# Entries are inserted at the start of the ignore list to ensure existing
|
||||
# entries starting with ! are not overridden. Such entries support
|
||||
# whitelisting exceptions after a more generic blacklist pattern.
|
||||
insert_if_absent() {
|
||||
file=$1
|
||||
str=$2
|
||||
test -f $file || touch $file
|
||||
test -r $file || die "Error: failed to read ignore file: $file"
|
||||
duplicate_entries=$(gitignore_entries $file | sort | uniq -d)
|
||||
if [ "$duplicate_entries" ] ; then
|
||||
die "Error: Duplicate entries in $file: " $duplicate_entries
|
||||
fi
|
||||
linesold=$(gitignore_entries $file | wc -l)
|
||||
linesnew=$( { echo "$str"; cat $file; } | gitignore_entries | sort -u | wc -l)
|
||||
if [ $linesold != $linesnew ] ; then
|
||||
{ echo "$str" | cat - $file > $file.bak && mv $file.bak $file; } \
|
||||
|| die "insert_if_absent $file $str: failed"
|
||||
fi
|
||||
}
|
||||
|
||||
# Adjust $PATTERN for $VC_IGNORE_FILE and insert it with
|
||||
# insert_if_absent.
|
||||
insert_vc_ignore() {
|
||||
vc_ignore_file="$1"
|
||||
pattern="$2"
|
||||
case $vc_ignore_file in
|
||||
*.gitignore)
|
||||
# A .gitignore entry that does not start with '/' applies
|
||||
# recursively to subdirectories, so prepend '/' to every
|
||||
# .gitignore entry.
|
||||
pattern=$(echo "$pattern" | sed s,^,/,);;
|
||||
esac
|
||||
insert_if_absent "$vc_ignore_file" "$pattern"
|
||||
}
|
||||
|
||||
symlink_to_dir()
|
||||
{
|
||||
src=$1/$2
|
||||
dst=${3-$2}
|
||||
|
||||
test -f "$src" && {
|
||||
|
||||
# If the destination directory doesn't exist, create it.
|
||||
# This is required at least for "lib/uniwidth/cjk.h".
|
||||
dst_dir=$(dirname "$dst")
|
||||
if ! test -d "$dst_dir"; then
|
||||
mkdir -p "$dst_dir"
|
||||
|
||||
# If we've just created a directory like lib/uniwidth,
|
||||
# tell version control system(s) it's ignorable.
|
||||
# FIXME: for now, this does only one level
|
||||
parent=$(dirname "$dst_dir")
|
||||
for dot_ig in x $vc_ignore; do
|
||||
test $dot_ig = x && continue
|
||||
ig=$parent/$dot_ig
|
||||
insert_vc_ignore $ig "${dst_dir##*/}"
|
||||
done
|
||||
fi
|
||||
|
||||
if $copy; then
|
||||
{
|
||||
test ! -h "$dst" || {
|
||||
echo "$me: rm -f $dst" &&
|
||||
rm -f "$dst"
|
||||
}
|
||||
} &&
|
||||
test -f "$dst" &&
|
||||
cmp -s "$src" "$dst" || {
|
||||
echo "$me: cp -fp $src $dst" &&
|
||||
cp -fp "$src" "$dst"
|
||||
}
|
||||
else
|
||||
# Leave any existing symlink alone, if it already points to the source,
|
||||
# so that broken build tools that care about symlink times
|
||||
# aren't confused into doing unnecessary builds. Conversely, if the
|
||||
# existing symlink's timestamp is older than the source, make it afresh,
|
||||
# so that broken tools aren't confused into skipping needed builds. See
|
||||
# <https://lists.gnu.org/r/bug-gnulib/2011-05/msg00326.html>.
|
||||
test -h "$dst" &&
|
||||
src_ls=$(ls -diL "$src" 2>/dev/null) && set $src_ls && src_i=$1 &&
|
||||
dst_ls=$(ls -diL "$dst" 2>/dev/null) && set $dst_ls && dst_i=$1 &&
|
||||
test "$src_i" = "$dst_i" &&
|
||||
both_ls=$(ls -dt "$src" "$dst") &&
|
||||
test "X$both_ls" = "X$dst$nl$src" || {
|
||||
dot_dots=
|
||||
case $src in
|
||||
/*) ;;
|
||||
*)
|
||||
case /$dst/ in
|
||||
*//* | */../* | */./* | /*/*/*/*/*/)
|
||||
die "invalid symlink calculation: $src -> $dst";;
|
||||
/*/*/*/*/) dot_dots=../../../;;
|
||||
/*/*/*/) dot_dots=../../;;
|
||||
/*/*/) dot_dots=../;;
|
||||
esac;;
|
||||
esac
|
||||
|
||||
echo "$me: ln -fs $dot_dots$src $dst" &&
|
||||
ln -fs "$dot_dots$src" "$dst"
|
||||
}
|
||||
fi
|
||||
}
|
||||
}
|
||||
|
||||
# Regenerate all autogeneratable files that are omitted from the
|
||||
# version control repository. In particular, regenerate all
|
||||
# aclocal.m4, config.h.in, Makefile.in, configure files with new
|
||||
# versions of autoconf or automake.
|
||||
autogen()
|
||||
{
|
||||
# Ensure that CDPATH is not set. Otherwise, the output from cd
|
||||
# would cause trouble in at least one use below.
|
||||
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
|
||||
|
||||
# Environment variables that may be set by the user.
|
||||
: "${AUTOPOINT=autopoint}"
|
||||
: "${AUTORECONF=autoreconf}"
|
||||
|
||||
if test "$vc_ignore" = auto; then
|
||||
vc_ignore=
|
||||
test -d .git && vc_ignore=.gitignore
|
||||
test -d CVS && vc_ignore="$vc_ignore .cvsignore"
|
||||
fi
|
||||
|
||||
|
||||
# Parse options.
|
||||
|
||||
# Whether to use copies instead of symlinks.
|
||||
copy=false
|
||||
|
||||
for option
|
||||
do
|
||||
case $option in
|
||||
--help)
|
||||
autogen_usage
|
||||
return;;
|
||||
--version)
|
||||
set -e
|
||||
echo "autogen.sh $scriptlibversion"
|
||||
echo "$copyright"
|
||||
return 0
|
||||
;;
|
||||
--force)
|
||||
checkout_only_file=;;
|
||||
--copy)
|
||||
copy=true;;
|
||||
*)
|
||||
bootstrap_option_hook $option || die "$option: unknown option";;
|
||||
esac
|
||||
done
|
||||
|
||||
test -z "$GNULIB_SRCDIR" || test -d "$GNULIB_SRCDIR" \
|
||||
|| die "Error: \$GNULIB_SRCDIR environment variable or --gnulib-srcdir option is specified, but does not denote a directory"
|
||||
|
||||
if test -n "$checkout_only_file" && test ! -r "$checkout_only_file"; then
|
||||
die "Running this script from a non-checked-out distribution is risky."
|
||||
fi
|
||||
|
||||
if $use_gnulib; then
|
||||
if test -z "$GNULIB_SRCDIR"; then
|
||||
gnulib_path=$(test -f .gitmodules && git config --file .gitmodules submodule.gnulib.path)
|
||||
test -z "$gnulib_path" && gnulib_path=gnulib
|
||||
GNULIB_SRCDIR=$gnulib_path
|
||||
fi
|
||||
fi
|
||||
|
||||
# Die if there is no AC_CONFIG_AUX_DIR($build_aux) line in configure.ac.
|
||||
found_aux_dir=no
|
||||
grep '^[ ]*AC_CONFIG_AUX_DIR(\['"$build_aux"'])' configure.ac \
|
||||
>/dev/null && found_aux_dir=yes
|
||||
grep '^[ ]*AC_CONFIG_AUX_DIR('"$build_aux"')' configure.ac \
|
||||
>/dev/null && found_aux_dir=yes
|
||||
test $found_aux_dir = yes \
|
||||
|| die "configure.ac lacks 'AC_CONFIG_AUX_DIR([$build_aux])'; add it"
|
||||
|
||||
# If $build_aux doesn't exist, create it now, otherwise some bits
|
||||
# below will malfunction. If creating it, also mark it as ignored.
|
||||
if test ! -d $build_aux; then
|
||||
mkdir $build_aux
|
||||
for dot_ig in x $vc_ignore; do
|
||||
test $dot_ig = x && continue
|
||||
insert_vc_ignore $dot_ig $build_aux
|
||||
done
|
||||
fi
|
||||
|
||||
check_build_prerequisites false
|
||||
|
||||
use_libtool=0
|
||||
# We'd like to use grep -E, to see if any of LT_INIT,
|
||||
# AC_PROG_LIBTOOL, AM_PROG_LIBTOOL is used in configure.ac,
|
||||
# but that's not portable enough (e.g., for Solaris).
|
||||
grep '^[ ]*A[CM]_PROG_LIBTOOL' configure.ac >/dev/null \
|
||||
&& use_libtool=1
|
||||
grep '^[ ]*LT_INIT' configure.ac >/dev/null \
|
||||
&& use_libtool=1
|
||||
if test $use_libtool = 1; then
|
||||
find_tool LIBTOOLIZE glibtoolize libtoolize
|
||||
fi
|
||||
|
||||
if $use_gnulib; then
|
||||
gnulib_tool=$GNULIB_SRCDIR/gnulib-tool
|
||||
<$gnulib_tool || return
|
||||
fi
|
||||
|
||||
# NOTE: we have to be careful to run both autopoint and libtoolize
|
||||
# before gnulib-tool, since gnulib-tool is likely to provide newer
|
||||
# versions of files "installed" by these two programs.
|
||||
# Then, *after* gnulib-tool (see below), we have to be careful to
|
||||
# run autoreconf in such a way that it does not run either of these
|
||||
# two just-pre-run programs.
|
||||
|
||||
# Import from gettext.
|
||||
with_gettext=yes
|
||||
grep '^[ ]*AM_GNU_GETTEXT_VERSION(' configure.ac >/dev/null || \
|
||||
with_gettext=no
|
||||
|
||||
if test $with_gettext = yes || test $use_libtool = 1; then
|
||||
|
||||
tempbase=.bootstrap$$
|
||||
trap "rm -f $tempbase.0 $tempbase.1" HUP INT PIPE TERM
|
||||
|
||||
> $tempbase.0 > $tempbase.1 &&
|
||||
find . ! -type d -print | sort > $tempbase.0 || return
|
||||
|
||||
if test $with_gettext = yes; then
|
||||
# Released autopoint has the tendency to install macros that have been
|
||||
# obsoleted in current gnulib, so run this before gnulib-tool.
|
||||
echo "$0: $AUTOPOINT --force"
|
||||
$AUTOPOINT --force || return
|
||||
fi
|
||||
|
||||
# Autoreconf runs aclocal before libtoolize, which causes spurious
|
||||
# warnings if the initial aclocal is confused by the libtoolized
|
||||
# (or worse out-of-date) macro directory.
|
||||
# libtoolize 1.9b added the --install option; but we support back
|
||||
# to libtoolize 1.5.22, where the install action was default.
|
||||
if test $use_libtool = 1; then
|
||||
install=
|
||||
case $($LIBTOOLIZE --help) in
|
||||
*--install*) install=--install ;;
|
||||
esac
|
||||
echo "running: $LIBTOOLIZE $install --copy"
|
||||
$LIBTOOLIZE $install --copy
|
||||
fi
|
||||
|
||||
find . ! -type d -print | sort >$tempbase.1
|
||||
old_IFS=$IFS
|
||||
IFS=$nl
|
||||
for file in $(comm -13 $tempbase.0 $tempbase.1); do
|
||||
IFS=$old_IFS
|
||||
parent=${file%/*}
|
||||
version_controlled_file "$parent" "$file" || {
|
||||
for dot_ig in x $vc_ignore; do
|
||||
test $dot_ig = x && continue
|
||||
ig=$parent/$dot_ig
|
||||
insert_vc_ignore "$ig" "${file##*/}"
|
||||
done
|
||||
}
|
||||
done
|
||||
IFS=$old_IFS
|
||||
|
||||
rm -f $tempbase.0 $tempbase.1
|
||||
trap - HUP INT PIPE TERM
|
||||
fi
|
||||
|
||||
# Import from gnulib.
|
||||
|
||||
if $use_gnulib; then
|
||||
gnulib_tool_options="\
|
||||
--no-changelog\
|
||||
--aux-dir=$build_aux\
|
||||
--doc-base=$doc_base\
|
||||
--lib=$gnulib_name\
|
||||
--m4-base=$m4_base/\
|
||||
--source-base=$source_base/\
|
||||
--tests-base=$tests_base\
|
||||
--local-dir=$local_gl_dir\
|
||||
$gnulib_tool_option_extras\
|
||||
"
|
||||
if test $use_libtool = 1; then
|
||||
case "$gnulib_tool_options " in
|
||||
*' --libtool '*) ;;
|
||||
*) gnulib_tool_options="$gnulib_tool_options --libtool" ;;
|
||||
esac
|
||||
fi
|
||||
echo "$0: $gnulib_tool $gnulib_tool_options --import ..."
|
||||
$gnulib_tool $gnulib_tool_options --import $gnulib_modules \
|
||||
|| die "gnulib-tool failed"
|
||||
|
||||
for file in $gnulib_files; do
|
||||
symlink_to_dir "$GNULIB_SRCDIR" $file \
|
||||
|| die "failed to symlink $file"
|
||||
done
|
||||
fi
|
||||
|
||||
bootstrap_post_import_hook \
|
||||
|| die "bootstrap_post_import_hook failed"
|
||||
|
||||
# Remove any dangling symlink matching "*.m4" or "*.[ch]" in some
|
||||
# gnulib-populated directories. Such .m4 files would cause aclocal to fail.
|
||||
# The following requires GNU find 4.2.3 or newer. Considering the usual
|
||||
# portability constraints of this script, that may seem a very demanding
|
||||
# requirement, but it should be ok. Ignore any failure, which is fine,
|
||||
# since this is only a convenience to help developers avoid the relatively
|
||||
# unusual case in which a symlinked-to .m4 file is git-removed from gnulib
|
||||
# between successive runs of this script.
|
||||
find "$m4_base" "$source_base" \
|
||||
-depth \( -name '*.m4' -o -name '*.[ch]' \) \
|
||||
-type l -xtype l -delete > /dev/null 2>&1
|
||||
|
||||
# Invoke autoreconf with --force --install to ensure upgrades of tools
|
||||
# such as ylwrap.
|
||||
AUTORECONFFLAGS="--verbose --install --force -I $m4_base $ACLOCAL_FLAGS"
|
||||
|
||||
# Some systems (RHEL 5) are using ancient autotools, for which the
|
||||
# --no-recursive option had not been invented. Detect that lack and
|
||||
# omit the option when it's not supported. FIXME in 2017: remove this
|
||||
# hack when RHEL 5 autotools are updated, or when they become irrelevant.
|
||||
case $($AUTORECONF --help) in
|
||||
*--no-recursive*) AUTORECONFFLAGS="$AUTORECONFFLAGS --no-recursive";;
|
||||
esac
|
||||
|
||||
# Tell autoreconf not to invoke autopoint or libtoolize; they were run above.
|
||||
echo "running: AUTOPOINT=true LIBTOOLIZE=true $AUTORECONF $AUTORECONFFLAGS"
|
||||
AUTOPOINT=true LIBTOOLIZE=true $AUTORECONF $AUTORECONFFLAGS \
|
||||
|| die "autoreconf failed"
|
||||
|
||||
# Get some extra files from gnulib, overriding existing files.
|
||||
for file in $gnulib_extra_files; do
|
||||
case $file in
|
||||
*/INSTALL) dst=INSTALL;;
|
||||
build-aux/*) dst=$build_aux/${file#build-aux/};;
|
||||
*) dst=$file;;
|
||||
esac
|
||||
symlink_to_dir "$GNULIB_SRCDIR" $file $dst \
|
||||
|| die "failed to symlink $file"
|
||||
done
|
||||
|
||||
if test $with_gettext = yes; then
|
||||
# Create gettext configuration.
|
||||
echo "$0: Creating po/Makevars from po/Makevars.template ..."
|
||||
rm -f po/Makevars
|
||||
sed '
|
||||
/^EXTRA_LOCALE_CATEGORIES *=/s/=.*/= '"$EXTRA_LOCALE_CATEGORIES"'/
|
||||
/^COPYRIGHT_HOLDER *=/s/=.*/= '"$COPYRIGHT_HOLDER"'/
|
||||
/^MSGID_BUGS_ADDRESS *=/s|=.*|= '"$MSGID_BUGS_ADDRESS"'|
|
||||
/^XGETTEXT_OPTIONS *=/{
|
||||
s/$/ \\/
|
||||
a\
|
||||
'"$XGETTEXT_OPTIONS"' $${end_of_xgettext_options+}
|
||||
}
|
||||
' po/Makevars.template >po/Makevars \
|
||||
|| die 'cannot generate po/Makevars'
|
||||
|
||||
# If the 'gettext' module is in use, grab the latest Makefile.in.in.
|
||||
# If only the 'gettext-h' module is in use, assume autopoint already
|
||||
# put the correct version of this file into place.
|
||||
case $gnulib_modules in
|
||||
*gettext-h*) ;;
|
||||
*gettext*)
|
||||
cp $GNULIB_SRCDIR/build-aux/po/Makefile.in.in po/Makefile.in.in \
|
||||
|| die "cannot create po/Makefile.in.in"
|
||||
;;
|
||||
esac
|
||||
|
||||
if test -d runtime-po; then
|
||||
# Similarly for runtime-po/Makevars, but not quite the same.
|
||||
rm -f runtime-po/Makevars
|
||||
sed '
|
||||
/^DOMAIN *=.*/s/=.*/= '"$package"'-runtime/
|
||||
/^subdir *=.*/s/=.*/= runtime-po/
|
||||
/^MSGID_BUGS_ADDRESS *=/s/=.*/= bug-'"$package"'@gnu.org/
|
||||
/^XGETTEXT_OPTIONS *=/{
|
||||
s/$/ \\/
|
||||
a\
|
||||
'"$XGETTEXT_OPTIONS_RUNTIME"' $${end_of_xgettext_options+}
|
||||
}
|
||||
' po/Makevars.template >runtime-po/Makevars \
|
||||
|| die 'cannot generate runtime-po/Makevars'
|
||||
|
||||
# Copy identical files from po to runtime-po.
|
||||
(cd po && cp -p Makefile.in.in *-quot *.header *.sed *.sin ../runtime-po)
|
||||
fi
|
||||
fi
|
||||
|
||||
bootstrap_epilogue
|
||||
|
||||
echo "$0: done. Now you can run './configure'."
|
||||
}
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# Local Variables:
|
||||
# eval: (add-hook 'before-save-hook 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-start: "scriptlibversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC0"
|
||||
# time-stamp-end: "; # UTC"
|
||||
|
@ -1,5 +1,5 @@
|
||||
@echo off
|
||||
:: Copyright (C) 2018-2022 Free Software Foundation, Inc.
|
||||
:: Copyright (C) 2018-2024 Free Software Foundation, Inc.
|
||||
:: This file is part of GNU Make.
|
||||
::
|
||||
:: GNU Make is free software; you can redistribute it and/or modify it under
|
||||
@ -13,7 +13,7 @@
|
||||
:: more details.
|
||||
::
|
||||
:: You should have received a copy of the GNU General Public License along
|
||||
:: with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
:: with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
setlocal
|
||||
set "svurl=https://git.savannah.gnu.org/cgit"
|
||||
@ -45,30 +45,62 @@ call :Download lib intprops-internal.h
|
||||
echo -- Configuring the workspace
|
||||
copy /Y gl\lib\*.* lib > nul
|
||||
|
||||
:: In general it's tricky to use special characters as arguments to a program
|
||||
:: in Windows batch files; the quoting rules are obscure and have changed over
|
||||
:: time which means older systems may behave differently. However, Windows
|
||||
:: echo is a dumb program that just writes out its command line without much
|
||||
:: interpreting: all we have to be careful of is ^ quoting. So, use echo
|
||||
:: to create script files to use with sed -f rather than using sed -e.
|
||||
|
||||
:: Create a sed script to convert templates
|
||||
if exist convert.sed del /Q convert.sed
|
||||
echo s,%%PACKAGE%%,make,g > convert.sed
|
||||
echo s,@PACKAGE@,make,g > convert.sed
|
||||
if ERRORLEVEL 1 goto Failed
|
||||
sed -n "s/^AC_INIT(\[GNU.make\],\[\([0-9.]*\)\].*/s,%%VERSION%%,\1,g/p" configure.ac >> convert.sed
|
||||
echo s,@PACKAGE_BUGREPORT@,bug-make@gnu.org,g >> convert.sed
|
||||
if ERRORLEVEL 1 goto Failed
|
||||
sed -z -e s/\\\n//g -e "s/[ \t][ \t]*/ /g" -e "s, [^ ]*\.h,,g" -e "s,src/,$(src),g" -e "s,lib/,$(lib),g" Makefile.am | sed -n "s/^\([A-Za-z0-9]*\)_SRCS *= *\(.*\)/s,%%\1_SOURCES%%,\2,/p" >> convert.sed
|
||||
echo s,@PACKAGE_NAME@,GNU Make,g >> convert.sed
|
||||
if ERRORLEVEL 1 goto Failed
|
||||
echo s,@PACKAGE_TARNAME@,make,g >> convert.sed
|
||||
if ERRORLEVEL 1 goto Failed
|
||||
echo s,@PACKAGE_URL@,https://www.gnu.org/software/make/,g >> convert.sed
|
||||
echo s/^^AC_INIT^(\[GNU.Make\],\[\^([0-9.]*\^)\].*/s,@PACKAGE_VERSION@,\1,g/p > cac.sed
|
||||
sed -n -f cac.sed configure.ac >> convert.sed
|
||||
if ERRORLEVEL 1 goto Failed
|
||||
:: Get the list of sources from Makefile.am
|
||||
echo s,\\\n,,g > mam.sed
|
||||
echo s,[ \t][ \t]*, ,g >> mam.sed
|
||||
echo s, [^^ ]*\.h,,g >> mam.sed
|
||||
echo s,src/,$^(src^),g >> mam.sed
|
||||
echo s,lib/,$^(lib^),g >> mam.sed
|
||||
echo s/^^\^([A-Za-z0-9]*\^)_SRCS *= *\^(.*\^)/s,%%\1_SOURCES%%,\2,/p > mam2.sed
|
||||
sed -z -f mam.sed Makefile.am | sed -n -f mam2.sed >> convert.sed
|
||||
if ERRORLEVEL 1 goto Failed
|
||||
|
||||
echo - Creating Basic.mk
|
||||
call sed -f convert.sed Basic.mk.template > Basic.mk
|
||||
sed -f convert.sed Basic.mk.template > Basic.mk
|
||||
if ERRORLEVEL 1 goto Failed
|
||||
echo - Creating src\config.h.W32
|
||||
call sed -f convert.sed src\config.h.W32.template > src\config.h.W32
|
||||
echo - Creating src\mkconfig.h
|
||||
sed -f convert.sed src\mkconfig.h.in > src\mkconfig.h
|
||||
if ERRORLEVEL 1 goto Failed
|
||||
|
||||
echo - Creating src\gmk-default.h
|
||||
echo static const char *const GUILE_module_defn = ^" \ > src\gmk-default.h
|
||||
call sed -e "s/;.*//" -e "/^[ \t]*$/d" -e "s/\"/\\\\\"/g" -e "s/$/ \\\/" src\gmk-default.scm >> src\gmk-default.h
|
||||
echo s/;.*// > gmk.sed
|
||||
echo /^^[ \t]*$/d >> gmk.sed
|
||||
echo s/"/\\"/g >> gmk.sed
|
||||
echo s/$/ \\/ >> gmk.sed
|
||||
sed -f gmk.sed src\gmk-default.scm >> src\gmk-default.h
|
||||
if ERRORLEVEL 1 goto Failed
|
||||
echo ^";>> src\gmk-default.h
|
||||
|
||||
:: These files would be created by bootstrap; they are not needed on Windows
|
||||
:: but our makefile depends on them
|
||||
echo >> lib\alloca.in.h
|
||||
|
||||
del /Q convert.sed cac.sed mam.sed mam2.sed gmk.sed
|
||||
|
||||
echo.
|
||||
echo Done. Run build_w32.bat to build GNU make.
|
||||
echo Done. Run build_w32.bat to build GNU Make.
|
||||
goto :EOF
|
||||
|
||||
:Download
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Bootstrap configuration. -*-shell-script-*-
|
||||
|
||||
# Copyright (C) 2018-2022 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2018-2024 Free Software Foundation, Inc.
|
||||
|
||||
# GNU Make is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU General Public License as published by the Free
|
||||
@ -19,7 +19,7 @@
|
||||
checkout_only_file=README.git
|
||||
|
||||
# Choose a specific version of gnulib, when checking out
|
||||
GNULIB_REVISION=stable-202207
|
||||
GNULIB_REVISION=stable-202407
|
||||
|
||||
# Always copy files rather than symlink
|
||||
copy=true
|
||||
@ -42,12 +42,12 @@ vc_ignore=
|
||||
|
||||
# Build prerequisites
|
||||
buildreq="\
|
||||
autoconf 2.69
|
||||
automake 1.16.1
|
||||
autoconf 2.72
|
||||
automake 1.16.5
|
||||
"
|
||||
|
||||
gnulib_name=libgnu
|
||||
gnulib_files=doc/make-stds.texi
|
||||
gnulib_files="doc/make-stds.texi m4/sig_atomic_t.m4"
|
||||
|
||||
# Using the full strtoll module pulls in a lot of stuff. But, it's pretty
|
||||
# simple to use just the base source file, so pull that. We'll use it in
|
||||
@ -60,5 +60,6 @@ fdl
|
||||
findprog-in
|
||||
getloadavg
|
||||
host-cpu-c-abi
|
||||
largefile
|
||||
make-glob
|
||||
make-macros"
|
||||
|
@ -1,7 +1,7 @@
|
||||
# Configuration for building GNU Make in the absence of any 'make' program.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1993-2022 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1993-2024 Free Software Foundation, Inc.
|
||||
# This file is part of GNU Make.
|
||||
#
|
||||
# GNU Make is free software; you can redistribute it and/or modify it under
|
||||
@ -15,7 +15,7 @@
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
# this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
# See Makefile.in for comments describing these variables.
|
||||
|
||||
|
59
build.sh
59
build.sh
@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
# Shell script to build GNU Make in the absence of any 'make' program.
|
||||
|
||||
# Copyright (C) 1993-2022 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1993-2024 Free Software Foundation, Inc.
|
||||
# This file is part of GNU Make.
|
||||
#
|
||||
# GNU Make is free software; you can redistribute it and/or modify it under
|
||||
@ -15,11 +15,16 @@
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
# this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
# Get configure-generated values
|
||||
. ./build.cfg
|
||||
|
||||
die () { echo "$*" 1>&2; exit 1; }
|
||||
usage () { echo "$0 [-k]"; exit $1; }
|
||||
|
||||
keep_going=false
|
||||
|
||||
: ${OUTDIR:=.}
|
||||
OUTLIB="$OUTDIR/lib"
|
||||
|
||||
@ -37,24 +42,19 @@ defines="-DLOCALEDIR=\"$localedir\" -DLIBDIR=\"$libdir\" -DINCLUDEDIR=\"$include
|
||||
# Print the value to stdout.
|
||||
get_mk_var ()
|
||||
{
|
||||
file=$1
|
||||
var=$2
|
||||
|
||||
val=
|
||||
v=$(sed -e :a -e '/\\$/N; s/\\\n//; ta' "$file" | sed -n "s=^ *$var *\= *==p")
|
||||
v=$(sed -e :a -e '/\\$/N; s/\\\n//; ta' "$1" | sed -n "s=^ *$2 *\= *==p")
|
||||
for w in $v; do
|
||||
case $w in
|
||||
(\$[\(\{]*[\)\}]) w=${w#\$[\(\{]}; w=$(get_mk_var "$file" "${w%[\)\}]}") ;;
|
||||
(\$[\(\{]*[\)\}]) w=${w#\$[\(\{]}; (get_mk_var "$1" "${w%[\)\}]}") ;;
|
||||
(*) echo "$w" ;;
|
||||
esac
|
||||
val="${val:+$val }$w"
|
||||
done
|
||||
|
||||
printf '%s\n' "$val"
|
||||
}
|
||||
|
||||
# Compile source files. Object files are put into $objs.
|
||||
compile ()
|
||||
{
|
||||
success=true
|
||||
objs=
|
||||
for ofile in "$@"; do
|
||||
# We should try to use a Makefile variable like libgnu_a_SOURCES or
|
||||
@ -65,10 +65,18 @@ compile ()
|
||||
esac
|
||||
echo "compiling $file..."
|
||||
of="$OUTDIR/$ofile"
|
||||
mkdir -p "${of%/*}"
|
||||
$CC $cflags $CPPFLAGS $CFLAGS -c -o "$of" "$top_srcdir/$file"
|
||||
mkdir -p "${of%/*}" || exit 1
|
||||
if $CC $cflags $CPPFLAGS $CFLAGS -c -o "$of" "$top_srcdir/$file"; then
|
||||
: worked
|
||||
else
|
||||
$keep_going || die "Compilation failed."
|
||||
success=false
|
||||
fi
|
||||
|
||||
objs="${objs:+$objs }$of"
|
||||
done
|
||||
|
||||
$success
|
||||
}
|
||||
|
||||
# Use config.status to convert a .in file. Output file is put into $out.
|
||||
@ -130,28 +138,39 @@ done
|
||||
# Get object files from the Makefile
|
||||
OBJS=$(get_mk_var Makefile make_OBJECTS | sed "s=\$[\(\{]OBJEXT[\)\}]=$OBJEXT=g")
|
||||
|
||||
# Exit as soon as any command fails.
|
||||
set -e
|
||||
while test -n "$1"; do
|
||||
case $1 in
|
||||
(-k) keep_going=true; shift ;;
|
||||
(--) shift; break ;;
|
||||
(-[h?]) usage 0 ;;
|
||||
(-*) echo "Unknown option: $1"; usage 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
test -z "$1" || die "Unknown argument: $*"
|
||||
|
||||
# Generate gnulib header files that would normally be created by make
|
||||
set -e
|
||||
for b in $(get_mk_var lib/Makefile BUILT_SOURCES); do
|
||||
convert $b
|
||||
done
|
||||
set +e
|
||||
|
||||
# Build the gnulib library
|
||||
cflags="$DEFS -I$OUTLIB -Ilib -I$top_srcdir/lib -I$OUTDIR/src -Isrc -I$top_srcdir/src"
|
||||
compile $LIBOBJS
|
||||
compile $LIBOBJS || die "Compilation failed."
|
||||
|
||||
echo "creating libgnu.a..."
|
||||
$AR $ARFLAGS "$OUTLIB"/libgnu.a $objs
|
||||
$AR $ARFLAGS "$OUTLIB"/libgnu.a $objs || die "Archive of libgnu failed."
|
||||
|
||||
# Compile the source files into those objects.
|
||||
cflags="$DEFS $defines -I$OUTDIR/src -Isrc -I$top_srcdir/src -I$OUTLIB -Ilib -I$top_srcdir/lib"
|
||||
compile $OBJS
|
||||
compile $OBJS || die "Compilation failed."
|
||||
|
||||
# Link all the objects together.
|
||||
echo "linking make..."
|
||||
$CC $CFLAGS $LDFLAGS -L"$OUTLIB" $objs -lgnu $LOADLIBES -o "$OUTDIR/makenew$EXEEXT"
|
||||
mv -f "$OUTDIR/makenew$EXEEXT" "$OUTDIR/make$EXEEXT"
|
||||
$CC $CFLAGS $LDFLAGS -L"$OUTLIB" -o "$OUTDIR/makenew$EXEEXT" $objs -lgnu $LOADLIBES || die "Link failed."
|
||||
|
||||
mv -f "$OUTDIR/makenew$EXEEXT" "$OUTDIR/make$EXEEXT" || exit 1
|
||||
|
||||
echo done.
|
||||
|
@ -1,5 +1,5 @@
|
||||
@echo off
|
||||
:: Copyright (C) 1996-2022 Free Software Foundation, Inc.
|
||||
:: Copyright (C) 1996-2024 Free Software Foundation, Inc.
|
||||
:: This file is part of GNU Make.
|
||||
::
|
||||
:: GNU Make is free software; you can redistribute it and/or modify it under
|
||||
@ -13,7 +13,7 @@
|
||||
:: more details.
|
||||
::
|
||||
:: You should have received a copy of the GNU General Public License along
|
||||
:: with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
:: with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
setlocal
|
||||
if not "%RECURSEME%"=="%~0" (
|
||||
@ -28,12 +28,13 @@ if "%1" == "-h" goto Usage
|
||||
if "%1" == "--help" goto Usage
|
||||
|
||||
echo.
|
||||
echo Creating GNU Make for Windows 9X/NT/2K/XP/Vista/7/8/10
|
||||
echo Creating GNU Make for Windows 9X/NT/2K/XP/Vista/7/8/10/11
|
||||
echo.
|
||||
|
||||
set MAKE=gnumake
|
||||
set GUILE=Y
|
||||
set COMPILER=cl.exe
|
||||
set RC=rc.exe
|
||||
set O=obj
|
||||
set ARCH=x64
|
||||
set DEBUG=N
|
||||
@ -81,6 +82,7 @@ goto ParseSW
|
||||
|
||||
:SetCC
|
||||
set COMPILER=gcc
|
||||
set RC=windres
|
||||
set O=o
|
||||
echo - Building with GCC
|
||||
shift
|
||||
@ -88,6 +90,7 @@ goto ParseSW
|
||||
|
||||
:SetTCC
|
||||
set COMPILER=tcc
|
||||
set RC=windres
|
||||
set O=o
|
||||
echo - Building with TinyC
|
||||
shift
|
||||
@ -103,7 +106,7 @@ if "%COMPILER%" == "tcc" goto FindTcc
|
||||
call %COMPILER% >nul 2>&1
|
||||
if not ERRORLEVEL 1 goto FoundMSVC
|
||||
|
||||
:: Visual Studio 17 and above provides the "vswhere" tool
|
||||
:: Visual Studio 15 2017 and above provides the "vswhere" tool
|
||||
call :FindVswhere
|
||||
if ERRORLEVEL 1 goto LegacyVS
|
||||
|
||||
@ -183,7 +186,7 @@ if "%MAINT%" == "Y" set "OPTS=%OPTS% /D MAKE_MAINTAINER_MODE"
|
||||
:: Unfortunately this also shows a "usage" note; I can't find anything better.
|
||||
echo.
|
||||
call %COMPILER%
|
||||
goto Build
|
||||
goto FindRC
|
||||
|
||||
:FindGcc
|
||||
set OUTDIR=.\GccRel
|
||||
@ -197,7 +200,7 @@ if "%MAINT%" == "Y" set "OPTS=%OPTS% -DMAKE_MAINTAINER_MODE"
|
||||
:: Show the compiler version that we found
|
||||
echo.
|
||||
call %COMPILER% --version
|
||||
if not ERRORLEVEL 1 goto Build
|
||||
if not ERRORLEVEL 1 goto FindRC
|
||||
echo No %COMPILER% found.
|
||||
exit 1
|
||||
|
||||
@ -212,11 +215,20 @@ if "%MAINT%" == "Y" set "OPTS=%OPTS% -DMAKE_MAINTAINER_MODE"
|
||||
:: Show the compiler version that we found
|
||||
echo.
|
||||
call %COMPILER% -v
|
||||
if not ERRORLEVEL 1 goto Build
|
||||
if not ERRORLEVEL 1 goto FindRC
|
||||
echo No %COMPILER% found.
|
||||
exit 1
|
||||
|
||||
:FindRC
|
||||
set HAVE_RC=Y
|
||||
call where %RC% >nul 2>&1
|
||||
if not ERRORLEVEL 1 goto Build
|
||||
echo.
|
||||
echo %RC% was not found. Building without UTF-8 resource.
|
||||
set HAVE_RC=N
|
||||
|
||||
:Build
|
||||
echo.
|
||||
:: Clean the directory if it exists
|
||||
if exist %OUTDIR%\nul rmdir /S /Q %OUTDIR%
|
||||
|
||||
@ -271,6 +283,7 @@ call :Compile src/strcache
|
||||
call :Compile src/variable
|
||||
call :Compile src/version
|
||||
call :Compile src/vpath
|
||||
call :Compile src/warning
|
||||
call :Compile src/w32/pathstuff
|
||||
call :Compile src/w32/w32os
|
||||
call :Compile src/w32/compat/posixfcn
|
||||
@ -284,6 +297,9 @@ call :Compile lib/getloadavg
|
||||
:: Compile dirent unless it is supported by compiler library (like with gcc).
|
||||
if "%DIRENT%" == "Y" call :Compile src\w32\compat\dirent
|
||||
|
||||
:: Compile UTF-8 resource if a resource compiler is available.
|
||||
if "%HAVE_RC%" == "Y" call :ResourceCompile src/w32/utf8
|
||||
|
||||
call :Link
|
||||
|
||||
echo.
|
||||
@ -313,24 +329,48 @@ if "%COMPILER%" == "tcc" goto TccCompile
|
||||
|
||||
:: MSVC Compile
|
||||
if "%VERBOSE%" == "Y" echo on
|
||||
call %COMPILER% /nologo /MT /W4 /EHsc %OPTS% /I %OUTDIR%/src /I src /I %OUTDIR%/lib /I lib /I src/w32/include /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR%OUTDIR% /Fp%OUTDIR%\%MAKE%.pch /Fo%OUTDIR%\%1.%O% /Fd%OUTDIR%\%MAKE%.pdb %EXTRAS% /c %1.c
|
||||
call %COMPILER% /nologo /MT /W4 /EHsc %OPTS% /I %OUTDIR%/src /I src /I %OUTDIR%/lib /I lib /I src/w32/include /D _CONSOLE /D HAVE_CONFIG_H /FR%OUTDIR% /Fp%OUTDIR%\%MAKE%.pch /Fo%OUTDIR%\%1.%O% /Fd%OUTDIR%\%MAKE%.pdb %EXTRAS% /c %1.c
|
||||
@echo off
|
||||
goto CompileDone
|
||||
|
||||
:GccCompile
|
||||
:: GCC Compile
|
||||
if "%VERBOSE%" == "Y" echo on
|
||||
call %COMPILER% -mthreads -Wall -std=gnu99 -gdwarf-2 -g3 %OPTS% -I%OUTDIR%/src -I./src -I%OUTDIR%/lib -I./lib -I./src/w32/include -DWINDOWS32 -DHAVE_CONFIG_H %EXTRAS% -o %OUTDIR%/%1.%O% -c %1.c
|
||||
call %COMPILER% -mthreads -Wall -std=gnu99 -gdwarf-2 -g3 %OPTS% -I%OUTDIR%/src -I./src -I%OUTDIR%/lib -I./lib -I./src/w32/include -DHAVE_CONFIG_H %EXTRAS% -o %OUTDIR%/%1.%O% -c %1.c
|
||||
@echo off
|
||||
goto CompileDone
|
||||
|
||||
:TccCompile
|
||||
:: TCC Compile
|
||||
if "%VERBOSE%" == "Y" echo on
|
||||
call %COMPILER% -mthreads -Wall -std=c11 %OPTS% -I%OUTDIR%/src -I./src -I%OUTDIR%/lib -I./lib -I./src/w32/include -D_cdecl= -D_MSC_VER -DWINDOWS32 -DHAVE_CONFIG_H %EXTRAS% -o %OUTDIR%/%1.%O% -c %1.c
|
||||
call %COMPILER% -mthreads -Wall -std=c11 %OPTS% -I%OUTDIR%/src -I./src -I%OUTDIR%/lib -I./lib -I./src/w32/include -D_cdecl= -D_MSC_VER -DHAVE_CONFIG_H %EXTRAS% -o %OUTDIR%/%1.%O% -c %1.c
|
||||
@echo off
|
||||
goto CompileDone
|
||||
|
||||
:ResourceCompile
|
||||
if "%VERBOSE%" == "N" echo - Compiling %1.rc
|
||||
echo %LNKOUT%/%1.%O% >>%OUTDIR%\link.sc
|
||||
if exist "%OUTDIR%\%1.%O%" del "%OUTDIR%\%1.%O%"
|
||||
if "%COMPILER%" == "gcc" goto GccResourceCompile
|
||||
if "%COMPILER%" == "tcc" goto TccResourceCompile
|
||||
|
||||
:: MSVC Resource Compile
|
||||
if "%VERBOSE%" == "Y" echo on
|
||||
call %RC% /fo %OUTDIR%\%1.%O% %1.rc
|
||||
@echo off
|
||||
goto CompileDone
|
||||
|
||||
:GccResourceCompile
|
||||
:: GCC Resource Compile
|
||||
if "%VERBOSE%" == "Y" echo on
|
||||
call %RC% -o %OUTDIR%/%1.%O% -i %1.rc
|
||||
@echo off
|
||||
goto CompileDone
|
||||
|
||||
:TccResourceCompile
|
||||
:: TCC Resource Compile
|
||||
goto GccResourceCompile
|
||||
|
||||
:CompileDone
|
||||
if not exist "%OUTDIR%\%1.%O%" exit 1
|
||||
goto :EOF
|
||||
|
22
builddos.bat
22
builddos.bat
@ -1,5 +1,5 @@
|
||||
@echo off
|
||||
rem Copyright (C) 1998-2022 Free Software Foundation, Inc.
|
||||
rem Copyright (C) 1998-2024 Free Software Foundation, Inc.
|
||||
rem This file is part of GNU Make.
|
||||
rem
|
||||
rem GNU Make is free software; you can redistribute it and/or modify it under
|
||||
@ -13,7 +13,7 @@ rem FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for.
|
||||
rem more details.
|
||||
rem
|
||||
rem You should have received a copy of the GNU General Public License along
|
||||
rem with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
rem with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
echo Building Make for MSDOS with DJGPP
|
||||
|
||||
@ -49,14 +49,15 @@ gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/s
|
||||
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/src/dir.c -o dir.o
|
||||
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/src/file.c -o file.o
|
||||
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/src/misc.c -o misc.o
|
||||
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/src/main.c -o main.o
|
||||
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -DINCLUDEDIR=\"c:/djgpp/include\" -O2 -g %XSRC%/src/read.c -o read.o
|
||||
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -DLIBDIR=\"c:/djgpp/lib\" -O2 -g %XSRC%/src/remake.c -o remake.o
|
||||
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -DLOCALEDIR=\"/dev/env/DJDIR/share/locale\" -O2 -g %XSRC%/src/main.c -o main.o
|
||||
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -DINCLUDEDIR=\"/dev/env/DJDIR/include\" -O2 -g %XSRC%/src/read.c -o read.o
|
||||
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -DLIBDIR=\"/dev/env/DJDIR/lib\" -O2 -g %XSRC%/src/remake.c -o remake.o
|
||||
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/src/rule.c -o rule.o
|
||||
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/src/implicit.c -o implicit.o
|
||||
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/src/default.c -o default.o
|
||||
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/src/variable.c -o variable.o
|
||||
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/src/expand.c -o eyxpand.o
|
||||
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/src/warning.c -o warning.o
|
||||
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/src/expand.c -o expand.o
|
||||
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/src/function.c -o function.o
|
||||
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/src/vpath.c -o vpath.o
|
||||
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/src/hash.c -o hash.o
|
||||
@ -69,15 +70,16 @@ gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/s
|
||||
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/src/getopt.c -o getopt.o
|
||||
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/src/getopt1.c -o getopt1.o
|
||||
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/src/shuffle.c -o shuffle.o
|
||||
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/src/load.c -o load.o
|
||||
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/lib/glob.c -o lib/glob.o
|
||||
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/lib/fnmatch.c -o lib/fnmatch.o
|
||||
@echo off
|
||||
echo commands.o > respf.$$$
|
||||
for %%f in (job output dir file misc main read remake rule implicit default variable) do echo %%f.o >> respf.$$$
|
||||
for %%f in (job output dir file misc main read remake rule implicit default variable warning load) do echo %%f.o >> respf.$$$
|
||||
for %%f in (expand function vpath hash strcache version ar arscan signame remote-stub getopt getopt1 shuffle) do echo %%f.o >> respf.$$$
|
||||
for %%f in (lib\glob lib\fnmatch) do echo %%f.o >> respf.$$$
|
||||
rem gcc -c -I./src -I%XSRC% -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/guile.c -o guile.o
|
||||
rem echo guile.o >> respf.$$$
|
||||
gcc -c -I./src -I%XSRC%/src -I./lib -I%XSRC%/lib -DHAVE_CONFIG_H -O2 -g %XSRC%/src/guile.c -o guile.o
|
||||
echo guile.o >> respf.$$$
|
||||
@echo Linking...
|
||||
@echo on
|
||||
gcc -o make.exe @respf.$$$
|
||||
@ -85,7 +87,7 @@ gcc -o make.exe @respf.$$$
|
||||
if not exist make.exe echo Make.exe build failed...
|
||||
if exist make.exe echo make.exe is now built!
|
||||
if exist make.exe del respf.$$$
|
||||
if exist make.exe copy /Y Basic.mk Makefile
|
||||
if exist make.exe copy /Y %XSRC%\Basic.mk Makefile
|
||||
goto End
|
||||
|
||||
:SmallEnv
|
||||
|
105
configure.ac
105
configure.ac
@ -1,6 +1,6 @@
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
#
|
||||
# Copyright (C) 1993-2022 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1993-2024 Free Software Foundation, Inc.
|
||||
# This file is part of GNU Make.
|
||||
#
|
||||
# GNU Make is free software; you can redistribute it and/or modify it under
|
||||
@ -14,9 +14,9 @@
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
# this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
AC_INIT([GNU make],[4.3.90],[bug-make@gnu.org])
|
||||
AC_INIT([GNU Make],[4.4.90],[bug-make@gnu.org])
|
||||
|
||||
AC_PREREQ([2.69])
|
||||
|
||||
@ -31,12 +31,14 @@ AC_CONFIG_LIBOBJ_DIR([lib])
|
||||
# We have to enable "foreign" because ChangeLog is auto-generated
|
||||
# Automake 1.15 and gnulib don't get along: gnulib has some strange error
|
||||
# in the way it handles getloadavg.c which causes make distcheck to fail.
|
||||
# http://lists.gnu.org/archive/html/bug-gnulib/2018-06/msg00024.html
|
||||
# https://lists.gnu.org/archive/html/bug-gnulib/2018-06/msg00024.html
|
||||
AM_INIT_AUTOMAKE([1.16.1 foreign -Werror -Wall])
|
||||
|
||||
# Checks for programs.
|
||||
AC_USE_SYSTEM_EXTENSIONS
|
||||
AC_PROG_CC
|
||||
AC_PROG_CXX
|
||||
AC_DEFINE_UNQUOTED(MAKE_CXX, ["$CXX"], [Default C++ compiler.])
|
||||
|
||||
# Configure gnulib
|
||||
gl_EARLY
|
||||
@ -57,11 +59,6 @@ AC_C_BIGENDIAN
|
||||
AM_GNU_GETTEXT_VERSION([0.19.4])
|
||||
AM_GNU_GETTEXT([external])
|
||||
|
||||
# This test must come as early as possible after the compiler configuration
|
||||
# tests, because the choice of the file model can (in principle) affect
|
||||
# whether functions and headers are available, whether they work, etc.
|
||||
AC_SYS_LARGEFILE
|
||||
|
||||
# Checks for libraries.
|
||||
AC_SEARCH_LIBS([strerror],[cposix])
|
||||
AC_SEARCH_LIBS([getpwnam], [sun])
|
||||
@ -69,9 +66,9 @@ AC_SEARCH_LIBS([getpwnam], [sun])
|
||||
AC_HEADER_DIRENT
|
||||
AC_HEADER_STAT
|
||||
|
||||
AC_CHECK_HEADERS([stdlib.h locale.h unistd.h limits.h fcntl.h string.h \
|
||||
memory.h sys/param.h sys/resource.h sys/timeb.h sys/time.h \
|
||||
sys/select.h sys/file.h spawn.h])
|
||||
AC_CHECK_HEADERS([stdlib.h string.h strings.h locale.h unistd.h limits.h \
|
||||
memory.h sys/param.h sys/resource.h sys/time.h sys/select.h \
|
||||
sys/file.h fcntl.h spawn.h])
|
||||
|
||||
AM_PROG_CC_C_O
|
||||
AC_C_CONST
|
||||
@ -80,8 +77,12 @@ AC_TYPE_PID_T
|
||||
AC_TYPE_OFF_T
|
||||
AC_TYPE_SIZE_T
|
||||
AC_TYPE_SSIZE_T
|
||||
AC_TYPE_INTMAX_T
|
||||
AC_TYPE_UINTMAX_T
|
||||
|
||||
# Check for sig_atomic_t
|
||||
gt_TYPE_SIG_ATOMIC_T
|
||||
|
||||
# Find out whether our struct stat returns nanosecond resolution timestamps.
|
||||
|
||||
AC_STRUCT_ST_MTIM_NSEC
|
||||
@ -176,18 +177,40 @@ AS_IF([test "x$with_guile" != xno],
|
||||
AC_MSG_RESULT([$guile_version])
|
||||
AS_IF([test "$have_guile" = yes],
|
||||
[ PKG_CHECK_MODULES(GUILE, [guile-$guile_version])
|
||||
# Unfortunately Guile requires a C99 compiler but GNU make doesn't, so
|
||||
# verify we can actually compile the header.
|
||||
# Unfortunately pkg doesn't help in multi-arch environments where the
|
||||
# package is installed for some architectures but not others; we need
|
||||
# to try to link.
|
||||
keep_CPPFLAGS="$CPPFLAGS"
|
||||
CPPFLAGS="$CPPFLAGS $pkg_cv_GUILE_CFLAGS"
|
||||
keep_LIBS="$LIBS"
|
||||
CPPFLAGS="$CPPFLAGS $GUILE_CFLAGS"
|
||||
LIBS="$LIBS $GUILE_LIBS"
|
||||
AC_CHECK_HEADER([libguile.h],
|
||||
[AC_DEFINE([HAVE_GUILE], [1], [Embed GNU Guile support])],
|
||||
[have_guile=yes],
|
||||
[have_guile=no],
|
||||
[/* Avoid configuration error warnings. */])
|
||||
AS_IF([test "$have_guile" = yes],
|
||||
[ AC_MSG_CHECKING([whether we can link GNU Guile])
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
|
||||
#include <libguile.h>
|
||||
static void *
|
||||
guile_init (void *arg)
|
||||
{
|
||||
(void) arg;
|
||||
return 0;
|
||||
}
|
||||
]], [[
|
||||
scm_with_guile (guile_init, 0);
|
||||
]])],
|
||||
[have_guile=yes],
|
||||
[have_guile=no])
|
||||
AC_MSG_RESULT([$have_guile])])
|
||||
CPPFLAGS="$keep_CPPFLAGS"
|
||||
LIBS="$keep_LIBS"
|
||||
])
|
||||
])
|
||||
|
||||
AS_IF([test "$have_guile" = yes],
|
||||
[AC_DEFINE([HAVE_GUILE], [1], [Embed GNU Guile support])])
|
||||
AM_CONDITIONAL([HAVE_GUILE], [test "$have_guile" = "yes"])
|
||||
|
||||
AC_CHECK_DECLS([sys_siglist, _sys_siglist, __sys_siglist], , ,
|
||||
@ -299,7 +322,7 @@ AS_CASE([$host_os], [os2*|mingw*], [make_cv_job_server=yes])
|
||||
AS_CASE([/$make_cv_job_server/$user_job_server/],
|
||||
[*/no/*], [: no jobserver],
|
||||
[AC_DEFINE(MAKE_JOBSERVER, 1,
|
||||
[Define to 1 to enable job server support in GNU make.])
|
||||
[Define to 1 to enable job server support in GNU Make.])
|
||||
])
|
||||
|
||||
# If dl*() functions are supported we can enable the load operation
|
||||
@ -322,7 +345,7 @@ AS_IF([test "$make_cv_load" = yes], [
|
||||
AS_CASE([/$make_cv_load/$user_load/],
|
||||
[*/no/*], [make_cv_load=no],
|
||||
[AC_DEFINE(MAKE_LOAD, 1,
|
||||
[Define to 1 to enable 'load' support in GNU make.])
|
||||
[Define to 1 to enable 'load' support in GNU Make.])
|
||||
])
|
||||
|
||||
# If we want load support, we might need to link with export-dynamic.
|
||||
@ -330,14 +353,14 @@ AS_CASE([/$make_cv_load/$user_load/],
|
||||
# For example passing -rdynamic to the SunPRO linker gives a warning
|
||||
# but succeeds and creates a shared object, not an executable!
|
||||
AS_IF([test "$make_cv_load" = yes], [
|
||||
AC_MSG_CHECKING([If the linker accepts -Wl,--export-dynamic])
|
||||
AC_MSG_CHECKING([if the linker accepts -Wl,--export-dynamic])
|
||||
old_LDFLAGS="$LDFLAGS"
|
||||
LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE([int main(){}])],
|
||||
[AC_MSG_RESULT([yes])
|
||||
AC_SUBST([AM_LDFLAGS], [-Wl,--export-dynamic])],
|
||||
[AC_MSG_RESULT([no])
|
||||
AC_MSG_CHECKING([If the linker accepts -rdynamic])
|
||||
AC_MSG_CHECKING([if the linker accepts -rdynamic])
|
||||
LDFLAGS="$old_LDFLAGS -rdynamic"
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE([int main(){}])],
|
||||
[AC_MSG_RESULT([yes])
|
||||
@ -369,20 +392,16 @@ AS_IF([test "$make_cv_posix_spawn" = yes],
|
||||
[make_cv_synchronous_posix_spawn],
|
||||
[make_cv_synchronous_posix_spawn=no
|
||||
AC_RUN_IFELSE([AC_LANG_SOURCE([[
|
||||
#include <errno.h>
|
||||
#include <spawn.h>
|
||||
#include <string.h>
|
||||
|
||||
extern char **environ;
|
||||
|
||||
int main() {
|
||||
char* path = strdup("./non-existent");
|
||||
char *argv[[2]];
|
||||
argv[[0]] = path;
|
||||
argv[[1]] = 0;
|
||||
return posix_spawn(0, path, 0, 0, argv, environ);
|
||||
int main () {
|
||||
char path[[]] = "./xxx-non-existent";
|
||||
char *argv[[]] = {path, 0};
|
||||
return posix_spawn (0, path, 0, 0, argv, environ) == ENOENT ? 0 : 1;
|
||||
}]])],
|
||||
[make_cv_synchronous_posix_spawn=no],
|
||||
[make_cv_synchronous_posix_spawn=yes],
|
||||
[make_cv_synchronous_posix_spawn=no],
|
||||
[make_cv_synchronous_posix_spawn="no (cross-compiling)"])]))
|
||||
|
||||
AS_CASE([/$user_posix_spawn/$make_cv_posix_spawn/$make_cv_synchronous_posix_spawn/],
|
||||
@ -425,13 +444,18 @@ AC_SUBST([MAKE_HOST])
|
||||
|
||||
w32_target_env=no
|
||||
AM_CONDITIONAL([WINDOWSENV], [false])
|
||||
AM_CONDITIONAL([HAVE_WINDRES], [false])
|
||||
|
||||
AS_CASE([$host],
|
||||
[*-*-mingw32],
|
||||
[AM_CONDITIONAL([WINDOWSENV], [true])
|
||||
w32_target_env=yes
|
||||
AC_DEFINE([WINDOWS32], [1], [Use platform specific coding])
|
||||
AC_DEFINE([HAVE_DOS_PATHS], [1], [Use platform specific coding])
|
||||
AC_DEFINE([MK_OS_W32], [1], [Build for the Windows32 API.])
|
||||
AC_DEFINE([HAVE_DOS_PATHS], [1], [Support DOS-style pathnames.])
|
||||
# Windows host tools.
|
||||
# If windres is available, make will use UTF-8.
|
||||
AC_CHECK_TOOL([WINDRES], [windres], [:])
|
||||
AM_CONDITIONAL([HAVE_WINDRES], [test "$WINDRES" != ':'])
|
||||
])
|
||||
|
||||
AC_DEFINE_UNQUOTED([PATH_SEPARATOR_CHAR],['$PATH_SEPARATOR'],
|
||||
@ -440,6 +464,11 @@ AC_DEFINE_UNQUOTED([PATH_SEPARATOR_CHAR],['$PATH_SEPARATOR'],
|
||||
AC_DEFINE_UNQUOTED([HAVE_DECL_GETLOADAVG],[$HAVE_DECL_GETLOADAVG],
|
||||
[Define to 1 if you have the declaration of 'getloadavg'.])
|
||||
|
||||
# Remember that we ran configure to generate config.h
|
||||
|
||||
AC_DEFINE([MK_CONFIGURE], [1],
|
||||
[Define to 1 if config.h is generated by running the configure script.])
|
||||
|
||||
# Include the Maintainer's Makefile section, if it's here.
|
||||
|
||||
MAINT_MAKEFILE=/dev/null
|
||||
@ -451,6 +480,10 @@ AC_SUBST_FILE([MAINT_MAKEFILE])
|
||||
# Allow building with dmalloc
|
||||
AM_WITH_DMALLOC
|
||||
|
||||
# Add custom header to config.h
|
||||
AH_BOTTOM([/* Include customized declarations. */
|
||||
#include "../src/mkcustom.h"])
|
||||
|
||||
# Forcibly disable SET_MAKE. If it's set it breaks things like the test
|
||||
# scripts, etc.
|
||||
SET_MAKE=
|
||||
@ -470,7 +503,7 @@ AS_CASE([$with_customs],
|
||||
[ echo
|
||||
echo "WARNING: '$with_customs/lib' does not appear to contain the"
|
||||
echo " Customs library. You must build and install Customs"
|
||||
echo " before compiling GNU make."
|
||||
echo " before compiling GNU Make."
|
||||
echo
|
||||
])])
|
||||
|
||||
@ -478,7 +511,7 @@ AS_IF([test "x$has_wait_nohang" = xno],
|
||||
[ echo
|
||||
echo "WARNING: Your system has neither waitpid() nor wait3()."
|
||||
echo " Without one of these, signal handling is unreliable."
|
||||
echo " You should be aware that running GNU make with -j"
|
||||
echo " You should be aware that running GNU Make with -j"
|
||||
echo " could result in erratic behavior."
|
||||
echo
|
||||
])
|
||||
@ -514,8 +547,8 @@ AM_CONDITIONAL([KNOWN_PREFIX],
|
||||
-o "x$prefix" = x/usr/gnu -o "x$prefix" = x/usr])
|
||||
|
||||
# Specify what files are to be created.
|
||||
AC_CONFIG_FILES([Makefile build.cfg lib/Makefile po/Makefile.in doc/Makefile \
|
||||
tests/config-flags.pm])
|
||||
AC_CONFIG_FILES([build.cfg tests/config-flags.pm \
|
||||
Makefile lib/Makefile doc/Makefile po/Makefile.in])
|
||||
# We don't need this: the standard automake output suffices for POSIX systems.
|
||||
#mk/Posix.mk
|
||||
|
||||
|
1
doc/.gitignore
vendored
1
doc/.gitignore
vendored
@ -1,4 +1,5 @@
|
||||
manual/
|
||||
make.t2d/
|
||||
make.t2p/
|
||||
gendocs_template
|
||||
fdl.texi
|
||||
|
@ -1,5 +1,5 @@
|
||||
# -*-Makefile-*-, or close enough
|
||||
# Copyright (C) 2000-2022 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2000-2024 Free Software Foundation, Inc.
|
||||
# This file is part of GNU Make.
|
||||
#
|
||||
# GNU Make is free software; you can redistribute it and/or modify it under
|
||||
@ -13,7 +13,7 @@
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
# this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
TEXI2HTML = texi2html
|
||||
TEXI2HTML_FLAGS = -split_chapter
|
||||
|
77
doc/make.1
77
doc/make.1
@ -1,6 +1,6 @@
|
||||
.TH MAKE 1 "31 May 2022" "GNU" "User Commands"
|
||||
.TH MAKE 1 "26 May 2023" "GNU" "User Commands"
|
||||
.SH NAME
|
||||
make \- GNU make utility to maintain groups of programs
|
||||
make \- GNU Make utility to maintain groups of programs
|
||||
.SH SYNOPSIS
|
||||
.B make
|
||||
[\fIOPTION\fR]... [\fITARGET\fR]...
|
||||
@ -76,9 +76,8 @@ listing, right near other important files such as
|
||||
The first name checked,
|
||||
.IR GNUmakefile ,
|
||||
is not recommended for most makefiles. You should use this name if you have a
|
||||
makefile that is specific to GNU
|
||||
.BR make ,
|
||||
and will not be understood by other versions of
|
||||
makefile that is specific to GNU Make, and will not be understood by other
|
||||
versions of
|
||||
.BR make .
|
||||
If
|
||||
.I makefile
|
||||
@ -271,10 +270,15 @@ reading the makefiles; then execute as usual or as otherwise
|
||||
specified.
|
||||
This also prints the version information given by the
|
||||
.B \-v
|
||||
switch (see below).
|
||||
To print the data base without trying to remake any files, use
|
||||
switch (see below). To print the built-in data base only, use
|
||||
.IR "make \-p \-f/dev/null" .
|
||||
.TP 0.5i
|
||||
\fB\-\-print\-targets\fR
|
||||
Print each target defined as a result of reading the makefiles, one target per
|
||||
line, then exit with success. Implicit rule targets are not printed, nor are
|
||||
special targets (target names that consist of "." followed by all upper-case
|
||||
letters). No recipe commands are invoked and no makefiles are rebuilt.
|
||||
.TP 0.5i
|
||||
\fB\-q\fR, \fB\-\-question\fR
|
||||
``Question mode''.
|
||||
Do not run any commands, or print anything; just return an exit status
|
||||
@ -365,12 +369,59 @@ command on the given file before running
|
||||
except that the modification time is changed only in the imagination of
|
||||
.BR make .
|
||||
.TP 0.5i
|
||||
\fB\-\-warn\fR[=\fIARG[\fR,\fIARG\fR]]
|
||||
Control warning reporting for makefiles. This option can appear multiple times.
|
||||
In case of conflicts, later settings override earlier settings.
|
||||
.I ARG
|
||||
can be an action; one of
|
||||
.IR ignore ,
|
||||
.IR warn ,
|
||||
or
|
||||
.I error
|
||||
to set the default action for all warnings, or it can be a specific warning:
|
||||
.I circular-dep
|
||||
(finding a circular dependency),
|
||||
.I invalid-ref
|
||||
(referencing an invalid variable name),
|
||||
.I invalid-var
|
||||
(assigning to an invalid variable name),
|
||||
or
|
||||
.I undefined-var
|
||||
(referencing an undefined variable). The behavior of each warning can be set
|
||||
by adding
|
||||
.BI : action
|
||||
after the warning name. If an action is not specified the default is
|
||||
.IR warn .
|
||||
If no
|
||||
.I ARG
|
||||
is provided the action for all warnings is
|
||||
.IR warn .
|
||||
If no
|
||||
.B \-\-warn
|
||||
option is provided the default action for
|
||||
.I invalid-var
|
||||
and
|
||||
.I invalid-ref
|
||||
is
|
||||
.I warn
|
||||
and the default action for
|
||||
.I undefined-var
|
||||
is
|
||||
.IR ignore .
|
||||
.TP 0.5i
|
||||
.B \-\-warn\-undefined\-variables
|
||||
Warn when an undefined variable is referenced.
|
||||
A deprecated alternative for
|
||||
.BR \-\-warn=undefined-var .
|
||||
.TP 0.5i
|
||||
.B \-
|
||||
This option alone (not as an argument to the
|
||||
.B \-f
|
||||
option) is ignored, unless a target named
|
||||
.B \-
|
||||
is defined in the makefile, in which case that target is added to the makefile
|
||||
goals.
|
||||
.SH "EXIT STATUS"
|
||||
GNU
|
||||
.B make
|
||||
exits with a status of zero if all makefiles were successfully parsed
|
||||
GNU Make exits with a status of zero if all makefiles were successfully parsed
|
||||
and no targets that were built failed. A status of one will be returned
|
||||
if the
|
||||
.B \-q
|
||||
@ -398,9 +449,9 @@ This manual page contributed by Dennis Morse of Stanford University.
|
||||
Further updates contributed by Mike Frysinger. It has been reworked by Roland
|
||||
McGrath. Maintained by Paul Smith.
|
||||
.SH "COPYRIGHT"
|
||||
Copyright \(co 1992-1993, 1996-2022 Free Software Foundation, Inc.
|
||||
Copyright \(co 1992\(en1993, 1996\(en2024 Free Software Foundation, Inc.
|
||||
This file is part of
|
||||
.IR "GNU make" .
|
||||
.IR "GNU Make" .
|
||||
.LP
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
|
3734
doc/make.texi
3734
doc/make.texi
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1991, 1992, 1993, 1996, 1997, 1998, 1999 Free Software
|
||||
/* Copyright (C) 1991, 1992, 1993, 1996, 1997, 1998, 1999, 2023 Free Software
|
||||
Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
@ -13,9 +13,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public License
|
||||
along with this library; see the file COPYING.LIB. If not, write to the Free
|
||||
Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA. */
|
||||
along with this library; see the file COPYING.LIB.
|
||||
If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
@ -128,48 +127,20 @@ extern char *getenv ();
|
||||
extern int errno;
|
||||
# endif
|
||||
|
||||
/* This function doesn't exist on most systems. */
|
||||
|
||||
# if !defined HAVE___STRCHRNUL && !defined _LIBC
|
||||
static char *
|
||||
__strchrnul (s, c)
|
||||
const char *s;
|
||||
int c;
|
||||
{
|
||||
char *result = strchr (s, c);
|
||||
if (result == NULL)
|
||||
result = strchr (s, '\0');
|
||||
return result;
|
||||
}
|
||||
# endif
|
||||
|
||||
# ifndef internal_function
|
||||
/* Inside GNU libc we mark some function in a special way. In other
|
||||
environments simply ignore the marking. */
|
||||
# define internal_function
|
||||
# endif
|
||||
|
||||
/* Match STRING against the filename pattern PATTERN, returning zero if
|
||||
it matches, nonzero if not. */
|
||||
static int internal_fnmatch __P ((const char *pattern, const char *string,
|
||||
int no_leading_period, int flags))
|
||||
internal_function;
|
||||
static int
|
||||
internal_function
|
||||
internal_fnmatch (pattern, string, no_leading_period, flags)
|
||||
const char *pattern;
|
||||
const char *string;
|
||||
int no_leading_period;
|
||||
int flags;
|
||||
internal_fnmatch (const char *pattern, const char *string,
|
||||
int no_leading_period, int flags)
|
||||
{
|
||||
register const char *p = pattern, *n = string;
|
||||
register unsigned char c;
|
||||
const char *p = pattern, *n = string;
|
||||
unsigned char c;
|
||||
|
||||
/* Note that this evaluates C many times. */
|
||||
# ifdef _LIBC
|
||||
# define FOLD(c) ((flags & FNM_CASEFOLD) ? tolower (c) : (c))
|
||||
# define FOLD(c) (unsigned char)((flags & FNM_CASEFOLD) ? tolower (c) : (c))
|
||||
# else
|
||||
# define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c))
|
||||
# define FOLD(c) (unsigned char)((flags & FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c))
|
||||
# endif
|
||||
|
||||
while ((c = *p++) != '\0')
|
||||
@ -237,7 +208,9 @@ internal_fnmatch (pattern, string, no_leading_period, flags)
|
||||
{
|
||||
const char *endp;
|
||||
|
||||
endp = __strchrnul (n, (flags & FNM_FILE_NAME) ? '/' : '\0');
|
||||
endp = strchr (n, (flags & FNM_FILE_NAME) ? '/' : '\0');
|
||||
if (endp == NULL)
|
||||
endp = n + strlen (n);
|
||||
|
||||
if (c == '[')
|
||||
{
|
||||
@ -292,7 +265,7 @@ internal_fnmatch (pattern, string, no_leading_period, flags)
|
||||
{
|
||||
/* Nonzero if the sense of the character class is inverted. */
|
||||
static int posixly_correct;
|
||||
register int not;
|
||||
int not;
|
||||
char cold;
|
||||
|
||||
if (posixly_correct == 0)
|
||||
@ -478,10 +451,7 @@ internal_fnmatch (pattern, string, no_leading_period, flags)
|
||||
|
||||
|
||||
int
|
||||
fnmatch (pattern, string, flags)
|
||||
const char *pattern;
|
||||
const char *string;
|
||||
int flags;
|
||||
fnmatch (const char *pattern, const char *string, int flags)
|
||||
{
|
||||
return internal_fnmatch (pattern, string, flags & FNM_PERIOD, flags);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1991, 1992, 1993, 1996, 1997, 1998, 1999 Free Software
|
||||
/* Copyright (C) 1991, 1992, 1993, 1996, 1997, 1998, 1999, 2023 Free Software
|
||||
Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
@ -13,9 +13,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public License
|
||||
along with this library; see the file COPYING.LIB. If not, write to the Free
|
||||
Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA. */
|
||||
along with this library; see the file COPYING.LIB.
|
||||
If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _FNMATCH_H
|
||||
#define _FNMATCH_H 1
|
||||
@ -24,27 +23,6 @@ USA. */
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined __cplusplus || (defined __STDC__ && __STDC__) || defined WINDOWS32
|
||||
# if !defined __GLIBC__
|
||||
# undef __P
|
||||
# define __P(protos) protos
|
||||
# endif
|
||||
#else /* Not C++ or ANSI C. */
|
||||
# undef __P
|
||||
# define __P(protos) ()
|
||||
/* We can get away without defining `const' here only because in this file
|
||||
it is used only inside the prototype for `fnmatch', which is elided in
|
||||
non-ANSI C where `const' is problematical. */
|
||||
#endif /* C++ or ANSI C. */
|
||||
|
||||
#ifndef const
|
||||
# if (defined __STDC__ && __STDC__) || defined __cplusplus || defined WINDOWS32
|
||||
# define __const const
|
||||
# else
|
||||
# define __const
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* We #undef these before defining them because some losing systems
|
||||
(HP-UX A.08.07 for example) define these in <unistd.h>. */
|
||||
#undef FNM_PATHNAME
|
||||
@ -75,8 +53,7 @@ extern "C" {
|
||||
|
||||
/* Match NAME against the filename pattern PATTERN,
|
||||
returning zero if it matches, FNM_NOMATCH if not. */
|
||||
extern int fnmatch __P ((__const char *__pattern, __const char *__name,
|
||||
int __flags));
|
||||
extern int fnmatch (const char *pattern, const char *name, int flags);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
271
gl/lib/glob.c
271
gl/lib/glob.c
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999 Free
|
||||
Software Foundation, Inc.
|
||||
/* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||
2023 Free Software Foundation, Inc.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
@ -12,9 +12,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public License
|
||||
along with this library; see the file COPYING.LIB. If not, write to the Free
|
||||
Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA. */
|
||||
along with this library; see the file COPYING.LIB.
|
||||
If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* AIX requires this to be the first thing in the file. */
|
||||
#if defined _AIX && !defined __GNUC__
|
||||
@ -38,9 +37,6 @@ USA. */
|
||||
/* #define NDEBUG 1 */
|
||||
#include <assert.h>
|
||||
|
||||
#include <stdio.h> /* Needed on stupid SunOS for assert. */
|
||||
|
||||
|
||||
/* Comment out all this code if we are using the GNU C Library, and are not
|
||||
actually compiling the library itself. This code is part of the GNU C
|
||||
Library, but also included in many other GNU distributions. Compiling
|
||||
@ -50,7 +46,9 @@ USA. */
|
||||
it is simpler to just do this in the source for each such file. */
|
||||
|
||||
#define GLOB_INTERFACE_VERSION 1
|
||||
#if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1
|
||||
#if defined _LIBC
|
||||
# define ELIDE_CODE
|
||||
#elif defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1
|
||||
# include <gnu-versions.h>
|
||||
# if _GNU_GLOB_INTERFACE_VERSION == GLOB_INTERFACE_VERSION
|
||||
# define ELIDE_CODE
|
||||
@ -63,7 +61,7 @@ USA. */
|
||||
# include <stddef.h>
|
||||
#endif
|
||||
|
||||
#if defined HAVE_UNISTD_H || defined _LIBC
|
||||
#if defined HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
# ifndef POSIX
|
||||
# ifdef _POSIX_VERSION
|
||||
@ -72,7 +70,7 @@ USA. */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined _AMIGA && !defined VMS && !defined WINDOWS32
|
||||
#if !defined _AMIGA && !MK_OS_VMS && !MK_OS_W32
|
||||
# include <pwd.h>
|
||||
#endif
|
||||
|
||||
@ -83,11 +81,6 @@ extern int errno;
|
||||
# define __set_errno(val) errno = (val)
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
# define NULL 0
|
||||
#endif
|
||||
|
||||
|
||||
#if defined HAVE_DIRENT_H || defined __GNU_LIBRARY__
|
||||
# include <dirent.h>
|
||||
# define NAMLEN(dirent) strlen((dirent)->d_name)
|
||||
@ -108,7 +101,6 @@ extern int errno;
|
||||
# endif /* HAVE_VMSDIR_H */
|
||||
#endif
|
||||
|
||||
|
||||
/* In GNU systems, <dirent.h> defines this macro for us. */
|
||||
#ifdef _D_NAMLEN
|
||||
# undef NAMLEN
|
||||
@ -122,7 +114,7 @@ extern int errno;
|
||||
#endif
|
||||
|
||||
|
||||
#if (defined POSIX || defined WINDOWS32) && !defined __GNU_LIBRARY__
|
||||
#if (defined POSIX || MK_OS_W32) && !defined __GNU_LIBRARY__
|
||||
/* Posix does not require that the d_ino field be present, and some
|
||||
systems do not provide it. */
|
||||
# define REAL_DIR_ENTRY(dp) 1
|
||||
@ -130,49 +122,10 @@ extern int errno;
|
||||
# define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
|
||||
#endif /* POSIX */
|
||||
|
||||
#if defined STDC_HEADERS || defined __GNU_LIBRARY__
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
# define ANSI_STRING
|
||||
#else /* No standard headers. */
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
extern char *getenv ();
|
||||
|
||||
# ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
# define ANSI_STRING
|
||||
# else
|
||||
# include <strings.h>
|
||||
# endif
|
||||
# ifdef HAVE_MEMORY_H
|
||||
# include <memory.h>
|
||||
# endif
|
||||
|
||||
extern char *malloc (), *realloc ();
|
||||
extern void free ();
|
||||
|
||||
extern void qsort ();
|
||||
extern void abort (), exit ();
|
||||
|
||||
#endif /* Standard headers. */
|
||||
|
||||
#ifndef ANSI_STRING
|
||||
|
||||
# ifndef bzero
|
||||
extern void bzero ();
|
||||
# endif
|
||||
# ifndef bcopy
|
||||
extern void bcopy ();
|
||||
# endif
|
||||
|
||||
# define memcpy(d, s, n) bcopy ((s), (d), (n))
|
||||
# define strrchr rindex
|
||||
/* memset is only used for zero here, but let's be paranoid. */
|
||||
# define memset(s, better_be_zero, n) \
|
||||
((void) ((better_be_zero) == 0 ? (bzero((s), (n)), 0) : (abort(), 0)))
|
||||
#endif /* Not ANSI_STRING. */
|
||||
|
||||
#if !defined HAVE_STRCOLL && !defined _LIBC
|
||||
#if !defined HAVE_STRCOLL
|
||||
# define strcoll strcmp
|
||||
#endif
|
||||
|
||||
@ -182,32 +135,6 @@ extern void bcopy ();
|
||||
# define mempcpy(Dest, Src, Len) __mempcpy (Dest, Src, Len)
|
||||
#endif
|
||||
|
||||
#if !defined __GNU_LIBRARY__ && !defined __DJGPP__
|
||||
# ifdef __GNUC__
|
||||
__inline
|
||||
# endif
|
||||
# ifndef __SASC
|
||||
# ifdef WINDOWS32
|
||||
static void *
|
||||
my_realloc (void *p, unsigned int n)
|
||||
# else
|
||||
static char *
|
||||
my_realloc (p, n)
|
||||
char *p;
|
||||
unsigned int n;
|
||||
# endif
|
||||
{
|
||||
/* These casts are the for sake of the broken Ultrix compiler,
|
||||
which warns of illegal pointer combinations otherwise. */
|
||||
if (p == NULL)
|
||||
return (char *) malloc (n);
|
||||
return (char *) realloc (p, n);
|
||||
}
|
||||
# define realloc my_realloc
|
||||
# endif /* __SASC */
|
||||
#endif /* __GNU_LIBRARY__ || __DJGPP__ */
|
||||
|
||||
|
||||
#if !defined __alloca && !defined __GNU_LIBRARY__
|
||||
|
||||
# ifdef __GNUC__
|
||||
@ -218,18 +145,17 @@ my_realloc (p, n)
|
||||
# include <alloca.h>
|
||||
# else /* Not HAVE_ALLOCA_H. */
|
||||
# ifndef _AIX
|
||||
# ifdef WINDOWS32
|
||||
# if MK_OS_W32
|
||||
# include <malloc.h>
|
||||
# else
|
||||
extern char *alloca ();
|
||||
# endif /* WINDOWS32 */
|
||||
# endif /* MK_OS_W32 */
|
||||
# endif /* Not _AIX. */
|
||||
# endif /* sparc or HAVE_ALLOCA_H. */
|
||||
# endif /* GCC. */
|
||||
#endif
|
||||
|
||||
#ifndef __GNU_LIBRARY__
|
||||
# define __stat stat
|
||||
# ifdef STAT_MACROS_BROKEN
|
||||
# undef S_ISDIR
|
||||
# endif
|
||||
@ -238,25 +164,6 @@ extern char *alloca ();
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef _LIBC
|
||||
# undef strdup
|
||||
# define strdup(str) __strdup (str)
|
||||
# define sysconf(id) __sysconf (id)
|
||||
# define closedir(dir) __closedir (dir)
|
||||
# define opendir(name) __opendir (name)
|
||||
# define readdir(str) __readdir (str)
|
||||
# define getpwnam_r(name, bufp, buf, len, res) \
|
||||
__getpwnam_r (name, bufp, buf, len, res)
|
||||
# ifndef __stat
|
||||
# define __stat(fname, buf) __xstat (_STAT_VER, fname, buf)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !(defined STDC_HEADERS || defined __GNU_LIBRARY__)
|
||||
# undef size_t
|
||||
# define size_t unsigned int
|
||||
#endif
|
||||
|
||||
/* Some system header files erroneously define these.
|
||||
We want our own definitions from <fnmatch.h> to take precedence. */
|
||||
#ifndef __GNU_LIBRARY__
|
||||
@ -284,30 +191,26 @@ extern char *alloca ();
|
||||
# define __alloca alloca
|
||||
#endif
|
||||
|
||||
#if !defined __stat
|
||||
# define __stat stat
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETLOGIN_R
|
||||
extern int getlogin_r __P ((char *, size_t));
|
||||
extern int getlogin_r (char *, size_t);
|
||||
#else
|
||||
extern char *getlogin __P ((void));
|
||||
extern char *getlogin (void);
|
||||
#endif
|
||||
|
||||
static
|
||||
#if __GNUC__ - 0 >= 2
|
||||
inline
|
||||
#endif
|
||||
const char *next_brace_sub __P ((const char *begin));
|
||||
static int glob_in_dir __P ((const char *pattern, const char *directory,
|
||||
int flags,
|
||||
int (*errfunc) (const char *, int),
|
||||
glob_t *pglob));
|
||||
static int prefix_array __P ((const char *prefix, char **array, size_t n));
|
||||
static int collated_compare __P ((const __ptr_t, const __ptr_t));
|
||||
const char *next_brace_sub (const char *begin);
|
||||
static int glob_in_dir (const char *pattern, const char *directory,
|
||||
int flags,
|
||||
int (*errfunc) (const char *, int),
|
||||
glob_t *pglob);
|
||||
static int prefix_array (const char *prefix, char **array, size_t n);
|
||||
static int collated_compare (const void *, const void *);
|
||||
|
||||
#if !defined _LIBC || !defined NO_GLOB_PATTERN_P
|
||||
int __glob_pattern_p __P ((const char *pattern, int quote));
|
||||
#if !defined NO_GLOB_PATTERN_P
|
||||
int __glob_pattern_p (const char *pattern, int quote);
|
||||
#endif
|
||||
|
||||
/* Find the end of the sub-pattern in a brace expression. We define
|
||||
@ -317,8 +220,7 @@ static
|
||||
inline
|
||||
#endif
|
||||
const char *
|
||||
next_brace_sub (begin)
|
||||
const char *begin;
|
||||
next_brace_sub (const char *begin)
|
||||
{
|
||||
unsigned int depth = 0;
|
||||
const char *cp = begin;
|
||||
@ -364,11 +266,8 @@ next_brace_sub (begin)
|
||||
If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned.
|
||||
Otherwise, `glob' returns zero. */
|
||||
int
|
||||
glob (pattern, flags, errfunc, pglob)
|
||||
const char *pattern;
|
||||
int flags;
|
||||
int (*errfunc) __P ((const char *, int));
|
||||
glob_t *pglob;
|
||||
glob (const char *pattern, int flags,
|
||||
int (*errfunc) (const char *, int), glob_t *pglob)
|
||||
{
|
||||
const char *filename;
|
||||
const char *dirname;
|
||||
@ -516,14 +415,14 @@ glob (pattern, flags, errfunc, pglob)
|
||||
|
||||
/* Find the filename. */
|
||||
filename = strrchr (pattern, '/');
|
||||
#if defined __MSDOS__ || defined WINDOWS32
|
||||
#if MK_OS_DOS || MK_OS_W32
|
||||
/* The case of "d:pattern". Since `:' is not allowed in
|
||||
file names, we can safely assume that wherever it
|
||||
happens in pattern, it signals the filename part. This
|
||||
is so we could some day support patterns like "[a-z]:foo". */
|
||||
if (filename == NULL)
|
||||
filename = strchr (pattern, ':');
|
||||
#endif /* __MSDOS__ || WINDOWS32 */
|
||||
#endif /* MK_OS_DOS || MK_OS_W32 */
|
||||
if (filename == NULL)
|
||||
{
|
||||
/* This can mean two things: a simple name or "~name". The later
|
||||
@ -560,7 +459,7 @@ glob (pattern, flags, errfunc, pglob)
|
||||
{
|
||||
char *newp;
|
||||
dirlen = filename - pattern;
|
||||
#if defined __MSDOS__ || defined WINDOWS32
|
||||
#if MK_OS_DOS || MK_OS_W32
|
||||
if (*filename == ':'
|
||||
|| (filename > pattern + 1 && filename[-1] == ':'))
|
||||
{
|
||||
@ -594,7 +493,7 @@ glob (pattern, flags, errfunc, pglob)
|
||||
++filename;
|
||||
|
||||
if (filename[0] == '\0'
|
||||
#if defined __MSDOS__ || defined WINDOWS32
|
||||
#if MK_OS_DOS || MK_OS_W32
|
||||
&& dirname[dirlen - 1] != ':'
|
||||
&& (dirlen < 3 || dirname[dirlen - 2] != ':'
|
||||
|| dirname[dirlen - 1] != '/')
|
||||
@ -618,13 +517,13 @@ glob (pattern, flags, errfunc, pglob)
|
||||
|
||||
oldcount = pglob->gl_pathc;
|
||||
|
||||
#ifndef VMS
|
||||
#if !MK_OS_VMS
|
||||
if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && dirname[0] == '~')
|
||||
{
|
||||
if (dirname[1] == '\0' || dirname[1] == '/')
|
||||
{
|
||||
/* Look up home directory. */
|
||||
#ifdef VMS
|
||||
#if MK_OS_VMS
|
||||
/* This isn't obvious, RTLs of DECC and VAXC know about "HOME" */
|
||||
const char *home_dir = getenv ("SYS$LOGIN");
|
||||
#else
|
||||
@ -634,11 +533,11 @@ glob (pattern, flags, errfunc, pglob)
|
||||
if (home_dir == NULL || home_dir[0] == '\0')
|
||||
home_dir = "SYS:";
|
||||
# else
|
||||
# ifdef WINDOWS32
|
||||
# if MK_OS_W32
|
||||
if (home_dir == NULL || home_dir[0] == '\0')
|
||||
home_dir = "c:/users/default"; /* poor default */
|
||||
# else
|
||||
# ifdef VMS
|
||||
# if MK_OS_VMS
|
||||
/* Again, this isn't obvious, if "HOME" isn't known "SYS$LOGIN" should be set */
|
||||
if (home_dir == NULL || home_dir[0] == '\0')
|
||||
home_dir = "SYS$DISK:[]";
|
||||
@ -647,7 +546,7 @@ glob (pattern, flags, errfunc, pglob)
|
||||
{
|
||||
int success;
|
||||
char *name;
|
||||
# if defined HAVE_GETLOGIN_R || defined _LIBC
|
||||
# if defined HAVE_GETLOGIN_R
|
||||
size_t buflen = sysconf (_SC_LOGIN_NAME_MAX) + 1;
|
||||
|
||||
if (buflen == 0)
|
||||
@ -663,7 +562,7 @@ glob (pattern, flags, errfunc, pglob)
|
||||
if (success)
|
||||
{
|
||||
struct passwd *p;
|
||||
# if defined HAVE_GETPWNAM_R || defined _LIBC
|
||||
# if defined HAVE_GETPWNAM_R
|
||||
size_t pwbuflen = sysconf (_SC_GETPW_R_SIZE_MAX);
|
||||
char *pwtmpbuf;
|
||||
struct passwd pwbuf;
|
||||
@ -701,8 +600,8 @@ glob (pattern, flags, errfunc, pglob)
|
||||
else
|
||||
home_dir = "~"; /* No luck. */
|
||||
}
|
||||
# endif /* VMS */
|
||||
# endif /* WINDOWS32 */
|
||||
# endif /* MK_OS_VMS */
|
||||
# endif /* MK_OS_W32 */
|
||||
# endif
|
||||
/* Now construct the full directory. */
|
||||
if (dirname[1] == '\0')
|
||||
@ -722,7 +621,7 @@ glob (pattern, flags, errfunc, pglob)
|
||||
dirname = newp;
|
||||
}
|
||||
}
|
||||
# if !defined _AMIGA && !defined WINDOWS32 && !defined VMS
|
||||
# if !defined _AMIGA && !MK_OS_W32 && !MK_OS_VMS
|
||||
else
|
||||
{
|
||||
char *end_name = strchr (dirname, '/');
|
||||
@ -748,7 +647,7 @@ glob (pattern, flags, errfunc, pglob)
|
||||
/* Look up specific user's home directory. */
|
||||
{
|
||||
struct passwd *p;
|
||||
# if defined HAVE_GETPWNAM_R || defined _LIBC
|
||||
# if defined HAVE_GETPWNAM_R
|
||||
size_t buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
|
||||
char *pwtmpbuf;
|
||||
struct passwd pwbuf;
|
||||
@ -802,9 +701,9 @@ glob (pattern, flags, errfunc, pglob)
|
||||
home directory. */
|
||||
return GLOB_NOMATCH;
|
||||
}
|
||||
# endif /* Not Amiga && not WINDOWS32 && not VMS. */
|
||||
# endif /* Not Amiga && not MK_OS_W32 && not MK_OS_VMS. */
|
||||
}
|
||||
#endif /* Not VMS. */
|
||||
#endif /* Not MK_OS_VMS. */
|
||||
|
||||
/* Now test whether we looked for "~" or "~NAME". In this case we
|
||||
can give the answer now. */
|
||||
@ -816,7 +715,7 @@ glob (pattern, flags, errfunc, pglob)
|
||||
if ((flags & GLOB_NOCHECK)
|
||||
|| (((flags & GLOB_ALTDIRFUNC)
|
||||
? (*pglob->gl_stat) (dirname, &st)
|
||||
: __stat (dirname, &st)) == 0
|
||||
: stat (dirname, &st)) == 0
|
||||
&& S_ISDIR (st.st_mode)))
|
||||
{
|
||||
pglob->gl_pathv
|
||||
@ -833,7 +732,7 @@ glob (pattern, flags, errfunc, pglob)
|
||||
while (pglob->gl_pathc < pglob->gl_offs)
|
||||
pglob->gl_pathv[pglob->gl_pathc++] = NULL;
|
||||
|
||||
#if defined HAVE_STRDUP || defined _LIBC
|
||||
#if defined HAVE_STRDUP
|
||||
pglob->gl_pathv[pglob->gl_pathc] = strdup (dirname);
|
||||
#else
|
||||
{
|
||||
@ -865,7 +764,7 @@ glob (pattern, flags, errfunc, pglob)
|
||||
have to glob for the directory, and then glob for
|
||||
the pattern in each directory found. */
|
||||
glob_t dirs;
|
||||
register size_t i;
|
||||
size_t i;
|
||||
|
||||
status = glob (dirname,
|
||||
((flags & (GLOB_ERR | GLOB_NOCHECK | GLOB_NOESCAPE))
|
||||
@ -879,7 +778,7 @@ glob (pattern, flags, errfunc, pglob)
|
||||
appending the results to PGLOB. */
|
||||
for (i = 0; i < dirs.gl_pathc; ++i)
|
||||
{
|
||||
int old_pathc;
|
||||
size_t old_pathc;
|
||||
|
||||
#ifdef SHELL
|
||||
{
|
||||
@ -962,7 +861,7 @@ glob (pattern, flags, errfunc, pglob)
|
||||
|
||||
/* First check whether this really is a directory. */
|
||||
if (((flags & GLOB_ALTDIRFUNC)
|
||||
? (*pglob->gl_stat) (dir, &st) : __stat (dir, &st)) != 0
|
||||
? (*pglob->gl_stat) (dir, &st) : stat (dir, &st)) != 0
|
||||
|| !S_ISDIR (st.st_mode))
|
||||
/* No directory, ignore this entry. */
|
||||
continue;
|
||||
@ -1038,7 +937,7 @@ glob (pattern, flags, errfunc, pglob)
|
||||
for (i = oldcount; i < pglob->gl_pathc; ++i)
|
||||
if (((flags & GLOB_ALTDIRFUNC)
|
||||
? (*pglob->gl_stat) (pglob->gl_pathv[i], &st)
|
||||
: __stat (pglob->gl_pathv[i], &st)) == 0
|
||||
: stat (pglob->gl_pathv[i], &st)) == 0
|
||||
&& S_ISDIR (st.st_mode))
|
||||
{
|
||||
size_t len = strlen (pglob->gl_pathv[i]) + 2;
|
||||
@ -1056,12 +955,12 @@ glob (pattern, flags, errfunc, pglob)
|
||||
if (!(flags & GLOB_NOSORT))
|
||||
{
|
||||
/* Sort the vector. */
|
||||
int non_sort = oldcount;
|
||||
size_t non_sort = oldcount;
|
||||
|
||||
if ((flags & GLOB_DOOFFS) && pglob->gl_offs > oldcount)
|
||||
non_sort = pglob->gl_offs;
|
||||
|
||||
qsort ((__ptr_t) &pglob->gl_pathv[non_sort],
|
||||
qsort ((void *) &pglob->gl_pathv[non_sort],
|
||||
pglob->gl_pathc - non_sort,
|
||||
sizeof (char *), collated_compare);
|
||||
}
|
||||
@ -1072,25 +971,22 @@ glob (pattern, flags, errfunc, pglob)
|
||||
|
||||
/* Free storage allocated in PGLOB by a previous `glob' call. */
|
||||
void
|
||||
globfree (pglob)
|
||||
register glob_t *pglob;
|
||||
globfree (glob_t *pglob)
|
||||
{
|
||||
if (pglob->gl_pathv != NULL)
|
||||
{
|
||||
register size_t i;
|
||||
size_t i;
|
||||
for (i = 0; i < pglob->gl_pathc; ++i)
|
||||
if (pglob->gl_pathv[i] != NULL)
|
||||
free ((__ptr_t) pglob->gl_pathv[i]);
|
||||
free ((__ptr_t) pglob->gl_pathv);
|
||||
free (pglob->gl_pathv[i]);
|
||||
free (pglob->gl_pathv);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Do a collated comparison of A and B. */
|
||||
static int
|
||||
collated_compare (a, b)
|
||||
const __ptr_t a;
|
||||
const __ptr_t b;
|
||||
collated_compare (const void *a, const void *b)
|
||||
{
|
||||
const char *const s1 = *(const char *const * const) a;
|
||||
const char *const s2 = *(const char *const * const) b;
|
||||
@ -1110,15 +1006,12 @@ collated_compare (a, b)
|
||||
A slash is inserted between DIRNAME and each elt of ARRAY,
|
||||
unless DIRNAME is just "/". Each old element of ARRAY is freed. */
|
||||
static int
|
||||
prefix_array (dirname, array, n)
|
||||
const char *dirname;
|
||||
char **array;
|
||||
size_t n;
|
||||
prefix_array (const char *dirname, char **array, size_t n)
|
||||
{
|
||||
register size_t i;
|
||||
size_t i;
|
||||
size_t dirlen = strlen (dirname);
|
||||
#if defined __MSDOS__ || defined WINDOWS32
|
||||
int sep_char = '/';
|
||||
#if MK_OS_DOS || MK_OS_W32
|
||||
char sep_char = '/';
|
||||
# define DIRSEP_CHAR sep_char
|
||||
#else
|
||||
# define DIRSEP_CHAR '/'
|
||||
@ -1128,7 +1021,7 @@ prefix_array (dirname, array, n)
|
||||
/* DIRNAME is just "/", so normal prepending would get us "//foo".
|
||||
We want "/foo" instead, so don't prepend any chars from DIRNAME. */
|
||||
dirlen = 0;
|
||||
#if defined __MSDOS__ || defined WINDOWS32
|
||||
#if MK_OS_DOS || MK_OS_W32
|
||||
else if (dirlen > 1)
|
||||
{
|
||||
if (dirname[dirlen - 1] == '/' && dirname[dirlen - 2] == ':')
|
||||
@ -1150,7 +1043,7 @@ prefix_array (dirname, array, n)
|
||||
if (new == NULL)
|
||||
{
|
||||
while (i > 0)
|
||||
free ((__ptr_t) array[--i]);
|
||||
free (array[--i]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1165,7 +1058,7 @@ prefix_array (dirname, array, n)
|
||||
new[dirlen] = DIRSEP_CHAR;
|
||||
memcpy (&new[dirlen + 1], array[i], eltlen);
|
||||
#endif
|
||||
free ((__ptr_t) array[i]);
|
||||
free (array[i]);
|
||||
array[i] = new;
|
||||
}
|
||||
|
||||
@ -1174,15 +1067,13 @@ prefix_array (dirname, array, n)
|
||||
|
||||
|
||||
/* We must not compile this function twice. */
|
||||
#if !defined _LIBC || !defined NO_GLOB_PATTERN_P
|
||||
#if !defined NO_GLOB_PATTERN_P
|
||||
/* Return nonzero if PATTERN contains any metacharacters.
|
||||
Metacharacters can be quoted with backslashes if QUOTE is nonzero. */
|
||||
int
|
||||
__glob_pattern_p (pattern, quote)
|
||||
const char *pattern;
|
||||
int quote;
|
||||
__glob_pattern_p (const char *pattern, int quote)
|
||||
{
|
||||
register const char *p;
|
||||
const char *p;
|
||||
int open = 0;
|
||||
|
||||
for (p = pattern; *p != '\0'; ++p)
|
||||
@ -1209,9 +1100,6 @@ __glob_pattern_p (pattern, quote)
|
||||
|
||||
return 0;
|
||||
}
|
||||
# ifdef _LIBC
|
||||
weak_alias (__glob_pattern_p, glob_pattern_p)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
@ -1220,14 +1108,10 @@ weak_alias (__glob_pattern_p, glob_pattern_p)
|
||||
The GLOB_NOSORT bit in FLAGS is ignored. No sorting is ever done.
|
||||
The GLOB_APPEND flag is assumed to be set (always appends). */
|
||||
static int
|
||||
glob_in_dir (pattern, directory, flags, errfunc, pglob)
|
||||
const char *pattern;
|
||||
const char *directory;
|
||||
int flags;
|
||||
int (*errfunc) __P ((const char *, int));
|
||||
glob_t *pglob;
|
||||
glob_in_dir (const char *pattern, const char *directory, int flags,
|
||||
int (*errfunc) (const char *, int), glob_t *pglob)
|
||||
{
|
||||
__ptr_t stream = NULL;
|
||||
void *stream = NULL;
|
||||
|
||||
struct globlink
|
||||
{
|
||||
@ -1239,7 +1123,7 @@ glob_in_dir (pattern, directory, flags, errfunc, pglob)
|
||||
int meta;
|
||||
int save;
|
||||
|
||||
#ifdef VMS
|
||||
#if MK_OS_VMS
|
||||
if (*directory == 0)
|
||||
directory = "[]";
|
||||
#endif
|
||||
@ -1271,7 +1155,7 @@ glob_in_dir (pattern, directory, flags, errfunc, pglob)
|
||||
# endif
|
||||
if (((flags & GLOB_ALTDIRFUNC)
|
||||
? (*pglob->gl_stat) (fullname, &st)
|
||||
: __stat (fullname, &st)) == 0)
|
||||
: stat (fullname, &st)) == 0)
|
||||
/* We found this file to be existing. Now tell the rest
|
||||
of the function to copy this name into the result. */
|
||||
flags |= GLOB_NOCHECK;
|
||||
@ -1298,7 +1182,7 @@ glob_in_dir (pattern, directory, flags, errfunc, pglob)
|
||||
{
|
||||
stream = ((flags & GLOB_ALTDIRFUNC)
|
||||
? (*pglob->gl_opendir) (directory)
|
||||
: (__ptr_t) opendir (directory));
|
||||
: (void *) opendir (directory));
|
||||
if (stream == NULL)
|
||||
{
|
||||
if (errno != ENOTDIR
|
||||
@ -1350,10 +1234,9 @@ glob_in_dir (pattern, directory, flags, errfunc, pglob)
|
||||
if (new->name == NULL)
|
||||
goto memory_error;
|
||||
#ifdef HAVE_MEMPCPY
|
||||
*((char *) mempcpy ((__ptr_t) new->name, name, len))
|
||||
= '\0';
|
||||
*((char *) mempcpy (new->name, name, len)) = '\0';
|
||||
#else
|
||||
memcpy ((__ptr_t) new->name, name, len);
|
||||
memcpy (new->name, name, len);
|
||||
new->name[len] = '\0';
|
||||
#endif
|
||||
new->next = names;
|
||||
@ -1428,7 +1311,7 @@ glob_in_dir (pattern, directory, flags, errfunc, pglob)
|
||||
while (names != NULL)
|
||||
{
|
||||
if (names->name != NULL)
|
||||
free ((__ptr_t) names->name);
|
||||
free (names->name);
|
||||
names = names->next;
|
||||
}
|
||||
return GLOB_NOSPACE;
|
||||
|
121
gl/lib/glob.in.h
121
gl/lib/glob.in.h
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 1991, 1992, 1995, 1996, 1997, 1998 Free Software Foundation,
|
||||
Inc.
|
||||
/* Copyright (C) 1991, 1992, 1995, 1996, 1997, 1998, 2023 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
@ -12,67 +12,18 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public License
|
||||
along with this library; see the file COPYING.LIB. If not, write to the Free
|
||||
Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA. */
|
||||
along with this library; see the file COPYING.LIB.
|
||||
If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _GLOB_H
|
||||
#define _GLOB_H 1
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#undef __ptr_t
|
||||
#if defined __cplusplus || (defined __STDC__ && __STDC__) || defined WINDOWS32
|
||||
# if !defined __GLIBC__
|
||||
# undef __P
|
||||
# undef __PMT
|
||||
# define __P(protos) protos
|
||||
# define __PMT(protos) protos
|
||||
# if !defined __GNUC__ || __GNUC__ < 2
|
||||
# undef __const
|
||||
# define __const const
|
||||
# endif
|
||||
# endif
|
||||
# define __ptr_t void *
|
||||
#else /* Not C++ or ANSI C. */
|
||||
# undef __P
|
||||
# undef __PMT
|
||||
# define __P(protos) ()
|
||||
# define __PMT(protos) ()
|
||||
# undef __const
|
||||
# define __const
|
||||
# define __ptr_t char *
|
||||
#endif /* C++ or ANSI C. */
|
||||
|
||||
/* We need `size_t' for the following definitions. */
|
||||
#ifndef __size_t
|
||||
# if defined __FreeBSD__
|
||||
# define __size_t size_t
|
||||
# else
|
||||
# if defined __GNUC__ && __GNUC__ >= 2
|
||||
typedef __SIZE_TYPE__ __size_t;
|
||||
# else
|
||||
/* This is a guess. */
|
||||
/*hb
|
||||
* Conflicts with DECCs already defined type __size_t.
|
||||
* Defining an own type with a name beginning with '__' is no good.
|
||||
* Anyway if DECC is used and __SIZE_T is defined then __size_t is
|
||||
* already defined (and I hope it's exactly the one we need here).
|
||||
*/
|
||||
# if !(defined __DECC && defined __SIZE_T)
|
||||
typedef unsigned long int __size_t;
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#else
|
||||
/* The GNU CC stddef.h version defines __size_t as empty. We need a real
|
||||
definition. */
|
||||
# undef __size_t
|
||||
# define __size_t size_t
|
||||
#endif
|
||||
|
||||
/* Bits set in the FLAGS argument to `glob'. */
|
||||
#define GLOB_ERR (1 << 0)/* Return on read errors. */
|
||||
#define GLOB_MARK (1 << 1)/* Append a slash to each name. */
|
||||
@ -115,26 +66,26 @@ typedef unsigned long int __size_t;
|
||||
#endif
|
||||
|
||||
/* Structure describing a globbing run. */
|
||||
#if !defined _AMIGA && !defined VMS /* Buggy compiler. */
|
||||
#if !defined _AMIGA && !MK_OS_VMS /* Buggy compiler. */
|
||||
struct stat;
|
||||
#endif
|
||||
typedef struct
|
||||
{
|
||||
__size_t gl_pathc; /* Count of paths matched by the pattern. */
|
||||
size_t gl_pathc; /* Count of paths matched by the pattern. */
|
||||
char **gl_pathv; /* List of matched pathnames. */
|
||||
__size_t gl_offs; /* Slots to reserve in `gl_pathv'. */
|
||||
size_t gl_offs; /* Slots to reserve in `gl_pathv'. */
|
||||
int gl_flags; /* Set to FLAGS, maybe | GLOB_MAGCHAR. */
|
||||
|
||||
/* If the GLOB_ALTDIRFUNC flag is set, the following functions
|
||||
are used instead of the normal file access functions. */
|
||||
void (*gl_closedir) __PMT ((void *));
|
||||
struct dirent *(*gl_readdir) __PMT ((void *));
|
||||
__ptr_t (*gl_opendir) __PMT ((__const char *));
|
||||
int (*gl_lstat) __PMT ((__const char *, struct stat *));
|
||||
#if defined(VMS) && defined(__DECC) && !defined(_POSIX_C_SOURCE)
|
||||
int (*gl_stat) __PMT ((__const char *, struct stat *, ...));
|
||||
void (*gl_closedir) (void *);
|
||||
struct dirent *(*gl_readdir) (void *);
|
||||
void * (*gl_opendir) (const char *);
|
||||
int (*gl_lstat) (const char *, struct stat *);
|
||||
#if MK_OS_VMS && defined(__DECC) && !defined(_POSIX_C_SOURCE)
|
||||
int (*gl_stat) (const char *, struct stat *, ...);
|
||||
#else
|
||||
int (*gl_stat) __PMT ((__const char *, struct stat *));
|
||||
int (*gl_stat) (const char *, struct stat *);
|
||||
#endif
|
||||
} glob_t;
|
||||
|
||||
@ -142,18 +93,18 @@ typedef struct
|
||||
struct stat64;
|
||||
typedef struct
|
||||
{
|
||||
__size_t gl_pathc;
|
||||
size_t gl_pathc;
|
||||
char **gl_pathv;
|
||||
__size_t gl_offs;
|
||||
size_t gl_offs;
|
||||
int gl_flags;
|
||||
|
||||
/* If the GLOB_ALTDIRFUNC flag is set, the following functions
|
||||
are used instead of the normal file access functions. */
|
||||
void (*gl_closedir) __PMT ((void *));
|
||||
struct dirent64 *(*gl_readdir) __PMT ((void *));
|
||||
__ptr_t (*gl_opendir) __PMT ((__const char *));
|
||||
int (*gl_lstat) __PMT ((__const char *, struct stat64 *));
|
||||
int (*gl_stat) __PMT ((__const char *, struct stat64 *));
|
||||
void (*gl_closedir) (void *);
|
||||
struct dirent64 *(*gl_readdir) (void *);
|
||||
void * (*gl_opendir) (const char *);
|
||||
int (*gl_lstat) (const char *, struct stat64 *);
|
||||
int (*gl_stat) (const char *, struct stat64 *);
|
||||
} glob64_t;
|
||||
#endif
|
||||
|
||||
@ -162,11 +113,11 @@ typedef struct
|
||||
# define globfree globfree64
|
||||
#else
|
||||
# ifdef _LARGEFILE64_SOURCE
|
||||
extern int glob64 __P ((__const char *__pattern, int __flags,
|
||||
int (*__errfunc) (__const char *, int),
|
||||
glob64_t *__pglob));
|
||||
extern int glob64 (const char *pattern, int flags,
|
||||
int (*errfunc) (const char *, int),
|
||||
glob64_t *pglob);
|
||||
|
||||
extern void globfree64 __P ((glob64_t *__pglob));
|
||||
extern void globfree64 (glob64_t *pglob);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@ -179,18 +130,18 @@ extern void globfree64 __P ((glob64_t *__pglob));
|
||||
If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned.
|
||||
Otherwise, `glob' returns zero. */
|
||||
#if _FILE_OFFSET_BITS != 64 || __GNUC__ < 2
|
||||
extern int glob __P ((__const char *__pattern, int __flags,
|
||||
int (*__errfunc) (__const char *, int),
|
||||
glob_t *__pglob));
|
||||
extern int glob (const char *pattern, int flags,
|
||||
int (*errfunc) (const char *, int),
|
||||
glob_t *pglob);
|
||||
|
||||
/* Free storage allocated in PGLOB by a previous `glob' call. */
|
||||
extern void globfree __P ((glob_t *__pglob));
|
||||
extern void globfree (glob_t *pglob);
|
||||
#else
|
||||
extern int glob __P ((__const char *__pattern, int __flags,
|
||||
int (*__errfunc) (__const char *, int),
|
||||
glob_t *__pglob)) __asm__ ("glob64");
|
||||
extern int glob (const char *pattern, int flags,
|
||||
int (*errfunc) (const char *, int),
|
||||
glob_t *pglob) __asm__ ("glob64");
|
||||
|
||||
extern void globfree __P ((glob_t *__pglob)) __asm__ ("globfree64");
|
||||
extern void globfree (glob_t *pglob) __asm__ ("globfree64");
|
||||
#endif
|
||||
|
||||
|
||||
@ -200,7 +151,7 @@ extern void globfree __P ((glob_t *__pglob)) __asm__ ("globfree64");
|
||||
|
||||
This function is not part of the interface specified by POSIX.2
|
||||
but several programs want to use it. */
|
||||
extern int glob_pattern_p __P ((__const char *__pattern, int __quote));
|
||||
extern int glob_pattern_p (const char *pattern, int quote);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -1,7 +1,7 @@
|
||||
dnl acinclude.m4 -- Extra macros needed for GNU make.
|
||||
dnl acinclude.m4 -- Extra macros needed for GNU Make.
|
||||
dnl
|
||||
dnl Automake will incorporate this into its generated aclocal.m4.
|
||||
dnl Copyright (C) 1998-2022 Free Software Foundation, Inc.
|
||||
dnl Copyright (C) 1998-2024 Free Software Foundation, Inc.
|
||||
dnl This file is part of GNU Make.
|
||||
dnl
|
||||
dnl GNU Make is free software; you can redistribute it and/or modify it under
|
||||
@ -15,7 +15,7 @@ dnl FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for.
|
||||
dnl more details.
|
||||
dnl
|
||||
dnl You should have received a copy of the GNU General Public License along
|
||||
dnl with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
dnl with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl Got this from the lynx 2.8 distribution.
|
||||
@ -43,8 +43,8 @@ AC_MSG_RESULT(working...)
|
||||
cf_cv_netlibs=""
|
||||
cf_test_netlibs=yes
|
||||
AC_CHECK_FUNCS(gethostname,,[
|
||||
CF_RECHECK_FUNC(gethostname,nsl,cf_cv_netlibs,[
|
||||
CF_RECHECK_FUNC(gethostname,socket,cf_cv_netlibs)])])
|
||||
CF_RECHECK_FUNC(gethostname,nsl,cf_cv_netlibs,[
|
||||
CF_RECHECK_FUNC(gethostname,socket,cf_cv_netlibs)])])
|
||||
#
|
||||
# FIXME: sequent needs this library (i.e., -lsocket -linet -lnsl), but
|
||||
# I don't know the entrypoints - 97/7/22 TD
|
||||
@ -52,12 +52,12 @@ AC_CHECK_LIB(inet,main,cf_cv_netlibs="-linet $cf_cv_netlibs")
|
||||
#
|
||||
if test "$ac_cv_func_lsocket" != no ; then
|
||||
AC_CHECK_FUNCS(socket,,[
|
||||
CF_RECHECK_FUNC(socket,socket,cf_cv_netlibs,[
|
||||
CF_RECHECK_FUNC(socket,bsd,cf_cv_netlibs)])])
|
||||
CF_RECHECK_FUNC(socket,socket,cf_cv_netlibs,[
|
||||
CF_RECHECK_FUNC(socket,bsd,cf_cv_netlibs)])])
|
||||
fi
|
||||
#
|
||||
AC_CHECK_FUNCS(gethostbyname,,[
|
||||
CF_RECHECK_FUNC(gethostbyname,nsl,cf_cv_netlibs)])
|
||||
CF_RECHECK_FUNC(gethostbyname,nsl,cf_cv_netlibs)])
|
||||
])
|
||||
LIBS="$LIBS $cf_cv_netlibs"
|
||||
test $cf_test_netlibs = no && echo "$cf_cv_netlibs" >&AC_FD_MSG
|
||||
@ -77,14 +77,14 @@ dnl used (autoconf does not distinguish between a null token and one that is
|
||||
dnl set to 'no').
|
||||
AC_DEFUN([CF_RECHECK_FUNC],[
|
||||
AC_CHECK_LIB($2,$1,[
|
||||
CF_UPPER(cf_tr_func,$1)
|
||||
AC_DEFINE_UNQUOTED(HAVE_$cf_tr_func,1,[Define if you have function $1])
|
||||
ac_cv_func_$1=yes
|
||||
$3="-l$2 [$]$3"],[
|
||||
ac_cv_func_$1=unknown
|
||||
unset ac_cv_func_$1 2>/dev/null
|
||||
$4],
|
||||
[[$]$3])
|
||||
CF_UPPER(cf_tr_func,$1)
|
||||
AC_DEFINE_UNQUOTED(HAVE_$cf_tr_func,1,[Define if you have function $1])
|
||||
ac_cv_func_$1=yes
|
||||
$3="-l$2 [$]$3"],[
|
||||
ac_cv_func_$1=unknown
|
||||
unset ac_cv_func_$1 2>/dev/null
|
||||
$4],
|
||||
[[$]$3])
|
||||
])dnl
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl Make an uppercase version of a variable
|
||||
@ -118,7 +118,7 @@ AC_DEFUN([AC_STRUCT_ST_MTIM_NSEC],
|
||||
CPPFLAGS="$ac_save_CPPFLAGS -DST_MTIM_NSEC=$ac_val"
|
||||
AC_TRY_COMPILE([#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
], [struct stat s; s.ST_MTIM_NSEC;],
|
||||
], [struct stat s; s.ST_MTIM_NSEC;],
|
||||
[ac_cv_struct_st_mtim_nsec=$ac_val; break])
|
||||
done
|
||||
CPPFLAGS="$ac_save_CPPFLAGS"
|
||||
@ -126,7 +126,7 @@ AC_DEFUN([AC_STRUCT_ST_MTIM_NSEC],
|
||||
|
||||
if test $ac_cv_struct_st_mtim_nsec != no; then
|
||||
AC_DEFINE_UNQUOTED([ST_MTIM_NSEC], [$ac_cv_struct_st_mtim_nsec],
|
||||
[Define if struct stat contains a nanoseconds field])
|
||||
[Define if struct stat contains a nanoseconds field])
|
||||
fi
|
||||
]
|
||||
)
|
||||
|
@ -1,7 +1,7 @@
|
||||
# Test if the system uses DOS-style pathnames (drive specs and backslashes)
|
||||
# By Paul Smith <psmith@gnu.org>. Based on dos.m4 by Jim Meyering.
|
||||
#
|
||||
# Copyright (C) 1993-2022 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1993-2024 Free Software Foundation, Inc.
|
||||
# This file is part of GNU Make.
|
||||
#
|
||||
# GNU Make is free software; you can redistribute it and/or modify it under
|
||||
@ -15,7 +15,7 @@
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
# this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
AC_DEFUN([pds_AC_DOS_PATHS], [
|
||||
AC_CACHE_CHECK([whether system uses MSDOS-style paths], [ac_cv_dos_paths], [
|
||||
|
@ -1,7 +1,7 @@
|
||||
# Check for getloadavg.
|
||||
|
||||
# Copyright (C) 1992-1996, 1999-2000, 2002-2003, 2006, 2008-2022 Free Software
|
||||
# Foundation, Inc.
|
||||
# Copyright (C) 1992-1996, 1999-2000, 2002-2003, 2006, 2008-2024 Free
|
||||
# Software Foundation, Inc.
|
||||
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@ -160,7 +160,7 @@ AC_CHECK_HEADERS([nlist.h],
|
||||
])dnl
|
||||
])# gl_PREREQ_GETLOADAVG
|
||||
|
||||
# ---- GNU make
|
||||
# ---- GNU Make
|
||||
# These macros are imported from stdlib which we don't want to include
|
||||
# Only the getloadavg content is imported.
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
Description:
|
||||
GNU make version of fnmatch()/glob() functions. This is a holdover from
|
||||
GNU Make version of fnmatch()/glob() functions. This is a holdover from
|
||||
a very old version of the globbing library.
|
||||
|
||||
Files:
|
||||
@ -10,21 +10,59 @@ lib/glob.in.h
|
||||
|
||||
configure.ac:
|
||||
# Check the system to see if it provides GNU glob. If not, use our
|
||||
# local version.
|
||||
AC_CACHE_CHECK([if system libc has GNU glob], [make_cv_sys_gnu_glob],
|
||||
[ AC_EGREP_CPP([gnu glob],[
|
||||
#include <features.h>
|
||||
#include <glob.h>
|
||||
#include <fnmatch.h>
|
||||
|
||||
#if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1
|
||||
# include <gnu-versions.h>
|
||||
# if _GNU_GLOB_INTERFACE_VERSION == 1 || _GNU_GLOB_INTERFACE_VERSION == 2
|
||||
gnu glob
|
||||
# endif
|
||||
#endif],
|
||||
[make_cv_sys_gnu_glob=yes],
|
||||
[make_cv_sys_gnu_glob=no])])
|
||||
# local version. Also avoid versions of glibc which have symlink bug
|
||||
# https://sourceware.org/bugzilla/show_bug.cgi?id=866 (test from gnulib)
|
||||
AC_CACHE_CHECK([if system libc has working GNU glob], [make_cv_sys_gnu_glob],[
|
||||
if ln -s conf-doesntexist conf$$-globtest 2>/dev/null; then
|
||||
make_check_symlink=yes
|
||||
else
|
||||
make_check_symlink=no
|
||||
fi
|
||||
if test $cross_compiling = yes || test $make_check_symlink = no; then
|
||||
# When cross-compiling or without symlink support, check the version
|
||||
AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[[#include <features.h>
|
||||
#include <gnu-versions.h>
|
||||
#include <glob.h>
|
||||
#include <fnmatch.h>
|
||||
]],
|
||||
[[
|
||||
#if _GNU_GLOB_INTERFACE_VERSION == 0
|
||||
GNU glob not available in libc
|
||||
#elif __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 27)
|
||||
GNU glob in libc has dangling symlink bug
|
||||
#endif
|
||||
]])],
|
||||
[make_cv_sys_gnu_glob=yes],
|
||||
[make_cv_sys_gnu_glob=no])
|
||||
else
|
||||
# Check for GNU glob, and that it handles dangling symlinks properly
|
||||
AC_RUN_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[[#include <features.h>
|
||||
#include <gnu-versions.h>
|
||||
#include <glob.h>
|
||||
#include <fnmatch.h>
|
||||
]],
|
||||
[[
|
||||
#if _GNU_GLOB_INTERFACE_VERSION == 0
|
||||
return 1;
|
||||
#else
|
||||
glob_t found;
|
||||
if (glob ("conf*-globtest", 0, 0, &found) == GLOB_NOMATCH)
|
||||
return 1;
|
||||
globfree (&found);
|
||||
#endif
|
||||
]])],
|
||||
[make_cv_sys_gnu_glob=yes],
|
||||
[make_cv_sys_gnu_glob=no],
|
||||
[dnl We don't get here.
|
||||
:
|
||||
])
|
||||
fi
|
||||
test $make_check_symlink = no || rm -f conf$$-globtest
|
||||
])
|
||||
|
||||
# Tell automake about this, so it can build the right .c files.
|
||||
AM_CONDITIONAL([USE_SYSTEM_GLOB], [test "$make_cv_sys_gnu_glob" = yes])
|
||||
|
@ -1,5 +1,5 @@
|
||||
Description:
|
||||
Install m4 macros for GNU make.
|
||||
Install m4 macros for GNU Make.
|
||||
|
||||
Files:
|
||||
m4/acinclude.m4
|
||||
|
131
maintMakefile
131
maintMakefile
@ -1,5 +1,5 @@
|
||||
# Maintainer-only makefile segment. This contains things that are relevant
|
||||
# only if you have the full copy of the GNU make sources from the Git
|
||||
# only if you have the full copy of the GNU Make sources from the Git
|
||||
# tree, not a dist copy.
|
||||
|
||||
# --------------------- #
|
||||
@ -20,7 +20,7 @@ SRCROOTDIR ?= $(HOME)/src
|
||||
# Where to put the CVS checkout of the GNU web repository
|
||||
GNUWEBDIR ?= $(SRCROOTDIR)/gnu-www
|
||||
|
||||
# Where to put the CVS checkout of the GNU make web repository
|
||||
# Where to put the CVS checkout of the GNU Make web repository
|
||||
MAKEWEBDIR ?= $(SRCROOTDIR)/make/make-web
|
||||
|
||||
# Enable Perl warnings for the test suite
|
||||
@ -34,7 +34,10 @@ MAKE_CFLAGS := -C -Wall -Wextra -Werror -Wwrite-strings -Wshadow \
|
||||
-Wtype-limits -Wunused-but-set-parameter -Wlogical-op -Wpointer-arith \
|
||||
-Wignored-qualifiers -Wformat-signedness -Wduplicated-cond
|
||||
|
||||
AM_CFLAGS += $(MAKE_CFLAGS)
|
||||
# Allow extra options without overriding MAKE_CFLAGS
|
||||
EXTRA_CFLAGS :=
|
||||
|
||||
AM_CFLAGS += $(MAKE_CFLAGS) $(EXTRA_CFLAGS)
|
||||
|
||||
# Unfortunately the Guile headers are sometimes broken. Convince GCC
|
||||
# to treat them as system headers so warnings are ignored.
|
||||
@ -43,39 +46,36 @@ GUILE_CFLAGS := $(patsubst -I%,-isystem %,$(GUILE_CFLAGS))
|
||||
MAKE_MAINTAINER_MODE := -DMAKE_MAINTAINER_MODE
|
||||
AM_CPPFLAGS += $(MAKE_MAINTAINER_MODE)
|
||||
|
||||
TEMPLATES = README README.DOS README.W32 README.OS2 \
|
||||
src/config.ami src/configh.dos src/config.h.W32 src/config.h-vms
|
||||
|
||||
all: $(TEMPLATES)
|
||||
|
||||
# Create preprocessor output files--GCC specific!
|
||||
%.i : %.c
|
||||
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) -E -dD -o $@ $<
|
||||
|
||||
# General rule for turning a .template into a regular file.
|
||||
#
|
||||
$(TEMPLATES) : % : %.template Makefile
|
||||
rm -f $@
|
||||
sed -e 's@%VERSION%@$(VERSION)@g' \
|
||||
-e 's@%PACKAGE%@$(PACKAGE)@g' \
|
||||
$< > $@
|
||||
chmod a-w $@
|
||||
# Create the mkconfig.h file for non-POSIX config headers
|
||||
|
||||
all: src/mkconfig.h
|
||||
src/mkconfig.h: src/mkconfig.h.in config.status
|
||||
./config.status --header=$@
|
||||
|
||||
# Build the README
|
||||
|
||||
all: README
|
||||
README : README.in config.status
|
||||
./config.status --file=$@
|
||||
|
||||
# Construct Makefiles by adding on dependencies, etc.
|
||||
#
|
||||
cvt = $(patsubst $1/%,$$($1)%,$(filter %.c,$2))
|
||||
Basic.mk: Basic.mk.template .dep_segment Makefile
|
||||
rm -f $@
|
||||
sed -e 's@%VERSION%@$(VERSION)@g' \
|
||||
-e 's@%make_SOURCES%@$(call cvt,src,$(make_SRCS))@g' \
|
||||
sed -e 's@%make_SOURCES%@$(call cvt,src,$(make_SRCS))@g' \
|
||||
-e 's@%w32_SOURCES%@$(call cvt,src,$(w32_SRCS))@g' \
|
||||
-e 's@%vms_SOURCES%@$(call cvt,src,$(vms_SRCS))@g' \
|
||||
-e 's@%amiga_SOURCES%@$(call cvt,src,$(amiga_SRCS))@g' \
|
||||
-e 's@%loadavg_SOURCES%@$(call cvt,lib,$(loadavg_SRCS))@g' \
|
||||
-e 's@%alloca_SOURCES%@$(call cvt,lib,$(alloca_SRCS))@g' \
|
||||
-e 's@%glob_SOURCES%@$(call cvt,lib,$(glob_SRCS))@g' \
|
||||
$< > $@
|
||||
echo >>$@; echo '# --------------- DEPENDENCIES' >>$@; echo '#' >>$@; \
|
||||
echo >>$@; echo '$$(OBJECTS): $$(SRCDIR)/src/mkconfig.h' >>$@; \
|
||||
sed -e 's@^\([^ ]*\)\.o:@$$(OUTDIR)\1.$$(OBJEXT):@' \
|
||||
-e 's@\([^ ]*\.[ch]\)@$$(SRCDIR)/\1@g' \
|
||||
-e 's@$$(SRCDIR)/src/config.h@$$(OUTDIR)src/config.h@g' \
|
||||
@ -176,7 +176,7 @@ po_sync = translationproject.org::tp/latest/$(PACKAGE)/
|
||||
|
||||
.PHONY: do-po-update po-update
|
||||
do-po-update:
|
||||
tmppo="/tmp/po-$(PACKAGE)-$(VERSION).$$$$" \
|
||||
tmppo="/tmp/po-$(PACKAGE)-$(PACKAGE_VERSION).$$$$" \
|
||||
&& rm -rf "$$tmppo" \
|
||||
&& mkdir "$$tmppo" \
|
||||
&& $(RSYNC) $(po_sync) "$$tmppo" \
|
||||
@ -238,18 +238,28 @@ export TAR_OPTIONS := --mode=u+w,go-w --owner=0 --group=0 --numeric-owner --sort
|
||||
# When I released 4.3 somehow the INSTALL file was missing.
|
||||
# When I tried to build it again, it was there. I have no idea what happened
|
||||
# but add a new check to be sure it doesn't happen again.
|
||||
mk_dist_files = AUTHORS ChangeLog COPYING INSTALL README
|
||||
mk_dist_files = AUTHORS ChangeLog COPYING INSTALL README src/mkconfig.h
|
||||
|
||||
dist: mk-distcheck
|
||||
dist: mk-dist mk-distcheck
|
||||
|
||||
.PHONY: mk-distcheck
|
||||
mk-distcheck: distdir
|
||||
@echo "Checking for extra installed files..."
|
||||
for fn in $(mk_dist_files); do \
|
||||
@for fn in $(mk_dist_files); do \
|
||||
test -f '$(distdir)'/"$$fn" \
|
||||
|| { echo "Missing dist file: $$fn"; exit 1; }; \
|
||||
done; true
|
||||
|
||||
# Make sure that the files in lib/ have been updated from the files in gl/lib/
|
||||
|
||||
GL_LIB_FILES := $(wildcard gl/lib/*)
|
||||
|
||||
mk-dist:
|
||||
@echo "Checking gl/lib files..."
|
||||
@for fn in $(GL_LIB_FILES); do \
|
||||
cmp $$fn $${fn##gl/} \
|
||||
|| { echo "Run ./bootstrap --gen ?"; exit 1; }; \
|
||||
done; true
|
||||
|
||||
# ---------------------------------- #
|
||||
# Alternative configuration checks. #
|
||||
@ -261,10 +271,12 @@ CFGCHECK_BUILDFLAGS =
|
||||
# as well, and that will fail.
|
||||
CFGCHECK_MAKEFLAGS = # CFLAGS='$(AM_CFLAGS)'
|
||||
|
||||
# This test can no longer be run: now that we rely on gnulib we must use C99+
|
||||
# We don't support C90 anymore, strictly, but this test still works (with lots
|
||||
# of warnings) and it helps us avoid egregious incompatibilities.
|
||||
checkcfg.strict-c90: CFGCHECK_CONFIGFLAGS = CFLAGS='-std=c90 -pedantic'
|
||||
checkcfg.strict-c90: CFGCHECK_MAKEFLAGS =
|
||||
|
||||
checkcfg.job-pipe: CFGCHECK_CONFIGFLAGS = CPPFLAGS=-DJOBSERVER_USE_FIFO=0
|
||||
checkcfg.no-jobserver:CFGCHECK_CONFIGFLAGS = --disable-job-server
|
||||
checkcfg.no-load: CFGCHECK_CONFIGFLAGS = --disable-load
|
||||
checkcfg.no-guile: CFGCHECK_CONFIGFLAGS = --without-guile
|
||||
@ -279,6 +291,8 @@ checkcfg.no-sync: CFGCHECK_CONFIGFLAGS = CPPFLAGS=-DNO_OUTPUT_SYNC
|
||||
checkcfg.no-archives: CFGCHECK_CONFIGFLAGS = CPPFLAGS=-DNO_ARCHIVES
|
||||
|
||||
CONFIG_CHECKS := \
|
||||
checkcfg.strict-c90 \
|
||||
checkcfg.job-pipe \
|
||||
checkcfg.no-jobserver \
|
||||
checkcfg.no-load \
|
||||
checkcfg.no-guile \
|
||||
@ -290,14 +304,15 @@ CONFIG_CHECKS := \
|
||||
|
||||
.PHONY: check-alt-config
|
||||
check-alt-config: $(CONFIG_CHECKS)
|
||||
@echo --- $@ SUCCESS
|
||||
|
||||
# Trick GNU make so it doesn't run the submake as a recursive make.
|
||||
# Trick GNU Make so it doesn't run the submake as a recursive make.
|
||||
NR_MAKE = $(MAKE)
|
||||
|
||||
# Check builds both with build.sh and with make
|
||||
build.sh_SCRIPT = exec >>'checkcfg.$*.log' 2>&1; set -x; \
|
||||
cd $(distdir)/_build \
|
||||
&& OUTDIR=_bld ../build.sh $(CFGCHECK_BUILD_FLAGS) \
|
||||
&& OUTDIR=_bld ../build.sh -k $(CFGCHECK_BUILD_FLAGS) \
|
||||
&& _bld/make GMK_OUTDIR=../_bld $(AM_MAKEFLAGS) check-local \
|
||||
&& _bld/make GMK_OUTDIR=../_bld $(AM_MAKEFLAGS) clean
|
||||
|
||||
@ -342,7 +357,7 @@ checkcfg.basicmk: checkcfg.% : distdir
|
||||
&& cd $(distdir) \
|
||||
&& ./configure \
|
||||
$(AM_DISTCHECK_CONFIGURE_FLAGS) $(DISTCHECK_CONFIGURE_FLAGS) \
|
||||
&& $(NR_MAKE) $(AM_MAKEFLAGS) -f Basic.mk $(CFGCHECK_MAKEFLAGS)' \
|
||||
&& $(NR_MAKE) $(AM_MAKEFLAGS) -f Basic.mk '$(CFGCHECK_MAKEFLAGS)' \
|
||||
&& ./make $(AM_MAKEFLAGS) -f Basic.mk check \
|
||||
&& ./make $(AM_MAKEFLAGS) -f Basic.mk clean
|
||||
|
||||
@ -363,10 +378,10 @@ local-check: po-check changelog-check
|
||||
# copyright-check writable-files
|
||||
|
||||
changelog-check:
|
||||
if head $(top_srcdir)/ChangeLog | grep 'Version $(VERSION)' >/dev/null; then \
|
||||
if head $(top_srcdir)/ChangeLog | grep 'Version $(PACKAGE_VERSION)' >/dev/null; then \
|
||||
:; \
|
||||
else \
|
||||
echo "$(VERSION) not in ChangeLog" 1>&2; \
|
||||
echo "$(PACKAGE_VERSION) not in ChangeLog" 1>&2; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
@ -393,7 +408,7 @@ makeweb-repo = $(USER)@cvs.sv.gnu.org:/web/make
|
||||
gnuweb-repo = :pserver:anonymous@cvs.sv.gnu.org:/web/www
|
||||
gnuweb-dir = www/server/standards
|
||||
|
||||
# Get the GNU make web page boilerplate etc.
|
||||
# Get the GNU Make web page boilerplate etc.
|
||||
update-makeweb:
|
||||
test -d '$(MAKEWEBDIR)' || mkdir -p '$(MAKEWEBDIR)'
|
||||
test -d '$(MAKEWEBDIR)'/CVS \
|
||||
@ -413,7 +428,7 @@ gendocs: update-gnuweb update-makeweb
|
||||
cd doc \
|
||||
&& rm -rf doc/manual \
|
||||
&& $(GNULIBDIR)/build-aux/gendocs.sh --email '$(BUGLIST)' \
|
||||
make 'GNU Make Manual'
|
||||
make '$(PACKAGE_NAME) Manual'
|
||||
find '$(MAKEWEBDIR)'/manual \( -name CVS -prune \) -o \( -name '[!.]*' -type f -exec rm -f '{}' \; \)
|
||||
cp -r doc/manual '$(MAKEWEBDIR)'
|
||||
@echo 'Status of $(MAKEWEBDIR) repo:' && cd '$(MAKEWEBDIR)' \
|
||||
@ -421,7 +436,7 @@ gendocs: update-gnuweb update-makeweb
|
||||
@echo '- cvs add <new files>' \
|
||||
&& echo '- cvs remove <deleted files>' \
|
||||
&& echo '- cvs commit' \
|
||||
&& echo '- cvs tag make-$(subst .,-,$(VERSION))'
|
||||
&& echo '- cvs tag make-$(subst .,-,$(PACKAGE_VERSION))'
|
||||
|
||||
|
||||
## --------------------------------------------- ##
|
||||
@ -459,15 +474,15 @@ $(COV_BUILD_FILE)-submitted: $(COV_BUILD_FILE)
|
||||
@test -n "$(COVERITY_TOKEN)" || { echo 'COVERITY_TOKEN not set'; exit 1; }
|
||||
@test -n "$(COVERITY_EMAIL)" || { echo 'COVERITY_EMAIL not set'; exit 1; }
|
||||
rm -f '$@'
|
||||
case '$(VERSION)' in \
|
||||
case '$(PACKAGE_VERSION)' in \
|
||||
(*.*.9*) type="daily build"; ext=".$$(date +%Y%m%d)" ;; \
|
||||
(*) type="release"; ext= ;; \
|
||||
esac; \
|
||||
curl --form token='$(COVERITY_TOKEN)' \
|
||||
--form email='$(COVERITY_EMAIL)' \
|
||||
--form file='@$<' \
|
||||
--form version="$(VERSION)$$ext" \
|
||||
--form description="GNU make $$type" \
|
||||
--form version="$(PACKAGE_VERSION)$$ext" \
|
||||
--form description="$(PACKAGE_NAME) $$type" \
|
||||
'https://scan.coverity.com/builds?project=gmake'
|
||||
cp '$<' '$@'
|
||||
|
||||
@ -478,11 +493,11 @@ $(COV_BUILD_FILE)-submitted: $(COV_BUILD_FILE)
|
||||
|
||||
.PHONY: tag-release
|
||||
tag-release:
|
||||
case '$(VERSION)' in \
|
||||
case '$(PACKAGE_VERSION)' in \
|
||||
(*.*.9*) message=" candidate" ;; \
|
||||
(*) message= ;; \
|
||||
esac; \
|
||||
$(GIT) tag -m "GNU Make release$$message $(VERSION)" -u '$(GPG_KEYID)' '$(VERSION)'
|
||||
$(GIT) tag -m "$(PACKAGE_NAME) release$$message $(PACKAGE_VERSION)" -u '$(GPG_KEYID)' '$(PACKAGE_VERSION)'
|
||||
|
||||
|
||||
## ------------------------- ##
|
||||
@ -493,48 +508,18 @@ tag-release:
|
||||
# Sign it with my key. If you don't have my key/passphrase then sorry,
|
||||
# you're SOL! :)
|
||||
|
||||
GPG = gpg
|
||||
GPGFLAGS = -u $(GPG_KEYID)
|
||||
|
||||
DIST_ARCHIVES_SIG = $(addsuffix .sig,$(DIST_ARCHIVES))
|
||||
DIST_ARCHIVES_DIRECTIVE = $(addsuffix .directive.asc,$(DIST_ARCHIVES))
|
||||
|
||||
# A simple rule to test signing, etc.
|
||||
.PHONY: distsign
|
||||
distsign: $(DIST_ARCHIVES_SIG) $(DIST_ARCHIVES_DIRECTIVE)
|
||||
|
||||
%.sig : %
|
||||
@echo "Signing file '$<':"
|
||||
$(GPG) $(GPGFLAGS) -o "$@" -b "$<"
|
||||
|
||||
%.directive.asc: %
|
||||
@echo "Creating signed directive file '$@':"
|
||||
@( \
|
||||
echo 'version: 1.2'; \
|
||||
echo 'directory: make'; \
|
||||
echo 'filename: $*'; \
|
||||
echo 'comment: Official upload of GNU make version $(VERSION)'; \
|
||||
) > "$*.directive"
|
||||
$(GPG) $(GPGFLAGS) -o "$@" --clearsign "$*.directive"
|
||||
@rm -f "$*.directive"
|
||||
|
||||
# Upload the artifacts
|
||||
|
||||
FTPPUT = ncftpput
|
||||
gnu-upload-host = ftp-upload.gnu.org
|
||||
gnu-upload-dir = /incoming
|
||||
|
||||
GNUPLOAD := $(GNULIBDIR)/build-aux/gnupload
|
||||
|
||||
UPLOADS = upload-alpha upload-ftp
|
||||
.PHONY: $(UPLOADS)
|
||||
$(UPLOADS): $(DIST_ARCHIVES) $(DIST_ARCHIVES_SIG) $(DIST_ARCHIVES_DIRECTIVE)
|
||||
$(FTPPUT) "$(gnu-upload-host)" "$(gnu-upload-dir)/$(@:upload-%=%)" $^
|
||||
$(UPLOADS): upload-%: $(DIST_ARCHIVES)
|
||||
$(GNUPLOAD) --user "$(GPG_KEYID)" --to "$*.gnu.org:make" -- $^
|
||||
|
||||
|
||||
# Rebuild Makefile.in if this file is modifed.
|
||||
# Rebuild Makefile.in if this file is modified.
|
||||
Makefile.in: maintMakefile
|
||||
|
||||
# Copyright (C) 1997-2022 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1997-2024 Free Software Foundation, Inc.
|
||||
# This file is part of GNU Make.
|
||||
#
|
||||
# GNU Make is free software; you can redistribute it and/or modify it under
|
||||
@ -548,4 +533,4 @@ Makefile.in: maintMakefile
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
# this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
@ -1,4 +1,4 @@
|
||||
"""GDB pretty-printer macros for GNU make."""
|
||||
"""GDB pretty-printer macros for GNU Make."""
|
||||
|
||||
import gdb # pylint: disable=import-error
|
||||
import gdb.printing # pylint: disable=import-error
|
||||
|
@ -154,7 +154,7 @@ $ exit
|
||||
$ endsubroutine : compileit
|
||||
$!
|
||||
$!-----------------------------------------------------------------------------
|
||||
$!Copyright (C) 1996-2022 Free Software Foundation, Inc.
|
||||
$!Copyright (C) 1996-2024 Free Software Foundation, Inc.
|
||||
$!This file is part of GNU Make.
|
||||
$!
|
||||
$!GNU Make is free software; you can redistribute it and/or modify it under
|
||||
@ -168,4 +168,4 @@ $!FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
$!details.
|
||||
$!
|
||||
$!You should have received a copy of the GNU General Public License along with
|
||||
$!this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
$!this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
45
mk/Amiga.mk
45
mk/Amiga.mk
@ -1,45 +0,0 @@
|
||||
# GNU -*-Makefile-*- to build GNU make on Amiga
|
||||
#
|
||||
# Amiga overrides for use with Basic.mk.
|
||||
#
|
||||
# Copyright (C) 2017-2022 Free Software Foundation, Inc.
|
||||
# This file is part of GNU Make.
|
||||
#
|
||||
# GNU Make is free software; you can redistribute it and/or modify it under
|
||||
# the terms of the GNU General Public License as published by the Free Software
|
||||
# Foundation; either version 3 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
CC = sc
|
||||
LD = $(CC) Link
|
||||
|
||||
MKDIR.cmd = makedir $1
|
||||
RM.cmd = delete $1
|
||||
CP.cmd = copy $1 To $2
|
||||
|
||||
CPPFLAGS =
|
||||
CFLAGS =
|
||||
LDFLAGS =
|
||||
|
||||
prog_SOURCES += $(alloca_SOURCES) $(loadavg_SOURCES) $(glob_SOURCES) $(amiga_SOURCES)
|
||||
|
||||
BUILT_SOURCES += $(lib)alloca.h $(lib)fnmatch.h $(lib)glob.h
|
||||
|
||||
extra_CPPFLAGS = IDir $(OUTDIR)src IDir $(SRCDIR)/src IDir $(OUTDIR)lib IDir $(SRCDIR)/lib
|
||||
|
||||
C_SOURCE =
|
||||
OUTPUT_OPTION =
|
||||
LDFLAGS = From LIB:cres.o
|
||||
LDLIBS = Lib LIB:sc.lib LIB:amiga.lib
|
||||
LINK_OUTPUT = To $@
|
||||
|
||||
$(OUTDIR)src/config.h: $(SRCDIR)/src/config.ami
|
||||
$(call CP.cmd,$<,$@)
|
@ -1,8 +1,8 @@
|
||||
# GNU -*-Makefile-*- to build GNU make on POSIX systems
|
||||
# GNU -*-Makefile-*- to build GNU Make on POSIX systems
|
||||
#
|
||||
# POSIX overrides for use with Basic.mk.
|
||||
#
|
||||
# Copyright (C) 2017-2022 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2017-2024 Free Software Foundation, Inc.
|
||||
# This file is part of GNU Make.
|
||||
#
|
||||
# GNU Make is free software; you can redistribute it and/or modify it under
|
||||
@ -16,11 +16,11 @@
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
# this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
# Very little is needed here since the default Basic.mk assumes POSIX
|
||||
|
||||
prog_SOURCES += $(posix_SOURCES)
|
||||
prog_SOURCES += $(src)/posixos.c
|
||||
|
||||
extra_CPPFLAGS += @GUILE_CFLAGS@
|
||||
extra_LDFLAGS += @AM_LDFLAGS@
|
||||
|
@ -1,8 +1,8 @@
|
||||
# GNU -*-Makefile-*- to build GNU make on VMS
|
||||
# GNU -*-Makefile-*- to build GNU Make on VMS
|
||||
#
|
||||
# VMS overrides for use with Basic.mk.
|
||||
#
|
||||
# Copyright (C) 2017-2022 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2017-2024 Free Software Foundation, Inc.
|
||||
# This file is part of GNU Make.
|
||||
#
|
||||
# GNU Make is free software; you can redistribute it and/or modify it under
|
||||
@ -16,7 +16,7 @@
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
# this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
src = [.src]
|
||||
lib = [.lib]
|
||||
@ -93,5 +93,5 @@ define CLEANSPACE
|
||||
endef
|
||||
|
||||
|
||||
$(OUTDIR)$(src)config.h: $(SRCDIR)$(src)config.h.W32
|
||||
$(OUTDIR)$(src)config.h: $(SRCDIR)$(src)config.h-vms
|
||||
$(call CP.cmd,$<,$@)
|
||||
|
@ -1,8 +1,8 @@
|
||||
# GNU -*-Makefile-*- to build GNU make on Windows
|
||||
# GNU -*-Makefile-*- to build GNU Make on Windows
|
||||
#
|
||||
# Windows overrides for use with Basic.mk.
|
||||
#
|
||||
# Copyright (C) 2017-2022 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2017-2024 Free Software Foundation, Inc.
|
||||
# This file is part of GNU Make.
|
||||
#
|
||||
# GNU Make is free software; you can redistribute it and/or modify it under
|
||||
@ -16,7 +16,7 @@
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
# this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
# TARGET_TYPE can be either "release" or "debug"
|
||||
TARGET_TYPE = release
|
||||
@ -30,6 +30,8 @@ P2W = $(subst /,\,$1)
|
||||
|
||||
prog_SOURCES += $(loadavg_SOURCES) $(glob_SOURCES) $(w32_SOURCES)
|
||||
|
||||
utf8_SOURCES = $(src)w32/utf8.rc $(src)w32/utf8.manifest
|
||||
|
||||
BUILT_SOURCES += $(lib)alloca.h $(lib)fnmatch.h $(lib)glob.h
|
||||
|
||||
w32_LIBS = kernel32 user32 gdi32 winspool comdlg32 advapi32 shell32 ole32 \
|
||||
@ -41,9 +43,10 @@ LDFLAGS =
|
||||
|
||||
# --- Visual Studio
|
||||
msvc_CC = cl.exe
|
||||
msvc_RC = rc.exe
|
||||
msvc_LD = link.exe
|
||||
|
||||
msvc_CPPFLAGS = /DHAVE_CONFIG_H /DWINDOWS32 /DWIN32 /D_CONSOLE
|
||||
msvc_CPPFLAGS = /DHAVE_CONFIG_H /DMK_OS_W32=1 /DWIN32 /D_CONSOLE
|
||||
msvc_CPPFLAGS += /I$(OUTDIR)src /I$(SRCDIR)/src /I$(SRCDIR)/src/w32/include /I$(OUTDIR)lib /I$(SRCDIR)/lib
|
||||
|
||||
msvc_CFLAGS = /nologo /MT /W4 /EHsc
|
||||
@ -54,6 +57,7 @@ msvc_LDFLAGS = /nologo /SUBSYSTEM:console /PDB:$(BASE_PROG).pdb
|
||||
msvc_LDLIBS = $(addsuffix .lib,$(w32_LIBS))
|
||||
|
||||
msvc_C_SOURCE = /c
|
||||
msvc_RC_SOURCE =
|
||||
msvc_OUTPUT_OPTION = /Fo$@
|
||||
msvc_LINK_OUTPUT = /OUT:$@
|
||||
|
||||
@ -68,6 +72,7 @@ debug_msvc_LDFLAGS = /DEBUG
|
||||
|
||||
# --- GCC
|
||||
gcc_CC = gcc
|
||||
gcc_RC = windres
|
||||
gcc_LD = $(gcc_CC)
|
||||
|
||||
release_gcc_OUTDIR = ./GccRel/
|
||||
@ -79,6 +84,7 @@ gcc_LDFLAGS = -mthreads -gdwarf-2 -g3
|
||||
gcc_LDLIBS = $(addprefix -l,$(w32_libs))
|
||||
|
||||
gcc_C_SOURCE = -c
|
||||
gcc_RC_SOURCE = -i
|
||||
gcc_OUTPUT_OPTION = -o $@
|
||||
gcc_LINK_OUTPUT = -o $@
|
||||
|
||||
@ -87,6 +93,7 @@ release_gcc_CFLAGS = -O2
|
||||
|
||||
# ---
|
||||
|
||||
RES_COMPILE.cmd = $(RC) $(OUTPUT_OPTION) $(RC_SOURCE) $1
|
||||
LINK.cmd = $(LD) $(extra_LDFLAGS) $(LDFLAGS) $(TARGET_ARCH) $1 $(LDLIBS) $(LINK_OUTPUT)
|
||||
|
||||
CHECK.cmd = cmd /c cd tests \& .\run_make_tests.bat -make ../$(PROG)
|
||||
@ -96,9 +103,11 @@ RM.cmd = cmd /c del /F /Q $(call P2W,$1)
|
||||
CP.cmd = cmd /c copy /Y $(call P2W,$1 $2)
|
||||
|
||||
CC = $($(TOOLCHAIN)_CC)
|
||||
RC = $($(TOOLCHAIN)_RC)
|
||||
LD = $($(TOOLCHAIN)_LD)
|
||||
|
||||
C_SOURCE = $($(TOOLCHAIN)_C_SOURCE)
|
||||
RC_SOURCE = $($(TOOLCHAIN)_RC_SOURCE)
|
||||
OUTPUT_OPTION = $($(TOOLCHAIN)_OUTPUT_OPTION)
|
||||
LINK_OUTPUT = $($(TOOLCHAIN)_LINK_OUTPUT)
|
||||
|
||||
@ -120,3 +129,11 @@ LDLIBS = $(call _CUSTOM,LDLIBS)
|
||||
|
||||
$(OUTDIR)src/config.h: $(SRCDIR)/src/config.h.W32
|
||||
$(call CP.cmd,$<,$@)
|
||||
|
||||
w32_UTF8OBJ = $(OUTDIR)src/w32/utf8.$(OBJEXT)
|
||||
$(w32_UTF8OBJ): $(utf8_SOURCES)
|
||||
$(call RES_COMPILE.cmd,$<)
|
||||
|
||||
ifneq (, $(shell where $(RC) 2>nul))
|
||||
RESOURCE_OBJECTS = $(w32_UTF8OBJ)
|
||||
endif
|
||||
|
@ -1,8 +1,8 @@
|
||||
# GNU -*-Makefile-*- to build GNU make on MS-DOS with DJGPP
|
||||
# GNU -*-Makefile-*- to build GNU Make on MS-DOS with DJGPP
|
||||
#
|
||||
# MS-DOS overrides for use with Basic.mk.
|
||||
#
|
||||
# Copyright (C) 2017-2022 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2017-2024 Free Software Foundation, Inc.
|
||||
# This file is part of GNU Make.
|
||||
#
|
||||
# GNU Make is free software; you can redistribute it and/or modify it under
|
||||
@ -16,7 +16,7 @@
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
# this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
OBJEXT = o
|
||||
EXEEXT = .exe
|
||||
|
@ -13,6 +13,7 @@ hr
|
||||
id
|
||||
it
|
||||
ja
|
||||
ka
|
||||
ko
|
||||
lt
|
||||
nl
|
||||
|
@ -1,5 +1,5 @@
|
||||
# List of source files containing translatable strings.
|
||||
# Copyright (C) 2000-2022 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2000-2024 Free Software Foundation, Inc.
|
||||
# This file is part of GNU Make.
|
||||
#
|
||||
# GNU Make is free software; you can redistribute it and/or modify it under
|
||||
@ -13,7 +13,7 @@
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
# this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
src/ar.c
|
||||
src/arscan.c
|
||||
@ -31,7 +31,6 @@ src/load.c
|
||||
src/main.c
|
||||
src/misc.c
|
||||
src/output.c
|
||||
src/output.h
|
||||
src/posixos.c
|
||||
src/read.c
|
||||
src/remake.c
|
||||
@ -41,8 +40,9 @@ src/shuffle.c
|
||||
src/signame.c
|
||||
src/strcache.c
|
||||
src/variable.c
|
||||
src/variable.h
|
||||
src/vmsfunctions.c
|
||||
src/vmsjobs.c
|
||||
src/vpath.c
|
||||
src/warning.c
|
||||
src/warning.h
|
||||
src/w32/w32os.c
|
||||
|
@ -4,28 +4,27 @@ $!
|
||||
$! This is used for building off the master instead of a release tarball.
|
||||
$!
|
||||
$!
|
||||
$!
|
||||
$! First try ODS-5, Pathworks V6 or UNZIP name.
|
||||
$!
|
||||
$ config_template = f$search("sys$disk:[]config*h-vms.template")
|
||||
$ config_template = f$search("sys$disk:[.src]mkconfig*h.in")
|
||||
$ if config_template .eqs. ""
|
||||
$ then
|
||||
$!
|
||||
$! Try NFS, VMStar, or Pathworks V5 ODS-2 encoded name.
|
||||
$!
|
||||
$ config_template = f$search("sys$disk:[]config.h-vms*template")
|
||||
$ config_template = f$search("sys$disk:[.src]mkconfig.h*in")
|
||||
$ if config_template .eqs. ""
|
||||
$ then
|
||||
$ write sys$output "Could not find config.h-vms*template!"
|
||||
$ write sys$output "Could not find mkconfig.h.in!"
|
||||
$ exit 44
|
||||
$ endif
|
||||
$ endif
|
||||
$ config_template_file = f$parse(config_template,,,"name")
|
||||
$ config_template_type = f$parse(config_template,,,"type")
|
||||
$ config_template = "sys$disk:[]" + config_template_file + config_template_type
|
||||
$ config_template = "sys$disk:[.src]" + config_template_file + config_template_type
|
||||
$!
|
||||
$!
|
||||
$! Pull the package and version from configure.ac
|
||||
$! Pull the version from configure.ac
|
||||
$!
|
||||
$ open/read ac_file sys$disk:[]configure.ac
|
||||
$ac_read_loop:
|
||||
@ -39,21 +38,26 @@ $ version = f$element (0,"]",version)
|
||||
$ac_read_loop_end:
|
||||
$ close ac_file
|
||||
$!
|
||||
$ if (package .eqs. "") .or. (version .eqs. "")
|
||||
$ if (version .eqs. "")
|
||||
$ then
|
||||
$ write sys$output "Unable to determine package and/or version!"
|
||||
$ write sys$output "Unable to determine version!"
|
||||
$ exit 44
|
||||
$ endif
|
||||
$!
|
||||
$!
|
||||
$ outfile = "sys$disk:[]config.h-vms"
|
||||
$ outfile = "sys$disk:[.src]mkconfig.h"
|
||||
$!
|
||||
$! Note the pipe command is close to the length of 255, which is the
|
||||
$! maximum token length prior to VMS V8.2:
|
||||
$! %DCL-W-TKNOVF, command element is too long - shorten
|
||||
$ pipe (write sys$output "sub/%PACKAGE%/''package'/WHOLE/NOTYPE" ;-
|
||||
write sys$output "sub/%VERSION%/''version'/WHOLE/NOTYPE" ;-
|
||||
$! PDS: Blown out; someone else will have to figure this out
|
||||
$ pipe (write sys$output "sub,@PACKAGE@,make,WHOLE/NOTYPE" ;-
|
||||
write sys$output "sub,@PACKAGE_BUGREPORT@,bug-make@gnu.org,WHOLE/NOTYPE" ;-
|
||||
write sys$output "sub,@PACKAGE_NAME@,GNU Make,WHOLE/NOTYPE" ;-
|
||||
write sys$output "sub,@PACKAGE_TARNAME@,make,WHOLE/NOTYPE" ;-
|
||||
write sys$output "sub,@PACKAGE_URL@,https://www.gnu.org/software/make/,WHOLE/NOTYPE" ;-
|
||||
write sys$output "sub,@PACKAGE_VERSION@,''version',WHOLE/NOTYPE" ;-
|
||||
write sys$output "exit") |-
|
||||
edit/edt 'config_template'/out='outfile'/command=sys$pipe >nla0:
|
||||
$!
|
||||
$ write sys$output package, ", version: ", version, " prepared for VMS"
|
||||
$ write sys$output "GNU Make version: ", version, " prepared for VMS"
|
||||
|
@ -1,9 +1,9 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (C) 2014-2022 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2014-2024 Free Software Foundation, Inc.
|
||||
# This file is part of GNU Make.
|
||||
#
|
||||
# Update GNU make copyrights using gnulib update-copyright
|
||||
# Update GNU Make copyrights using gnulib update-copyright
|
||||
|
||||
EXCLUDE='^\(\.[a-z].*\|.*/\.[a-z].*\|.*COPYING\|src/hash\.[ch]\|ChangeLog.*\|.*/ChangeLog.*\|INSTALL\|doc/make\.texi\|bootstrap\)$'
|
||||
|
||||
@ -31,7 +31,7 @@ run () {
|
||||
if $force; then
|
||||
: just do it
|
||||
elif test ! -f src/makeint.h; then
|
||||
die "Run in the root of the GNU make workspace"
|
||||
die "Run in the root of the GNU Make workspace"
|
||||
elif test -f configure; then
|
||||
die "Run in a clean workspace (git clean -fdX)"
|
||||
fi
|
||||
@ -60,4 +60,4 @@ run "$@"
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
# this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
113
src/amiga.c
113
src/amiga.c
@ -1,113 +0,0 @@
|
||||
/* Running commands on Amiga
|
||||
Copyright (C) 1995-2022 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "makeint.h"
|
||||
#include "variable.h"
|
||||
#include "amiga.h"
|
||||
#include <assert.h>
|
||||
#include <exec/memory.h>
|
||||
#include <dos/dostags.h>
|
||||
#include <proto/exec.h>
|
||||
#include <proto/dos.h>
|
||||
|
||||
static const char Amiga_version[] = "$VER: Make 3.74.3 (12.05.96) \n"
|
||||
"Amiga Port by A. Digulla (digulla@home.lake.de)";
|
||||
|
||||
int
|
||||
MyExecute (char **argv)
|
||||
{
|
||||
char * buffer, * ptr;
|
||||
char ** aptr;
|
||||
int len = 0;
|
||||
int status;
|
||||
|
||||
for (aptr=argv; *aptr; aptr++)
|
||||
{
|
||||
len += strlen (*aptr) + 4;
|
||||
}
|
||||
|
||||
buffer = AllocMem (len, MEMF_ANY);
|
||||
|
||||
if (!buffer)
|
||||
O (fatal, NILF, "MyExecute: Cannot allocate space for calling a command");
|
||||
|
||||
ptr = buffer;
|
||||
|
||||
for (aptr=argv; *aptr; aptr++)
|
||||
{
|
||||
if (((*aptr)[0] == ';' && !(*aptr)[1]))
|
||||
{
|
||||
*ptr ++ = '"';
|
||||
ptr = stpcpy (ptr, *aptr);
|
||||
*(ptr++) = '"';
|
||||
}
|
||||
else if ((*aptr)[0] == '@' && (*aptr)[1] == '@' && !(*aptr)[2])
|
||||
{
|
||||
*ptr ++ = '\n';
|
||||
continue;
|
||||
}
|
||||
else
|
||||
ptr = stpcpy (ptr, *aptr);
|
||||
*ptr ++ = ' ';
|
||||
*ptr = 0;
|
||||
}
|
||||
|
||||
ptr[-1] = '\n';
|
||||
|
||||
status = SystemTags (buffer,
|
||||
SYS_UserShell, TRUE,
|
||||
TAG_END);
|
||||
|
||||
FreeMem (buffer, len);
|
||||
|
||||
if (SetSignal (0L,0L) & SIGBREAKF_CTRL_C)
|
||||
status = 20;
|
||||
|
||||
/* Warnings don't count */
|
||||
if (status == 5)
|
||||
status = 0;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
char *
|
||||
wildcard_expansion (char *wc, char *o)
|
||||
{
|
||||
# define PATH_SIZE 1024
|
||||
struct AnchorPath * apath;
|
||||
|
||||
if ( (apath = AllocMem (sizeof (struct AnchorPath) + PATH_SIZE,
|
||||
MEMF_CLEAR))
|
||||
)
|
||||
{
|
||||
apath->ap_Strlen = PATH_SIZE;
|
||||
|
||||
if (MatchFirst (wc, apath) == 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
o = variable_buffer_output (o, apath->ap_Buf,
|
||||
strlen (apath->ap_Buf));
|
||||
o = variable_buffer_output (o, " ",1);
|
||||
} while (MatchNext (apath) == 0);
|
||||
}
|
||||
|
||||
MatchEnd (apath);
|
||||
FreeMem (apath, sizeof (struct AnchorPath) + PATH_SIZE);
|
||||
}
|
||||
|
||||
return o;
|
||||
}
|
18
src/amiga.h
18
src/amiga.h
@ -1,18 +0,0 @@
|
||||
/* Definitions for amiga specific things
|
||||
Copyright (C) 1995-2022 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
int MyExecute (char ** argv);
|
||||
char * wildcard_expansion (char * wc, char * o);
|
44
src/ar.c
44
src/ar.c
@ -1,5 +1,5 @@
|
||||
/* Interface to 'ar' archives for GNU Make.
|
||||
Copyright (C) 1988-2022 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988-2024 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Make.
|
||||
|
||||
@ -13,7 +13,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "makeint.h"
|
||||
|
||||
@ -22,6 +22,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
#include "filedef.h"
|
||||
#include "dep.h"
|
||||
#include <fnmatch.h>
|
||||
#include <intprops.h>
|
||||
|
||||
/* Return nonzero if NAME is an archive-member reference, zero if not. An
|
||||
archive-member reference is a name like 'lib(member)' where member is a
|
||||
@ -35,7 +36,7 @@ ar_name (const char *name)
|
||||
const char *p = strchr (name, '(');
|
||||
const char *end;
|
||||
|
||||
if (p == 0 || p == name)
|
||||
if (p == NULL || p == name)
|
||||
return 0;
|
||||
|
||||
end = p + strlen (p) - 1;
|
||||
@ -60,6 +61,9 @@ ar_parse_name (const char *name, char **arname_p, char **memname_p)
|
||||
|
||||
*arname_p = xstrdup (name);
|
||||
p = strchr (*arname_p, '(');
|
||||
/* This is never called unless ar_name() is true so p cannot be NULL. */
|
||||
if (!p)
|
||||
OS (fatal, NILF, "INTERNAL: ar_parse_name: bad name '%s'", *arname_p);
|
||||
*(p++) = '\0';
|
||||
p[strlen (p) - 1] = '\0';
|
||||
*memname_p = p;
|
||||
@ -69,10 +73,10 @@ ar_parse_name (const char *name, char **arname_p, char **memname_p)
|
||||
/* This function is called by 'ar_scan' to find which member to look at. */
|
||||
|
||||
/* ARGSUSED */
|
||||
static long int
|
||||
static intmax_t
|
||||
ar_member_date_1 (int desc UNUSED, const char *mem, int truncated,
|
||||
long int hdrpos UNUSED, long int datapos UNUSED,
|
||||
long int size UNUSED, long int date,
|
||||
long int size UNUSED, intmax_t date,
|
||||
int uid UNUSED, int gid UNUSED, unsigned int mode UNUSED,
|
||||
const void *name)
|
||||
{
|
||||
@ -86,7 +90,7 @@ ar_member_date (const char *name)
|
||||
{
|
||||
char *arname;
|
||||
char *memname;
|
||||
long int val;
|
||||
intmax_t val;
|
||||
|
||||
ar_parse_name (name, &arname, &memname);
|
||||
|
||||
@ -111,12 +115,12 @@ ar_member_date (const char *name)
|
||||
|
||||
free (arname);
|
||||
|
||||
return (val <= 0 ? (time_t) -1 : (time_t) val);
|
||||
return 0 < val && val <= TYPE_MAXIMUM (time_t) ? val : -1;
|
||||
}
|
||||
|
||||
/* Set the archive-member NAME's modtime to now. */
|
||||
|
||||
#ifdef VMS
|
||||
#if MK_OS_VMS
|
||||
int
|
||||
ar_touch (const char *name)
|
||||
{
|
||||
@ -144,7 +148,7 @@ ar_touch (const char *name)
|
||||
switch (ar_member_touch (arname, memname))
|
||||
{
|
||||
case -1:
|
||||
OS (error, NILF, _("touch: Archive '%s' does not exist"), arname);
|
||||
OS (error, NILF, _("touch: archive '%s' does not exist"), arname);
|
||||
break;
|
||||
case -2:
|
||||
OS (error, NILF, _("touch: '%s' is not a valid archive"), arname);
|
||||
@ -154,21 +158,21 @@ ar_touch (const char *name)
|
||||
break;
|
||||
case 1:
|
||||
OSS (error, NILF,
|
||||
_("touch: Member '%s' does not exist in '%s'"), memname, arname);
|
||||
_("touch: member '%s' does not exist in '%s'"), memname, arname);
|
||||
break;
|
||||
case 0:
|
||||
val = 0;
|
||||
break;
|
||||
default:
|
||||
OS (error, NILF,
|
||||
_("touch: Bad return code from ar_member_touch on '%s'"), name);
|
||||
_("touch: bad return code from ar_member_touch on '%s'"), name);
|
||||
}
|
||||
|
||||
free (arname);
|
||||
|
||||
return val;
|
||||
}
|
||||
#endif /* !VMS */
|
||||
#endif /* !MK_OS_VMS */
|
||||
|
||||
/* State of an 'ar_glob' run, passed to 'ar_glob_match'. */
|
||||
|
||||
@ -183,7 +187,7 @@ struct ar_glob_state
|
||||
{
|
||||
const char *arname;
|
||||
const char *pattern;
|
||||
#ifdef VMS
|
||||
#if MK_OS_VMS
|
||||
char *suffix;
|
||||
#endif
|
||||
size_t size;
|
||||
@ -194,10 +198,10 @@ struct ar_glob_state
|
||||
/* This function is called by 'ar_scan' to match one archive
|
||||
element against the pattern in STATE. */
|
||||
|
||||
static long int
|
||||
static intmax_t
|
||||
ar_glob_match (int desc UNUSED, const char *mem, int truncated UNUSED,
|
||||
long int hdrpos UNUSED, long int datapos UNUSED,
|
||||
long int size UNUSED, long int date UNUSED, int uid UNUSED,
|
||||
long int size UNUSED, intmax_t date UNUSED, int uid UNUSED,
|
||||
int gid UNUSED, unsigned int mode UNUSED, const void *arg)
|
||||
{
|
||||
struct ar_glob_state *state = (struct ar_glob_state *)arg;
|
||||
@ -206,7 +210,7 @@ ar_glob_match (int desc UNUSED, const char *mem, int truncated UNUSED,
|
||||
{
|
||||
/* We have a match. Add it to the chain. */
|
||||
struct nameseq *new = xcalloc (state->size);
|
||||
#ifdef VMS
|
||||
#if MK_OS_VMS
|
||||
if (state->suffix)
|
||||
new->name = strcache_add(
|
||||
concat(5, state->arname, "(", mem, state->suffix, ")"));
|
||||
@ -218,7 +222,7 @@ ar_glob_match (int desc UNUSED, const char *mem, int truncated UNUSED,
|
||||
++state->n;
|
||||
}
|
||||
|
||||
return 0L;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return nonzero if PATTERN contains any metacharacters.
|
||||
@ -264,7 +268,7 @@ ar_glob (const char *arname, const char *member_pattern, size_t size)
|
||||
struct nameseq *n;
|
||||
const char **names;
|
||||
unsigned int i;
|
||||
#ifdef VMS
|
||||
#if MK_OS_VMS
|
||||
char *vms_member_pattern;
|
||||
#endif
|
||||
if (! ar_glob_pattern_p (member_pattern, 1))
|
||||
@ -274,7 +278,7 @@ ar_glob (const char *arname, const char *member_pattern, size_t size)
|
||||
ar_glob_match will accumulate them in STATE.chain. */
|
||||
state.arname = arname;
|
||||
state.pattern = member_pattern;
|
||||
#ifdef VMS
|
||||
#if MK_OS_VMS
|
||||
{
|
||||
/* In a copy of the pattern, find the suffix, save it and remove it from
|
||||
the pattern */
|
||||
@ -295,7 +299,7 @@ ar_glob (const char *arname, const char *member_pattern, size_t size)
|
||||
state.n = 0;
|
||||
ar_scan (arname, ar_glob_match, &state);
|
||||
|
||||
#ifdef VMS
|
||||
#if MK_OS_VMS
|
||||
/* Deallocate any duplicated string */
|
||||
free(vms_member_pattern);
|
||||
if (state.suffix)
|
||||
|
124
src/arscan.c
124
src/arscan.c
@ -1,5 +1,5 @@
|
||||
/* Library function for scanning an archive file.
|
||||
Copyright (C) 1987-2022 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2024 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
@ -12,7 +12,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "makeint.h"
|
||||
|
||||
@ -29,7 +29,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef NO_ARCHIVES
|
||||
|
||||
#ifdef VMS
|
||||
#if MK_OS_VMS
|
||||
#include <lbrdef.h>
|
||||
#include <mhddef.h>
|
||||
#include <credef.h>
|
||||
@ -75,9 +75,9 @@ static void *VMS_lib_idx;
|
||||
|
||||
static const void *VMS_saved_arg;
|
||||
|
||||
static long int (*VMS_function) ();
|
||||
static intmax_t (*VMS_function) ();
|
||||
|
||||
static long int VMS_function_ret;
|
||||
static intmax_t VMS_function_ret;
|
||||
|
||||
|
||||
/* This is a callback procedure for lib$get_index */
|
||||
@ -203,7 +203,7 @@ VMS_get_member_info(struct dsc$descriptor_s *module, unsigned long *rfa)
|
||||
Returns -2 if archive has invalid format.
|
||||
Returns 0 if have scanned successfully. */
|
||||
|
||||
long int
|
||||
intmax_t
|
||||
ar_scan (const char *archive, ar_member_func_t function, const void *varg)
|
||||
{
|
||||
char *vms_archive;
|
||||
@ -289,11 +289,11 @@ ar_scan (const char *archive, ar_member_func_t function, const void *varg)
|
||||
return -2;
|
||||
}
|
||||
|
||||
#else /* !VMS */
|
||||
#else /* !MK_OS_VMS */
|
||||
|
||||
/* SCO Unix's compiler defines both of these. */
|
||||
#ifdef M_UNIX
|
||||
#undef M_XENIX
|
||||
#ifdef M_UNIX
|
||||
#undef M_XENIX
|
||||
#endif
|
||||
|
||||
/* On the sun386i and in System V rel 3, ar.h defines two different archive
|
||||
@ -302,7 +302,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *varg)
|
||||
to have a nonzero value. */
|
||||
|
||||
#if (!defined (PORTAR) || PORTAR == 0) && (!defined (PORT5AR) || PORT5AR == 0)
|
||||
#undef PORTAR
|
||||
#undef PORTAR
|
||||
#ifdef M_XENIX
|
||||
/* According to Jim Sievert <jas1@rsvl.unisys.com>, for SCO XENIX defining
|
||||
PORTAR to 1 gets the wrong archive format, and defining it to 0 gets the
|
||||
@ -330,8 +330,8 @@ ar_scan (const char *archive, ar_member_func_t function, const void *varg)
|
||||
# define __AR_BIG__
|
||||
#endif
|
||||
|
||||
#ifndef WINDOWS32
|
||||
# if !defined (__ANDROID__) && !defined (__BEOS__)
|
||||
#if !MK_OS_W32
|
||||
# if !defined (__ANDROID__) && !defined (__BEOS__) && !defined(MK_OS_ZOS)
|
||||
# include <ar.h>
|
||||
# else
|
||||
/* These platforms don't have <ar.h> but have archives in the same format
|
||||
@ -376,16 +376,18 @@ struct ar_hdr
|
||||
# define AR_HDR_SIZE (sizeof (struct ar_hdr))
|
||||
#endif
|
||||
|
||||
#include "intprops.h"
|
||||
|
||||
#include "output.h"
|
||||
|
||||
|
||||
static unsigned long int
|
||||
parse_int (const char *ptr, const size_t len, const int base,
|
||||
static uintmax_t
|
||||
parse_int (const char *ptr, const size_t len, const int base, uintmax_t max,
|
||||
const char *type, const char *archive, const char *name)
|
||||
{
|
||||
const char *const ep = ptr + len;
|
||||
const char max = '0' + base - 1;
|
||||
long int val = 0;
|
||||
const int maxchar = '0' + base - 1;
|
||||
uintmax_t val = 0;
|
||||
|
||||
/* In all the versions I know of the spaces come last, but be safe. */
|
||||
while (ptr < ep && *ptr == ' ')
|
||||
@ -393,10 +395,12 @@ parse_int (const char *ptr, const size_t len, const int base,
|
||||
|
||||
while (ptr < ep && *ptr != ' ')
|
||||
{
|
||||
if (*ptr < '0' || *ptr > max)
|
||||
OSSS (fatal, NILF, _("Invalid %s for archive %s member %s"),
|
||||
type, archive, name);
|
||||
val = (val * base) + (*ptr - '0');
|
||||
if (*ptr < '0' || *ptr > maxchar
|
||||
|| INT_MULTIPLY_WRAPV (val, base, &val)
|
||||
|| INT_ADD_WRAPV (val, *ptr - '0', &val)
|
||||
|| val > max)
|
||||
OSSS (fatal, NILF,
|
||||
_("invalid %s for archive %s member %s"), type, archive, name);
|
||||
++ptr;
|
||||
}
|
||||
|
||||
@ -430,7 +434,7 @@ parse_int (const char *ptr, const size_t len, const int base,
|
||||
Returns -2 if archive has invalid format.
|
||||
Returns 0 if have scanned successfully. */
|
||||
|
||||
long int
|
||||
intmax_t
|
||||
ar_scan (const char *archive, ar_member_func_t function, const void *arg)
|
||||
{
|
||||
#ifdef AIAMAG
|
||||
@ -550,7 +554,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
|
||||
# define ARNAME_MAX 255
|
||||
char name[ARNAME_MAX + 1];
|
||||
int name_len;
|
||||
long int dateval;
|
||||
intmax_t dateval;
|
||||
int uidval, gidval;
|
||||
long int data_offset;
|
||||
#else
|
||||
@ -562,7 +566,9 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
|
||||
#endif
|
||||
long int eltsize;
|
||||
unsigned int eltmode;
|
||||
long int fnval;
|
||||
intmax_t eltdate;
|
||||
int eltuid, eltgid;
|
||||
intmax_t fnval;
|
||||
off_t o;
|
||||
|
||||
memset(&member_header, '\0', sizeof (member_header));
|
||||
@ -593,7 +599,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
|
||||
|
||||
name[name_len] = '\0';
|
||||
|
||||
sscanf (member_header_big.ar_date, "%12ld", &dateval);
|
||||
sscanf (member_header_big.ar_date, "%12" SCNdMAX, &dateval);
|
||||
sscanf (member_header_big.ar_uid, "%12d", &uidval);
|
||||
sscanf (member_header_big.ar_gid, "%12d", &gidval);
|
||||
sscanf (member_header_big.ar_mode, "%12o", &eltmode);
|
||||
@ -621,7 +627,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
|
||||
|
||||
name[name_len] = '\0';
|
||||
|
||||
sscanf (member_header.ar_date, "%12ld", &dateval);
|
||||
sscanf (member_header.ar_date, "%12" SCNdMAX, &dateval);
|
||||
sscanf (member_header.ar_uid, "%12d", &uidval);
|
||||
sscanf (member_header.ar_gid, "%12d", &gidval);
|
||||
sscanf (member_header.ar_mode, "%12o", &eltmode);
|
||||
@ -716,12 +722,12 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
|
||||
const char* err;
|
||||
unsigned int name_len = make_toui (name + 3, &err);
|
||||
|
||||
if (err || name_len == 0 || name_len > PATH_MAX)
|
||||
if (err || name_len == 0 || name_len >= MIN (PATH_MAX, INT_MAX))
|
||||
goto invalid;
|
||||
|
||||
name = alloca (name_len + 1);
|
||||
nread = readbuf (desc, name, name_len);
|
||||
if (nread != name_len)
|
||||
if (nread < 0 || (unsigned int) nread != name_len)
|
||||
goto invalid;
|
||||
|
||||
name[name_len] = '\0';
|
||||
@ -732,8 +738,16 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
|
||||
}
|
||||
|
||||
#ifndef M_XENIX
|
||||
eltmode = parse_int (TOCHAR (member_header.ar_mode), sizeof (member_header.ar_mode), 8, "mode", archive, name);
|
||||
eltsize = parse_int (TOCHAR (member_header.ar_size), sizeof (member_header.ar_size), 10, "size", archive, name);
|
||||
#define PARSE_INT(_m, _t, _b, _n) \
|
||||
(_t) parse_int (TOCHAR (member_header._m), sizeof (member_header._m), \
|
||||
_b, TYPE_MAXIMUM (_t), _n, archive, name)
|
||||
|
||||
eltmode = PARSE_INT (ar_mode, unsigned int, 8, "mode");
|
||||
eltsize = PARSE_INT (ar_size, long, 10, "size");
|
||||
eltdate = PARSE_INT (ar_date, intmax_t, 10, "date");
|
||||
eltuid = PARSE_INT (ar_uid, int, 10, "uid");
|
||||
eltgid = PARSE_INT (ar_gid, int, 10, "gid");
|
||||
#undef PARSE_INT
|
||||
#else /* Xenix. */
|
||||
eltmode = (unsigned short int) member_header.ar_mode;
|
||||
eltsize = member_header.ar_size;
|
||||
@ -743,9 +757,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
|
||||
(*function) (desc, name, ! long_name, member_offset,
|
||||
member_offset + AR_HDR_SIZE, eltsize,
|
||||
#ifndef M_XENIX
|
||||
parse_int (TOCHAR (member_header.ar_date), sizeof (member_header.ar_date), 10, "date", archive, name),
|
||||
parse_int (TOCHAR (member_header.ar_uid), sizeof (member_header.ar_uid), 10, "uid", archive, name),
|
||||
parse_int (TOCHAR (member_header.ar_gid), sizeof (member_header.ar_gid), 10, "gid", archive, name),
|
||||
eltdate, eltuid, eltgid,
|
||||
#else /* Xenix. */
|
||||
member_header.ar_date,
|
||||
member_header.ar_uid,
|
||||
@ -825,7 +837,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
|
||||
close (desc);
|
||||
return -2;
|
||||
}
|
||||
#endif /* !VMS */
|
||||
#endif /* !MK_OS_VMS */
|
||||
|
||||
/* Return nonzero iff NAME matches MEM.
|
||||
If TRUNCATED is nonzero, MEM may be truncated to
|
||||
@ -836,11 +848,16 @@ ar_name_equal (const char *name, const char *mem, int truncated)
|
||||
{
|
||||
const char *p;
|
||||
|
||||
/* GNU ar allows -P to preserve parent paths, so test the literal name
|
||||
before stripping off the directory. */
|
||||
if (streq (name, mem))
|
||||
return 1;
|
||||
|
||||
p = strrchr (name, '/');
|
||||
if (p != 0)
|
||||
name = p + 1;
|
||||
|
||||
#ifndef VMS
|
||||
#if !MK_OS_VMS
|
||||
if (truncated)
|
||||
{
|
||||
#ifdef AIAMAG
|
||||
@ -880,15 +897,15 @@ ar_name_equal (const char *name, const char *mem, int truncated)
|
||||
match = !strcasecmp (name, mem);
|
||||
return match;
|
||||
}
|
||||
#endif /* !VMS */
|
||||
#endif /* !MK_OS_VMS */
|
||||
}
|
||||
|
||||
#ifndef VMS
|
||||
#if !MK_OS_VMS
|
||||
/* ARGSUSED */
|
||||
static long int
|
||||
static intmax_t
|
||||
ar_member_pos (int desc UNUSED, const char *mem, int truncated,
|
||||
long int hdrpos, long int datapos UNUSED, long int size UNUSED,
|
||||
long int date UNUSED, int uid UNUSED, int gid UNUSED,
|
||||
intmax_t date UNUSED, int uid UNUSED, int gid UNUSED,
|
||||
unsigned int mode UNUSED, const void *name)
|
||||
{
|
||||
if (!ar_name_equal (name, mem, truncated))
|
||||
@ -906,12 +923,13 @@ ar_member_pos (int desc UNUSED, const char *mem, int truncated,
|
||||
int
|
||||
ar_member_touch (const char *arname, const char *memname)
|
||||
{
|
||||
long int pos = ar_scan (arname, ar_member_pos, memname);
|
||||
intmax_t pos = ar_scan (arname, ar_member_pos, memname);
|
||||
off_t opos;
|
||||
int fd;
|
||||
struct ar_hdr ar_hdr;
|
||||
off_t o;
|
||||
int r;
|
||||
unsigned int ui;
|
||||
int datelen;
|
||||
struct stat statbuf;
|
||||
|
||||
if (pos < 0)
|
||||
@ -919,11 +937,13 @@ ar_member_touch (const char *arname, const char *memname)
|
||||
if (!pos)
|
||||
return 1;
|
||||
|
||||
opos = (off_t) pos;
|
||||
|
||||
EINTRLOOP (fd, open (arname, O_RDWR, 0666));
|
||||
if (fd < 0)
|
||||
return -3;
|
||||
/* Read in this member's header */
|
||||
EINTRLOOP (o, lseek (fd, pos, 0));
|
||||
EINTRLOOP (o, lseek (fd, opos, 0));
|
||||
if (o < 0)
|
||||
goto lose;
|
||||
r = readbuf (fd, &ar_hdr, AR_HDR_SIZE);
|
||||
@ -934,16 +954,17 @@ ar_member_touch (const char *arname, const char *memname)
|
||||
if (r < 0)
|
||||
goto lose;
|
||||
/* Advance member's time to that time */
|
||||
#if defined(ARFMAG) || defined(ARFZMAG) || defined(AIAMAG) || defined(WINDOWS32)
|
||||
for (ui = 0; ui < sizeof ar_hdr.ar_date; ui++)
|
||||
ar_hdr.ar_date[ui] = ' ';
|
||||
sprintf (TOCHAR (ar_hdr.ar_date), "%lu", (long unsigned) statbuf.st_mtime);
|
||||
ar_hdr.ar_date[strlen ((char *) ar_hdr.ar_date)] = ' ';
|
||||
#if defined(ARFMAG) || defined(ARFZMAG) || defined(AIAMAG) || MK_OS_W32
|
||||
datelen = snprintf (TOCHAR (ar_hdr.ar_date), sizeof ar_hdr.ar_date,
|
||||
"%" PRIdMAX, (intmax_t) statbuf.st_mtime);
|
||||
if (! (0 <= datelen && datelen < (int) sizeof ar_hdr.ar_date))
|
||||
goto lose;
|
||||
memset (ar_hdr.ar_date + datelen, ' ', sizeof ar_hdr.ar_date - datelen);
|
||||
#else
|
||||
ar_hdr.ar_date = statbuf.st_mtime;
|
||||
#endif
|
||||
/* Write back this member's header */
|
||||
EINTRLOOP (o, lseek (fd, pos, 0));
|
||||
EINTRLOOP (o, lseek (fd, opos, 0));
|
||||
if (o < 0)
|
||||
goto lose;
|
||||
r = writebuf (fd, &ar_hdr, AR_HDR_SIZE);
|
||||
@ -962,18 +983,21 @@ ar_member_touch (const char *arname, const char *memname)
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
long int
|
||||
intmax_t
|
||||
describe_member (int desc, const char *name, int truncated,
|
||||
long int hdrpos, long int datapos, long int size,
|
||||
long int date, int uid, int gid, unsigned int mode,
|
||||
intmax_t date, int uid, int gid, unsigned int mode,
|
||||
const void *arg)
|
||||
{
|
||||
extern char *ctime ();
|
||||
time_t d = date;
|
||||
char const *ds;
|
||||
|
||||
printf (_("Member '%s'%s: %ld bytes at %ld (%ld).\n"),
|
||||
name, truncated ? _(" (name might be truncated)") : "",
|
||||
size, hdrpos, datapos);
|
||||
printf (_(" Date %s"), ctime (&date));
|
||||
ds = ctime (&d);
|
||||
printf (_(" Date %s"), ds ? ds : "?");
|
||||
printf (_(" uid = %d, gid = %d, mode = 0%o.\n"), uid, gid, mode);
|
||||
|
||||
return 0;
|
||||
|
109
src/commands.c
109
src/commands.c
@ -1,5 +1,5 @@
|
||||
/* Command processing for GNU Make.
|
||||
Copyright (C) 1988-2022 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988-2024 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
@ -12,20 +12,21 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "makeint.h"
|
||||
#include "filedef.h"
|
||||
#include "os.h"
|
||||
#include "dep.h"
|
||||
#include "variable.h"
|
||||
#include "job.h"
|
||||
#include "commands.h"
|
||||
#ifdef WINDOWS32
|
||||
#if MK_OS_W32
|
||||
#include <windows.h>
|
||||
#include "w32err.h"
|
||||
#endif
|
||||
|
||||
#if VMS
|
||||
#if MK_OS_VMS
|
||||
# define FILE_LIST_SEPARATOR (vms_comma_separator ? ',' : ' ')
|
||||
#else
|
||||
# define FILE_LIST_SEPARATOR ' '
|
||||
@ -312,7 +313,7 @@ set_file_variables (struct file *file, const char *stem)
|
||||
DEFINE_VARIABLE ("|", 1, bar_value);
|
||||
}
|
||||
|
||||
#undef DEFINE_VARIABLE
|
||||
#undef DEFINE_VARIABLE
|
||||
}
|
||||
|
||||
/* Chop CMDS up into individual command lines if necessary.
|
||||
@ -321,14 +322,12 @@ set_file_variables (struct file *file, const char *stem)
|
||||
void
|
||||
chop_commands (struct commands *cmds)
|
||||
{
|
||||
unsigned int nlines;
|
||||
unsigned short idx;
|
||||
unsigned short nlines;
|
||||
unsigned short i;
|
||||
char **lines;
|
||||
|
||||
/* If we don't have any commands,
|
||||
or we already parsed them, never mind. */
|
||||
|
||||
if (!cmds || cmds->command_lines != 0)
|
||||
/* If we don't have any commands, or we already parsed them, never mind. */
|
||||
if (!cmds || cmds->command_lines != NULL)
|
||||
return;
|
||||
|
||||
/* Chop CMDS->commands up into lines in CMDS->command_lines. */
|
||||
@ -347,25 +346,27 @@ chop_commands (struct commands *cmds)
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *p;
|
||||
const char *p = cmds->commands;
|
||||
size_t max = 5;
|
||||
|
||||
nlines = 5;
|
||||
lines = xmalloc (nlines * sizeof (char *));
|
||||
idx = 0;
|
||||
p = cmds->commands;
|
||||
nlines = 0;
|
||||
lines = xmalloc (max * sizeof (char *));
|
||||
while (*p != '\0')
|
||||
{
|
||||
const char *end = p;
|
||||
find_end:;
|
||||
end = strchr (end, '\n');
|
||||
if (end == 0)
|
||||
if (end == NULL)
|
||||
end = p + strlen (p);
|
||||
else if (end > p && end[-1] == '\\')
|
||||
{
|
||||
int backslash = 1;
|
||||
const char *b;
|
||||
for (b = end - 2; b >= p && *b == '\\'; --b)
|
||||
backslash = !backslash;
|
||||
if (end > p + 1)
|
||||
{
|
||||
const char *b;
|
||||
for (b = end - 2; b >= p && *b == '\\'; --b)
|
||||
backslash = !backslash;
|
||||
}
|
||||
if (backslash)
|
||||
{
|
||||
++end;
|
||||
@ -373,40 +374,36 @@ chop_commands (struct commands *cmds)
|
||||
}
|
||||
}
|
||||
|
||||
if (idx == nlines)
|
||||
if (nlines == USHRT_MAX)
|
||||
ON (fatal, &cmds->fileinfo,
|
||||
_("recipe has too many lines (limit %hu)"), nlines);
|
||||
|
||||
if (nlines == max)
|
||||
{
|
||||
nlines += 2;
|
||||
lines = xrealloc (lines, nlines * sizeof (char *));
|
||||
max += 2;
|
||||
lines = xrealloc (lines, max * sizeof (char *));
|
||||
}
|
||||
lines[idx++] = xstrndup (p, (size_t) (end - p));
|
||||
|
||||
lines[nlines++] = xstrndup (p, (size_t) (end - p));
|
||||
p = end;
|
||||
if (*p != '\0')
|
||||
++p;
|
||||
}
|
||||
|
||||
if (idx != nlines)
|
||||
{
|
||||
nlines = idx;
|
||||
lines = xrealloc (lines, nlines * sizeof (char *));
|
||||
}
|
||||
}
|
||||
|
||||
/* Finally, set the corresponding CMDS->lines_flags elements and the
|
||||
CMDS->any_recurse flag. */
|
||||
|
||||
if (nlines > USHRT_MAX)
|
||||
ON (fatal, &cmds->fileinfo, _("Recipe has too many lines (%ud)"), nlines);
|
||||
|
||||
cmds->ncommand_lines = (unsigned short)nlines;
|
||||
cmds->ncommand_lines = nlines;
|
||||
cmds->command_lines = lines;
|
||||
|
||||
cmds->any_recurse = 0;
|
||||
cmds->lines_flags = xmalloc (nlines);
|
||||
|
||||
for (idx = 0; idx < nlines; ++idx)
|
||||
for (i = 0; i < nlines; ++i)
|
||||
{
|
||||
unsigned char flags = 0;
|
||||
const char *p = lines[idx];
|
||||
const char *p = lines[i];
|
||||
|
||||
while (ISBLANK (*p) || *p == '-' || *p == '@' || *p == '+')
|
||||
switch (*(p++))
|
||||
@ -423,12 +420,12 @@ chop_commands (struct commands *cmds)
|
||||
}
|
||||
|
||||
/* If no explicit '+' was given, look for MAKE variable references. */
|
||||
if (!(flags & COMMANDS_RECURSE)
|
||||
if (! ANY_SET (flags, COMMANDS_RECURSE)
|
||||
&& (strstr (p, "$(MAKE)") != 0 || strstr (p, "${MAKE}") != 0))
|
||||
flags |= COMMANDS_RECURSE;
|
||||
|
||||
cmds->lines_flags[idx] = flags;
|
||||
cmds->any_recurse |= flags & COMMANDS_RECURSE ? 1 : 0;
|
||||
cmds->lines_flags[i] = flags;
|
||||
cmds->any_recurse |= ANY_SET (flags, COMMANDS_RECURSE) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -479,14 +476,14 @@ execute_file_commands (struct file *file)
|
||||
/* This is set while we are inside fatal_error_signal,
|
||||
so things can avoid nonreentrant operations. */
|
||||
|
||||
int handling_fatal_signal = 0;
|
||||
volatile sig_atomic_t handling_fatal_signal = 0;
|
||||
|
||||
/* Handle fatal signals. */
|
||||
|
||||
void
|
||||
fatal_error_signal (int sig)
|
||||
{
|
||||
#ifdef __MSDOS__
|
||||
#if MK_OS_DOS
|
||||
extern int dos_status, dos_command_running;
|
||||
|
||||
if (dos_command_running)
|
||||
@ -497,15 +494,8 @@ fatal_error_signal (int sig)
|
||||
}
|
||||
remove_intermediates (1);
|
||||
exit (EXIT_FAILURE);
|
||||
#else /* not __MSDOS__ */
|
||||
#ifdef _AMIGA
|
||||
remove_intermediates (1);
|
||||
if (sig == SIGINT)
|
||||
fputs (_("*** Break.\n"), stderr);
|
||||
|
||||
exit (10);
|
||||
#else /* not Amiga */
|
||||
#ifdef WINDOWS32
|
||||
#else /* not MK_OS_DOS */
|
||||
#if MK_OS_W32
|
||||
extern HANDLE main_thread;
|
||||
|
||||
/* Windows creates a separate thread for handling Ctrl+C, so we need
|
||||
@ -532,6 +522,10 @@ fatal_error_signal (int sig)
|
||||
It is blocked now while we run this handler. */
|
||||
signal (sig, SIG_DFL);
|
||||
|
||||
temp_stdin_unlink ();
|
||||
osync_clear ();
|
||||
jobserver_clear ();
|
||||
|
||||
/* A termination signal won't be sent to the entire
|
||||
process group, but it means we want to kill the children. */
|
||||
|
||||
@ -587,7 +581,7 @@ fatal_error_signal (int sig)
|
||||
exit (MAKE_TROUBLE);
|
||||
#endif
|
||||
|
||||
#ifdef WINDOWS32
|
||||
#if MK_OS_W32
|
||||
if (main_thread)
|
||||
CloseHandle (main_thread);
|
||||
/* Cannot call W32_kill with a pid (it needs a handle). The exit
|
||||
@ -598,9 +592,8 @@ fatal_error_signal (int sig)
|
||||
will be unblocked when we return and arrive then to kill us. */
|
||||
if (kill (make_pid (), sig) < 0)
|
||||
pfatal_with_name ("kill");
|
||||
#endif /* not WINDOWS32 */
|
||||
#endif /* not Amiga */
|
||||
#endif /* not __MSDOS__ */
|
||||
#endif /* not MK_OS_W32 */
|
||||
#endif /* not MK_OS_DOS */
|
||||
}
|
||||
|
||||
/* Delete FILE unless it's precious or not actually a file (phony),
|
||||
@ -625,11 +618,11 @@ delete_target (struct file *file, const char *on_behalf_of)
|
||||
{
|
||||
if (on_behalf_of)
|
||||
OSS (error, NILF,
|
||||
_("*** [%s] Archive member '%s' may be bogus; not deleted"),
|
||||
_("*** [%s] archive member '%s' may be bogus; not deleted"),
|
||||
on_behalf_of, file->name);
|
||||
else
|
||||
OS (error, NILF,
|
||||
_("*** Archive member '%s' may be bogus; not deleted"),
|
||||
_("*** archive member '%s' may be bogus; not deleted"),
|
||||
file->name);
|
||||
}
|
||||
return;
|
||||
@ -643,9 +636,9 @@ delete_target (struct file *file, const char *on_behalf_of)
|
||||
{
|
||||
if (on_behalf_of)
|
||||
OSS (error, NILF,
|
||||
_("*** [%s] Deleting file '%s'"), on_behalf_of, file->name);
|
||||
_("*** [%s] deleting file '%s'"), on_behalf_of, file->name);
|
||||
else
|
||||
OS (error, NILF, _("*** Deleting file '%s'"), file->name);
|
||||
OS (error, NILF, _("*** deleting file '%s'"), file->name);
|
||||
if (unlink (file->name) < 0
|
||||
&& errno != ENOENT) /* It disappeared; so what. */
|
||||
perror_with_name ("unlink: ", file->name);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Definition of data structures describing shell commands for GNU Make.
|
||||
Copyright (C) 1988-2022 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988-2024 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
@ -12,7 +12,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Structure that gives the commands to make a file
|
||||
and information about where these commands came from. */
|
||||
|
@ -1,329 +0,0 @@
|
||||
/* config.h -- hand-massaged for Amiga -*-C-*-
|
||||
Copyright (C) 1995-2022 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Define if on AIX 3.
|
||||
System headers sometimes define this.
|
||||
We just want to avoid a redefinition error message. */
|
||||
#ifndef _ALL_SOURCE
|
||||
/* #undef _ALL_SOURCE */
|
||||
#endif
|
||||
|
||||
/* Define if using alloca.c. */
|
||||
#define C_ALLOCA
|
||||
|
||||
/* Define if the closedir function returns void instead of int. */
|
||||
/* #undef CLOSEDIR_VOID */
|
||||
|
||||
/* Define to empty if the keyword does not work. */
|
||||
/* #undef const */
|
||||
|
||||
/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
|
||||
This function is required for alloca.c support on those systems. */
|
||||
/* #undef CRAY_STACKSEG_END */
|
||||
|
||||
/* Define for DGUX with <sys/dg_sys_info.h>. */
|
||||
/* #undef DGUX */
|
||||
|
||||
/* Define to 'unsigned long' or 'unsigned long long'
|
||||
if <inttypes.h> doesn't define. */
|
||||
#define uintmax_t unsigned long
|
||||
|
||||
/* Define to 'int' if <sys/types.h> doesn't define. */
|
||||
#define gid_t int
|
||||
|
||||
/* Define if you have alloca, as a function or macro. */
|
||||
/* #undef HAVE_ALLOCA */
|
||||
|
||||
/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
|
||||
/* #undef HAVE_ALLOCA_H */
|
||||
|
||||
/* Define to 1 if you have the declaration of 'getloadavg'. */
|
||||
/* #undef HAVE_DECL_GETLOADAVG */
|
||||
|
||||
/* Define if your system has a working fnmatch function. */
|
||||
/* #undef HAVE_FNMATCH */
|
||||
|
||||
/* Define if you have the getmntent function. */
|
||||
/* #undef HAVE_GETMNTENT */
|
||||
|
||||
/* Embed GNU Guile support */
|
||||
/* #undef HAVE_GUILE */
|
||||
|
||||
/* Define if the 'long double' type works. */
|
||||
/* #undef HAVE_LONG_DOUBLE */
|
||||
|
||||
/* Define if you support file names longer than 14 characters. */
|
||||
#define HAVE_LONG_FILE_NAMES 1
|
||||
|
||||
/* Define if you have a working 'mmap' system call. */
|
||||
/* #undef HAVE_MMAP */
|
||||
|
||||
/* Define if system calls automatically restart after interruption
|
||||
by a signal. */
|
||||
/* #undef HAVE_RESTARTABLE_SYSCALLS */
|
||||
|
||||
/* Define if your struct stat has st_blksize. */
|
||||
/* #undef HAVE_ST_BLKSIZE */
|
||||
|
||||
/* Define if your struct stat has st_blocks. */
|
||||
/* #undef HAVE_ST_BLOCKS */
|
||||
|
||||
/* Define if you have the strcoll function and it is properly defined. */
|
||||
#define HAVE_STRCOLL 1
|
||||
|
||||
/* Define if your struct stat has st_rdev. */
|
||||
#define HAVE_ST_RDEV 1
|
||||
|
||||
/* Define if you have the strftime function. */
|
||||
#define HAVE_STRFTIME 1
|
||||
|
||||
/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
|
||||
/* #undef HAVE_SYS_WAIT_H */
|
||||
|
||||
/* Define if your struct tm has tm_zone. */
|
||||
/* #undef HAVE_TM_ZONE */
|
||||
|
||||
/* Define if you don't have tm_zone but do have the external array
|
||||
tzname. */
|
||||
#define HAVE_TZNAME 1
|
||||
|
||||
/* Define if you have <unistd.h>. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Define if utime(file, NULL) sets file's timestamp to the present. */
|
||||
/* #undef HAVE_UTIME_NULL */
|
||||
|
||||
/* Define if you have the wait3 system call. */
|
||||
/* #undef HAVE_WAIT3 */
|
||||
|
||||
/* Define if on MINIX. */
|
||||
/* #undef _MINIX */
|
||||
|
||||
/* Define if your struct nlist has an n_un member. */
|
||||
/* #undef NLIST_NAME_UNION */
|
||||
|
||||
/* Define if you have <nlist.h>. */
|
||||
/* #undef NLIST_STRUCT */
|
||||
|
||||
/* Define if your C compiler doesn't accept -c and -o together. */
|
||||
/* #undef NO_MINUS_C_MINUS_O */
|
||||
|
||||
/* Define to 'int' if <sys/types.h> doesn't define. */
|
||||
#define pid_t int
|
||||
|
||||
/* Define if the system does not provide POSIX.1 features except
|
||||
with this defined. */
|
||||
/* #undef _POSIX_1_SOURCE */
|
||||
|
||||
/* Define if you need to in order for stat and other things to work. */
|
||||
/* #undef _POSIX_SOURCE */
|
||||
|
||||
/* If using the C implementation of alloca, define if you know the
|
||||
direction of stack growth for your system; otherwise it will be
|
||||
automatically deduced at run-time.
|
||||
STACK_DIRECTION > 0 => grows toward higher addresses
|
||||
STACK_DIRECTION < 0 => grows toward lower addresses
|
||||
STACK_DIRECTION = 0 => direction of growth unknown
|
||||
*/
|
||||
#define STACK_DIRECTION -1
|
||||
|
||||
/* Define if the 'S_IS*' macros in <sys/stat.h> do not work properly. */
|
||||
/* #undef STAT_MACROS_BROKEN */
|
||||
|
||||
/* Define if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS
|
||||
|
||||
/* Define on System V Release 4. */
|
||||
/* #undef SVR4 */
|
||||
|
||||
/* Define if 'sys_siglist' is declared by <signal.h>. */
|
||||
/* #undef SYS_SIGLIST_DECLARED */
|
||||
|
||||
/* Define to 'int' if <sys/types.h> doesn't define. */
|
||||
#define uid_t int
|
||||
|
||||
/* Define for Encore UMAX. */
|
||||
/* #undef UMAX */
|
||||
|
||||
/* Define for Encore UMAX 4.3 that has <inq_status/cpustats.h>
|
||||
instead of <sys/cpustats.h>. */
|
||||
/* #undef UMAX4_3 */
|
||||
|
||||
/* Name of this package (needed by automake) */
|
||||
#define PACKAGE "%PACKAGE%"
|
||||
|
||||
/* Version of this package (needed by automake) */
|
||||
#define VERSION "%VERSION%"
|
||||
|
||||
/* Define to the name of the SCCS 'get' command. */
|
||||
#define SCCS_GET "get"
|
||||
|
||||
/* Define this if the SCCS 'get' command understands the '-G<file>' option. */
|
||||
/* #undef SCCS_GET_MINUS_G */
|
||||
|
||||
/* Define this to enable job server support in GNU make. */
|
||||
/* #undef MAKE_JOBSERVER */
|
||||
|
||||
/* Define to be the nanoseconds member of struct stat's st_mtim,
|
||||
if it exists. */
|
||||
/* #undef ST_MTIM_NSEC */
|
||||
|
||||
/* Define this if the C library defines the variable 'sys_siglist'. */
|
||||
/* #undef HAVE_SYS_SIGLIST */
|
||||
|
||||
/* Define this if the C library defines the variable '_sys_siglist'. */
|
||||
/* #undef HAVE__SYS_SIGLIST */
|
||||
|
||||
/* Define this if you have the 'union wait' type in <sys/wait.h>. */
|
||||
/* #undef HAVE_UNION_WAIT */
|
||||
|
||||
/* Define if you have the dup2 function. */
|
||||
/* #undef HAVE_DUP2 */
|
||||
|
||||
/* Define if you have the getcwd function. */
|
||||
#define HAVE_GETCWD 1
|
||||
|
||||
/* Define if you have the getgroups function. */
|
||||
/* #undef HAVE_GETGROUPS */
|
||||
|
||||
/* Define if you have the gethostbyname function. */
|
||||
/* #undef HAVE_GETHOSTBYNAME */
|
||||
|
||||
/* Define if you have the gethostname function. */
|
||||
/* #undef HAVE_GETHOSTNAME */
|
||||
|
||||
/* Define if you have the memmove function. */
|
||||
#define HAVE_MEMMOVE 1
|
||||
|
||||
/* Define if you have the mktemp function. */
|
||||
#define HAVE_MKTEMP 1
|
||||
|
||||
/* Define if you have the psignal function. */
|
||||
/* #undef HAVE_PSIGNAL */
|
||||
|
||||
/* Define if you have the pstat_getdynamic function. */
|
||||
/* #undef HAVE_PSTAT_GETDYNAMIC */
|
||||
|
||||
/* Define if you have the setegid function. */
|
||||
/* #undef HAVE_SETEGID */
|
||||
|
||||
/* Define if you have the seteuid function. */
|
||||
/* #undef HAVE_SETEUID */
|
||||
|
||||
/* Define if you have the setlinebuf function. */
|
||||
/* #undef HAVE_SETLINEBUF */
|
||||
|
||||
/* Define if you have the setregid function. */
|
||||
/* #undef HAVE_SETREGID */
|
||||
|
||||
/* Define if you have the setreuid function. */
|
||||
/* #undef HAVE_SETREUID */
|
||||
|
||||
/* Define if you have the sigsetmask function. */
|
||||
/* #undef HAVE_SIGSETMASK */
|
||||
|
||||
/* Define if you have the socket function. */
|
||||
/* #undef HAVE_SOCKET */
|
||||
|
||||
/* Define to 1 if you have the strcasecmp function. */
|
||||
/* #undef HAVE_STRCASECMP */
|
||||
|
||||
/* Define to 1 if you have the strcmpi function. */
|
||||
/* #undef HAVE_STRCMPI */
|
||||
|
||||
/* Define to 1 if you have the stricmp function. */
|
||||
/* #undef HAVE_STRICMP */
|
||||
|
||||
/* Define if you have the strsignal function. */
|
||||
/* #undef HAVE_STRSIGNAL */
|
||||
|
||||
/* Define if you have the strtoll function. */
|
||||
/* #undef HAVE_STRTOLL */
|
||||
|
||||
/* Define if you have the wait3 function. */
|
||||
/* #undef HAVE_WAIT3 */
|
||||
|
||||
/* Define if you have the waitpid function. */
|
||||
/* #undef HAVE_WAITPID */
|
||||
|
||||
/* Define if you have the <dirent.h> header file. */
|
||||
#define HAVE_DIRENT_H 1
|
||||
|
||||
/* Define if you have the <fcntl.h> header file. */
|
||||
#define HAVE_FCNTL_H 1
|
||||
|
||||
/* Define if you have the <limits.h> header file. */
|
||||
#define HAVE_LIMITS_H 1
|
||||
|
||||
/* Define if you have the <mach/mach.h> header file. */
|
||||
/* #undef HAVE_MACH_MACH_H */
|
||||
|
||||
/* Define if you have the <memory.h> header file. */
|
||||
/* #undef HAVE_MEMORY_H */
|
||||
|
||||
/* Define if you have the <ndir.h> header file. */
|
||||
/* #undef HAVE_NDIR_H */
|
||||
|
||||
/* Define if you have the <stdlib.h> header file. */
|
||||
/* #undef HAVE_STDLIB_H */
|
||||
|
||||
/* Define if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define if you have the <sys/dir.h> header file. */
|
||||
#define HAVE_SYS_DIR_H 1
|
||||
|
||||
/* Define if you have the <sys/ndir.h> header file. */
|
||||
/* #undef HAVE_SYS_NDIR_H */
|
||||
|
||||
/* Define if you have the <sys/param.h> header file. */
|
||||
/* #undef HAVE_SYS_PARAM_H */
|
||||
|
||||
/* Define if you have the <sys/timeb.h> header file. */
|
||||
/* #undef HAVE_SYS_TIMEB_H */
|
||||
|
||||
/* Define if you have the <sys/wait.h> header file. */
|
||||
/* #undef HAVE_SYS_WAIT_H */
|
||||
|
||||
/* Define if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Define if you have the dgc library (-ldgc). */
|
||||
/* #undef HAVE_LIBDGC */
|
||||
|
||||
/* Define if you have the kstat library (-lkstat). */
|
||||
/* #undef HAVE_LIBKSTAT */
|
||||
|
||||
/* Define to 1 if you have the `isatty' function. */
|
||||
/* #undef HAVE_ISATTY */
|
||||
|
||||
/* Define to 1 if you have the `ttyname' function. */
|
||||
/* #undef HAVE_TTYNAME */
|
||||
|
||||
/* Define if you have the sun library (-lsun). */
|
||||
/* #undef HAVE_LIBSUN */
|
||||
|
||||
/* Output sync support */
|
||||
#define NO_OUTPUT_SYNC
|
||||
|
||||
/* Define for Case Insensitive behavior */
|
||||
#define HAVE_CASE_INSENSITIVE_FS
|
||||
|
||||
/* Build host information. */
|
||||
#define MAKE_HOST "Amiga"
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
#define ssize_t int
|
@ -1,6 +1,6 @@
|
||||
/* config.h-vms. Generated by hand by Klaus Kämpf <kkaempf@rmi.de> -*-C-*-
|
||||
|
||||
Copyright (C) 1996-2022 Free Software Foundation, Inc.
|
||||
Copyright (C) 1996-2024 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
@ -13,10 +13,11 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* config.h. Generated automatically by configure. */
|
||||
/* config.h.in. Generated automatically from configure.ac by autoheader. */
|
||||
#include "mkconfig.h"
|
||||
|
||||
#define MK_OS_VMS 1
|
||||
|
||||
/* Pull in types.h here to get __CRTL_VER defined for old versions of the
|
||||
compiler which don't define it. */
|
||||
@ -65,6 +66,10 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
/* Define for DGUX with <sys/dg_sys_info.h>. */
|
||||
/* #undef DGUX */
|
||||
|
||||
/* Define to the widest signed integer type if <stdint.h> and <inttypes.h> do
|
||||
not define. */
|
||||
#define intmax_t unsigned long
|
||||
|
||||
/* Define to 'unsigned long' or 'unsigned long long'
|
||||
if <inttypes.h> doesn't define. */
|
||||
#define uintmax_t unsigned long
|
||||
@ -202,31 +207,13 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
instead of <sys/cpustats.h>. */
|
||||
/* #undef UMAX4_3 */
|
||||
|
||||
/* Name of this package (needed by automake) */
|
||||
#define PACKAGE "%PACKAGE%"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT "bug-make@gnu.org"
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "GNU make"
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#define PACKAGE_URL "https://www.gnu.org/software/make/"
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "%VERSION%"
|
||||
|
||||
/* Version of this package (needed by automake) */
|
||||
#define VERSION "%VERSION%"
|
||||
|
||||
/* Define to the name of the SCCS 'get' command. */
|
||||
/* #undef SCCS_GET */
|
||||
|
||||
/* Define this if the SCCS 'get' command understands the '-G<file>' option. */
|
||||
/* #undef SCCS_GET_MINUS_G */
|
||||
|
||||
/* Define this to enable job server support in GNU make. */
|
||||
/* Define this to enable job server support in GNU Make. */
|
||||
/* #undef MAKE_JOBSERVER */
|
||||
|
||||
/* Define to be the nanoseconds member of struct stat's st_mtim,
|
||||
@ -352,11 +339,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||
/* #undef HAVE_SYS_PARAM_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/timeb.h> header file. */
|
||||
#ifndef __GNUC__
|
||||
#define HAVE_SYS_TIMEB_H 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have the <sys/wait.h> header file. */
|
||||
/* #undef HAVE_SYS_WAIT_H */
|
||||
|
||||
@ -441,3 +423,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Build host information. */
|
||||
#define MAKE_HOST "VMS"
|
||||
|
||||
/* Include customized declarations. */
|
||||
#include "../src/mkcustom.h"
|
@ -1,6 +1,6 @@
|
||||
/* config.h.W32 -- hand-massaged config.h file for Windows builds -*-C-*-
|
||||
|
||||
Copyright (C) 1996-2022 Free Software Foundation, Inc.
|
||||
Copyright (C) 1996-2024 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
@ -13,7 +13,12 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "mkconfig.h"
|
||||
|
||||
/* Build for the Windows32 API. */
|
||||
#define MK_OS_W32 1
|
||||
|
||||
/* Suppress some Visual C++ warnings.
|
||||
Maybe after the code cleanup for ISO C we can remove some/all of these. */
|
||||
@ -104,7 +109,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
# define HAVE_DIRECT_H 1
|
||||
#endif
|
||||
|
||||
/* Use platform specific coding */
|
||||
/* Support DOS-style pathnames. */
|
||||
#define HAVE_DOS_PATHS 1
|
||||
|
||||
/* Define to 1 if you have the 'dup' function. */
|
||||
@ -177,6 +182,9 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
/* Define to 1 if you have the <locale.h> header file. */
|
||||
/* #undef HAVE_LOCALE_H */
|
||||
|
||||
/* Define to 1 if the system has the type 'long long int'. */
|
||||
#define HAVE_LONG_LONG_INT 1
|
||||
|
||||
/* Define to 1 if you have the 'lstat' function. */
|
||||
/* #undef HAVE_LSTAT */
|
||||
|
||||
@ -334,6 +342,14 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Define to 1 if you have the `strtoll' function. */
|
||||
#define HAVE_STRTOLL 1
|
||||
#ifdef __TINYC__
|
||||
# ifndef strtoll
|
||||
# define strtoll _strtoi64
|
||||
# endif
|
||||
# ifndef strtoull
|
||||
# define strtoull _strtoui64
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Define to 1 if `d_type' is a member of `struct dirent'. */
|
||||
/* SV 57152: MinGW64 version of dirent doesn't support d_type. */
|
||||
@ -372,9 +388,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/timeb.h> header file. */
|
||||
#define HAVE_SYS_TIMEB_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#ifdef __MINGW32__
|
||||
#define HAVE_SYS_TIME_H 1
|
||||
@ -390,6 +403,9 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
#define HAVE_TTYNAME 1
|
||||
char *ttyname (int);
|
||||
|
||||
/* Define to 1 if the system has the type `intmax_t'. */
|
||||
#define HAVE_INTMAX_T 1
|
||||
|
||||
/* Define to 1 if the system has the type `uintmax_t'. */
|
||||
#define HAVE_UINTMAX_T 1
|
||||
|
||||
@ -436,10 +452,10 @@ char *ttyname (int);
|
||||
/* Build host information. */
|
||||
#define MAKE_HOST "Windows32"
|
||||
|
||||
/* Define to 1 to enable job server support in GNU make. */
|
||||
/* Define to 1 to enable job server support in GNU Make. */
|
||||
#define MAKE_JOBSERVER 1
|
||||
|
||||
/* Define to 1 to enable 'load' support in GNU make. */
|
||||
/* Define to 1 to enable 'load' support in GNU Make. */
|
||||
#define MAKE_LOAD 1
|
||||
|
||||
/* Define to 1 to enable symbolic link timestamp checking. */
|
||||
@ -455,21 +471,6 @@ char *ttyname (int);
|
||||
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
|
||||
/* #undef NO_MINUS_C_MINUS_O */
|
||||
|
||||
/* Name of this package (needed by automake) */
|
||||
#define PACKAGE "%PACKAGE%"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT "bug-make@gnu.org"
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "GNU make"
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#define PACKAGE_URL "https://www.gnu.org/software/make/"
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "%VERSION%"
|
||||
|
||||
/* Define to the character that separates directories in PATH. */
|
||||
#define PATH_SEPARATOR_CHAR ';'
|
||||
|
||||
@ -506,9 +507,6 @@ char *ttyname (int);
|
||||
<sys/cpustats.h>. */
|
||||
/* #undef UMAX4_3 */
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "%VERSION%"
|
||||
|
||||
/* Define if using the dmalloc debugging malloc package */
|
||||
/* #undef WITH_DMALLOC */
|
||||
|
||||
@ -547,6 +545,14 @@ char *ttyname (int);
|
||||
# define __USE_MINGW_ANSI_STDIO 1
|
||||
#endif
|
||||
|
||||
/* Number of bits in a timestamp, on hosts where this is settable. */
|
||||
/* #undef _TIME_BITS */
|
||||
|
||||
/* For 64-bit time_t on 32-bit mingw. */
|
||||
#ifdef __MINGW32__
|
||||
# define __MINGW_USE_VC2005_COMPAT 1
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
/* Define to 'int' if <sys/types.h> doesn't define. */
|
||||
@ -568,9 +574,10 @@ char *ttyname (int);
|
||||
/* Define to 'int' if <sys/types.h> doesn't define. */
|
||||
#define uid_t int
|
||||
|
||||
/* Define uintmax_t if not defined in <stdint.h> or <inttypes.h>. */
|
||||
/* Define {u,}intmax_t if not defined in <stdint.h> or <inttypes.h>. */
|
||||
#if !HAVE_STDINT_H && !HAVE_INTTYPES_H
|
||||
#define uintmax_t unsigned long
|
||||
#define intmax_t long long
|
||||
#define uintmax_t unsigned long long
|
||||
#endif
|
||||
|
||||
/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
|
||||
@ -617,3 +624,6 @@ char *ttyname (int);
|
||||
#ifdef HAVE_CYGWIN_SHELL
|
||||
#undef BATCH_MODE_ONLY_SHELL
|
||||
#endif
|
||||
|
||||
/* Include customized declarations. */
|
||||
#include "../src/mkcustom.h"
|
@ -1,6 +1,6 @@
|
||||
/* configh.dos -- hand-massaged config.h file for MS-DOS builds -*-C-*-
|
||||
|
||||
Copyright (C) 1994-2022 Free Software Foundation, Inc.
|
||||
Copyright (C) 1994-2024 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
@ -13,7 +13,11 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "mkconfig.h"
|
||||
|
||||
#define MK_OS_DOS 1
|
||||
|
||||
/* Include this header to make __DJGPP_MINOR__ available because DJGPP ports
|
||||
of GCC 4.3.0 and later no longer do it automatically. */
|
||||
@ -49,6 +53,9 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
/* Define to 1 if you have the 'getgroups' function. */
|
||||
#define HAVE_GETGROUPS 1
|
||||
|
||||
/* Define to 1 if the system has the type 'long long int'. */
|
||||
#define HAVE_LONG_LONG_INT 1
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
@ -66,13 +73,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define SCCS_GET "get"
|
||||
|
||||
/* Define to 'unsigned long' or 'unsigned long long'
|
||||
if <inttypes.h> doesn't define. */
|
||||
#define uintmax_t unsigned long long
|
||||
|
||||
/* Define the type of the first arg to select(). */
|
||||
#define fd_set_size_t int
|
||||
|
||||
/* Define to 1 if you have the select function. */
|
||||
#define HAVE_SELECT 1
|
||||
|
||||
@ -82,35 +82,33 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
/* Define to 1 if you have the 'strncasecmp' function. */
|
||||
#define HAVE_STRNCASECMP 1
|
||||
|
||||
/* Name of the package */
|
||||
#define PACKAGE "%PACKAGE%"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT "bug-%PACKAGE%@gnu.org"
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "GNU %PACKAGE%"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "GNU %PACKAGE% %VERSION%"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "%PACKAGE%"
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "%VERSION%"
|
||||
/* Define to 1 if you have the `strtoll' function. */
|
||||
#define HAVE_STRTOLL 1
|
||||
|
||||
/* Output sync support */
|
||||
#define NO_OUTPUT_SYNC
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "%VERSION%"
|
||||
#define NO_OUTPUT_SYNC 1
|
||||
|
||||
/* Build host information. */
|
||||
#define MAKE_HOST "i386-pc-msdosdjgpp"
|
||||
|
||||
/* Grok DOS paths (drive specs and backslash path element separators) */
|
||||
#define HAVE_DOS_PATHS
|
||||
#define HAVE_DOS_PATHS 1
|
||||
|
||||
/* Define the type of the first arg to select(). */
|
||||
#define fd_set_size_t int
|
||||
|
||||
/* Define to the widest signed integer type if <stdint.h> and <inttypes.h> do
|
||||
not define. */
|
||||
#define intmax_t long long
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
#if __DJGPP__ == 2 && __DJGPP_MINOR__ < 5
|
||||
#define ssize_t int
|
||||
#endif
|
||||
|
||||
/* Define to 'unsigned long' or 'unsigned long long'
|
||||
if <inttypes.h> doesn't define. */
|
||||
#define uintmax_t unsigned long long
|
||||
|
||||
/* Include customized declarations. */
|
||||
#include "../src/mkcustom.h"
|
@ -1,5 +1,5 @@
|
||||
/* Debugging macros and interface.
|
||||
Copyright (C) 1999-2022 Free Software Foundation, Inc.
|
||||
Copyright (C) 1999-2024 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
@ -12,7 +12,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#define DB_NONE (0x000)
|
||||
#define DB_BASIC (0x001)
|
||||
|
122
src/default.c
122
src/default.c
@ -1,5 +1,5 @@
|
||||
/* Data base of default implicit rules for GNU Make.
|
||||
Copyright (C) 1988-2022 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988-2024 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
@ -12,7 +12,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "makeint.h"
|
||||
|
||||
@ -27,7 +27,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Define GCC_IS_NATIVE if gcc is the native development environment on
|
||||
your system (gcc/bison/flex vs cc/yacc/lex). */
|
||||
#if defined(__MSDOS__) || defined(__EMX__)
|
||||
#if MK_OS_DOS || MK_OS_OS2
|
||||
# define GCC_IS_NATIVE
|
||||
#endif
|
||||
|
||||
@ -36,14 +36,14 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
'.s' must come last, so that a '.o' file will be made from
|
||||
a '.c' or '.p' or ... file rather than from a .s file. */
|
||||
|
||||
static char default_suffixes[]
|
||||
#ifdef VMS
|
||||
static const char default_suffixes[]
|
||||
#if MK_OS_VMS
|
||||
/* VMS should include all UNIX/POSIX + some VMS extensions */
|
||||
= ".out .exe .a .olb .hlb .tlb .mlb .ln .o .obj .c .cxx .cc .cpp .pas .p \
|
||||
.for .f .r .y .l .ym .yl .mar .s .ss .i .ii .mod .sym .def .h .info .dvi \
|
||||
.tex .texinfo .texi .txinfo .mem .hlp .brn .rnh .rno .rnt .rnx .w .ch .cweb \
|
||||
.web .com .sh .elc .el";
|
||||
#elif defined(__EMX__)
|
||||
#elif MK_OS_OS2
|
||||
= ".out .a .ln .o .c .cc .C .cpp .p .f .F .m .r .y .l .ym .yl .s .S \
|
||||
.mod .sym .def .h .info .dvi .tex .texinfo .texi .txinfo \
|
||||
.w .ch .web .sh .elc .el .obj .exe .dll .lib";
|
||||
@ -53,9 +53,9 @@ static char default_suffixes[]
|
||||
.w .ch .web .sh .elc .el";
|
||||
#endif
|
||||
|
||||
static struct pspec default_pattern_rules[] =
|
||||
static const struct pspec default_pattern_rules[] =
|
||||
{
|
||||
#ifdef VMS
|
||||
#if MK_OS_VMS
|
||||
{ "(%)", "%",
|
||||
"@if f$$search(\"$@\") .eqs. \"\" then $(LIBRARY)/CREATE/"
|
||||
"$(or "
|
||||
@ -76,7 +76,7 @@ static struct pspec default_pattern_rules[] =
|
||||
/* The X.out rules are only in BSD's default set because
|
||||
BSD Make has no null-suffix rules, so 'foo.out' and
|
||||
'foo' are the same thing. */
|
||||
#ifdef VMS
|
||||
#if MK_OS_VMS
|
||||
{ "%.exe", "%",
|
||||
"$(CP) $< $@" },
|
||||
|
||||
@ -93,9 +93,9 @@ static struct pspec default_pattern_rules[] =
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
static struct pspec default_terminal_rules[] =
|
||||
static const struct pspec default_terminal_rules[] =
|
||||
{
|
||||
#ifdef VMS
|
||||
#if MK_OS_VMS
|
||||
|
||||
/* RCS. */
|
||||
{ "%", "%$$5lv", /* Multinet style */
|
||||
@ -124,13 +124,13 @@ static struct pspec default_terminal_rules[] =
|
||||
"$(GET) $(GFLAGS) $(SCCS_OUTPUT_OPTION) $<" },
|
||||
{ "%", "SCCS/s.%",
|
||||
"$(GET) $(GFLAGS) $(SCCS_OUTPUT_OPTION) $<" },
|
||||
#endif /* !VMS */
|
||||
#endif /* !MK_OS_VMS */
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
static const char *default_suffix_rules[] =
|
||||
static const char *const default_suffix_rules[] =
|
||||
{
|
||||
#ifdef VMS
|
||||
#if MK_OS_VMS
|
||||
".o",
|
||||
"$(LINK.obj) $^ $(LOADLIBES) $(LDLIBS) -o $@",
|
||||
".obj",
|
||||
@ -263,7 +263,7 @@ static const char *default_suffix_rules[] =
|
||||
".l.ln",
|
||||
"@$(RM) $*.c\n $(LEX.l) $< > $*.c\n$(LINT.c) -i $*.c -o $@\n $(RM) $*.c",
|
||||
|
||||
#else /* ! VMS */
|
||||
#else /* ! MK_OS_VMS */
|
||||
|
||||
".o",
|
||||
"$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@",
|
||||
@ -326,19 +326,19 @@ static const char *default_suffix_rules[] =
|
||||
".c.ln",
|
||||
"$(LINT.c) -C$* $<",
|
||||
".y.ln",
|
||||
#ifndef __MSDOS__
|
||||
"$(YACC.y) $< \n $(LINT.c) -C$* y.tab.c \n $(RM) y.tab.c",
|
||||
#else
|
||||
#if MK_OS_DOS
|
||||
"$(YACC.y) $< \n $(LINT.c) -C$* y_tab.c \n $(RM) y_tab.c",
|
||||
#else
|
||||
"$(YACC.y) $< \n $(LINT.c) -C$* y.tab.c \n $(RM) y.tab.c",
|
||||
#endif
|
||||
".l.ln",
|
||||
"@$(RM) $*.c\n $(LEX.l) $< > $*.c\n$(LINT.c) -i $*.c -o $@\n $(RM) $*.c",
|
||||
|
||||
".y.c",
|
||||
#ifndef __MSDOS__
|
||||
"$(YACC.y) $< \n mv -f y.tab.c $@",
|
||||
#else
|
||||
#if MK_OS_DOS
|
||||
"$(YACC.y) $< \n mv -f y_tab.c $@",
|
||||
#else
|
||||
"$(YACC.y) $< \n mv -f y.tab.c $@",
|
||||
#endif
|
||||
".l.c",
|
||||
"@$(RM) $@ \n $(LEX.l) $< > $@",
|
||||
@ -393,14 +393,14 @@ static const char *default_suffix_rules[] =
|
||||
".web.tex",
|
||||
"$(WEAVE) $<",
|
||||
|
||||
#endif /* !VMS */
|
||||
#endif /* !MK_OS_VMS */
|
||||
|
||||
0, 0,
|
||||
};
|
||||
|
||||
static const char *default_variables[] =
|
||||
static const char *const default_variables[] =
|
||||
{
|
||||
#ifdef VMS
|
||||
#if MK_OS_VMS
|
||||
#ifdef __ALPHA
|
||||
"ARCH", "ALPHA",
|
||||
#endif
|
||||
@ -515,7 +515,7 @@ static const char *default_variables[] =
|
||||
"CP", "copy",
|
||||
".LIBPATTERNS", "%.olb lib%.a",
|
||||
|
||||
#else /* !VMS */
|
||||
#else /* !MK_OS_VMS */
|
||||
|
||||
"AR", "ar",
|
||||
#ifdef _AIX
|
||||
@ -527,18 +527,24 @@ static const char *default_variables[] =
|
||||
"AS", "as",
|
||||
#ifdef GCC_IS_NATIVE
|
||||
"CC", "gcc",
|
||||
# ifdef __MSDOS__
|
||||
"CXX", "gpp", /* g++ is an invalid name on MSDOS */
|
||||
# else
|
||||
"CXX", "gcc",
|
||||
# endif /* __MSDOS__ */
|
||||
"OBJC", "gcc",
|
||||
#else
|
||||
"CC", "cc",
|
||||
"CXX", "g++",
|
||||
"OBJC", "cc",
|
||||
#endif
|
||||
|
||||
#ifdef MAKE_CXX
|
||||
"CXX", MAKE_CXX,
|
||||
#else
|
||||
# ifdef GCC_IS_NATIVE
|
||||
# ifdef MK_OS_DOS
|
||||
"CXX", "gpp", /* g++ is an invalid name on MSDOS */
|
||||
# else
|
||||
"CXX", "gcc",
|
||||
# endif /* __MSDOS__ */
|
||||
# else
|
||||
"CXX", "g++",
|
||||
# endif
|
||||
#endif
|
||||
/* This expands to $(CO) $(COFLAGS) $< $@ if $@ does not exist,
|
||||
and to the empty string if $@ does exist. */
|
||||
"CHECKOUT,v", "+$(if $(wildcard $@),,$(CO) $(COFLAGS) $< $@)",
|
||||
@ -546,17 +552,17 @@ static const char *default_variables[] =
|
||||
"COFLAGS", "",
|
||||
|
||||
"CPP", "$(CC) -E",
|
||||
#ifdef CRAY
|
||||
#ifdef CRAY
|
||||
"CF77PPFLAGS", "-P",
|
||||
"CF77PP", "/lib/cpp",
|
||||
"CFT", "cft77",
|
||||
"CF", "cf77",
|
||||
"FC", "$(CF)",
|
||||
#else /* Not CRAY. */
|
||||
#ifdef _IBMR2
|
||||
#else /* Not CRAY. */
|
||||
#ifdef _IBMR2
|
||||
"FC", "xlf",
|
||||
#else
|
||||
#ifdef __convex__
|
||||
#ifdef __convex__
|
||||
"FC", "fc",
|
||||
#else
|
||||
"FC", "f77",
|
||||
@ -576,10 +582,10 @@ static const char *default_variables[] =
|
||||
#endif
|
||||
"LINT", "lint",
|
||||
"M2C", "m2c",
|
||||
#ifdef pyr
|
||||
#ifdef pyr
|
||||
"PC", "pascal",
|
||||
#else
|
||||
#ifdef CRAY
|
||||
#ifdef CRAY
|
||||
"PC", "PASCAL",
|
||||
"SEGLDR", "segldr",
|
||||
#else
|
||||
@ -650,23 +656,21 @@ static const char *default_variables[] =
|
||||
"OUTPUT_OPTION", "-o $@",
|
||||
#endif
|
||||
|
||||
#ifdef SCCS_GET_MINUS_G
|
||||
#ifdef SCCS_GET_MINUS_G
|
||||
"SCCS_OUTPUT_OPTION", "-G$@",
|
||||
#endif
|
||||
|
||||
#if defined(_AMIGA)
|
||||
".LIBPATTERNS", "%.lib",
|
||||
#elif defined(__MSDOS__)
|
||||
#if MK_OS_DOS
|
||||
".LIBPATTERNS", "lib%.a $(DJDIR)/lib/lib%.a",
|
||||
#elif defined(__APPLE__)
|
||||
".LIBPATTERNS", "lib%.dylib lib%.a",
|
||||
#elif defined(__CYGWIN__) || defined(WINDOWS32)
|
||||
#elif defined(__CYGWIN__) || MK_OS_W32
|
||||
".LIBPATTERNS", "lib%.dll.a %.dll.a lib%.a %.lib lib%.dll %.dll",
|
||||
#else
|
||||
".LIBPATTERNS", "lib%.so lib%.a",
|
||||
#endif
|
||||
|
||||
#endif /* !VMS */
|
||||
#endif /* !MK_OS_VMS */
|
||||
/* Make this assignment to avoid undefined variable warnings. */
|
||||
GNUMAKEFLAGS_NAME, "",
|
||||
0, 0
|
||||
@ -701,9 +705,9 @@ set_default_suffixes (void)
|
||||
installed after. */
|
||||
|
||||
void
|
||||
install_default_suffix_rules (void)
|
||||
install_default_suffix_rules ()
|
||||
{
|
||||
const char **s;
|
||||
const char *const *s;
|
||||
|
||||
if (no_builtin_rules_flag)
|
||||
return;
|
||||
@ -711,14 +715,16 @@ install_default_suffix_rules (void)
|
||||
for (s = default_suffix_rules; *s != 0; s += 2)
|
||||
{
|
||||
struct file *f = enter_file (strcache_add (s[0]));
|
||||
/* This function should run before any makefile is parsed. */
|
||||
assert (f->cmds == 0);
|
||||
f->cmds = xmalloc (sizeof (struct commands));
|
||||
f->cmds->fileinfo.filenm = 0;
|
||||
f->cmds->commands = xstrdup (s[1]);
|
||||
f->cmds->command_lines = 0;
|
||||
f->cmds->recipe_prefix = RECIPEPREFIX_DEFAULT;
|
||||
f->builtin = 1;
|
||||
/* Install the default rule only if there is no user defined rule. */
|
||||
if (!f->cmds)
|
||||
{
|
||||
f->cmds = xmalloc (sizeof (struct commands));
|
||||
f->cmds->fileinfo.filenm = NULL;
|
||||
f->cmds->commands = xstrdup (s[1]);
|
||||
f->cmds->command_lines = NULL;
|
||||
f->cmds->recipe_prefix = RECIPEPREFIX_DEFAULT;
|
||||
f->builtin = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -728,7 +734,7 @@ install_default_suffix_rules (void)
|
||||
void
|
||||
install_default_implicit_rules (void)
|
||||
{
|
||||
struct pspec *p;
|
||||
const struct pspec *p;
|
||||
|
||||
if (no_builtin_rules_flag)
|
||||
return;
|
||||
@ -743,7 +749,7 @@ install_default_implicit_rules (void)
|
||||
void
|
||||
define_default_variables (void)
|
||||
{
|
||||
const char **s;
|
||||
const char *const *s;
|
||||
|
||||
if (no_builtin_variables_flag)
|
||||
return;
|
||||
@ -755,8 +761,8 @@ define_default_variables (void)
|
||||
void
|
||||
undefine_default_variables (void)
|
||||
{
|
||||
const char **s;
|
||||
const char *const *s;
|
||||
|
||||
for (s = default_variables; *s != 0; s += 2)
|
||||
undefine_variable_global (s[0], strlen (s[0]), o_default);
|
||||
undefine_variable_global (NILF, s[0], strlen (s[0]), o_default);
|
||||
}
|
||||
|
29
src/dep.h
29
src/dep.h
@ -1,5 +1,5 @@
|
||||
/* Definitions of dependency data structures for GNU Make.
|
||||
Copyright (C) 1988-2022 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988-2024 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
@ -12,7 +12,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
|
||||
/* Structure used in chains of names, for parsing and globbing. */
|
||||
@ -42,7 +42,6 @@ struct nameseq
|
||||
explicit is set when implicit rule search is performed and the prerequisite
|
||||
does not contain %. When explicit is set the file is not intermediate. */
|
||||
|
||||
|
||||
#define DEP(_t) \
|
||||
NAMESEQ (_t); \
|
||||
struct file *file; \
|
||||
@ -89,7 +88,7 @@ struct goaldep
|
||||
#define PARSE_SIMPLE_SEQ(_s,_t) \
|
||||
(_t *)parse_file_seq ((_s),sizeof (_t),MAP_NUL,NULL,PARSEFS_NONE)
|
||||
|
||||
#ifdef VMS
|
||||
#if MK_OS_VMS
|
||||
void *parse_file_seq ();
|
||||
#else
|
||||
void *parse_file_seq (char **stringp, size_t size,
|
||||
@ -102,24 +101,23 @@ char *tilde_expand (const char *name);
|
||||
struct nameseq *ar_glob (const char *arname, const char *member_pattern, size_t size);
|
||||
#endif
|
||||
|
||||
#define dep_name(d) ((d)->name ? (d)->name : (d)->file->name)
|
||||
#define dep_name(d) ((d)->name ? (d)->name : (d)->file->name)
|
||||
|
||||
#define alloc_seq_elt(_t) xcalloc (sizeof (_t))
|
||||
#define alloc_seq_elt(_t) xcalloc (sizeof (_t))
|
||||
void free_ns_chain (struct nameseq *n);
|
||||
|
||||
#if defined(MAKE_MAINTAINER_MODE) && defined(__GNUC__) && !defined(__STRICT_ANSI__)
|
||||
/* Use inline to get real type-checking. */
|
||||
#define SI static inline
|
||||
SI struct nameseq *alloc_ns() { return alloc_seq_elt (struct nameseq); }
|
||||
SI struct dep *alloc_dep() { return alloc_seq_elt (struct dep); }
|
||||
SI struct goaldep *alloc_goaldep() { return alloc_seq_elt (struct goaldep); }
|
||||
SI struct nameseq *alloc_ns (void) { return alloc_seq_elt (struct nameseq); }
|
||||
SI struct dep *alloc_dep (void) { return alloc_seq_elt (struct dep); }
|
||||
SI struct goaldep *alloc_goaldep (void) { return alloc_seq_elt (struct goaldep); }
|
||||
|
||||
SI void free_ns(struct nameseq *n) { free (n); }
|
||||
SI void free_dep(struct dep *d) { free_ns ((struct nameseq *)d); }
|
||||
SI void free_goaldep(struct goaldep *g) { free_dep ((struct dep *)g); }
|
||||
|
||||
SI void free_dep_chain(struct dep *d) { free_ns_chain((struct nameseq *)d); }
|
||||
SI void free_goal_chain(struct goaldep *g) { free_dep_chain((struct dep *)g); }
|
||||
SI void free_ns (struct nameseq *n) { free (n); }
|
||||
SI void free_dep (struct dep *d) { free_ns ((struct nameseq *)d); }
|
||||
SI void free_goaldep (struct goaldep *g) { free_dep ((struct dep *)g); }
|
||||
SI void free_dep_chain (struct dep *d) { free_ns_chain((struct nameseq *)d); }
|
||||
SI void free_goal_chain (struct goaldep *g) { free_dep_chain((struct dep *)g); }
|
||||
#else
|
||||
# define alloc_ns() alloc_seq_elt (struct nameseq)
|
||||
# define alloc_dep() alloc_seq_elt (struct dep)
|
||||
@ -133,6 +131,7 @@ SI void free_goal_chain(struct goaldep *g) { free_dep_chain((struct dep *)g); }
|
||||
# define free_goal_chain(_g) free_ns_chain ((struct nameseq *)(_g))
|
||||
#endif
|
||||
|
||||
struct dep *copy_dep (const struct dep *d);
|
||||
struct dep *copy_dep_chain (const struct dep *d);
|
||||
|
||||
struct goaldep *read_all_makefiles (const char **makefiles);
|
||||
|
341
src/dir.c
341
src/dir.c
@ -1,5 +1,5 @@
|
||||
/* Directory hashing for GNU Make.
|
||||
Copyright (C) 1988-2022 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988-2024 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
@ -12,7 +12,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "makeint.h"
|
||||
#include "hash.h"
|
||||
@ -20,10 +20,10 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
#include "dep.h"
|
||||
#include "debug.h"
|
||||
|
||||
#ifdef HAVE_DIRENT_H
|
||||
#ifdef HAVE_DIRENT_H
|
||||
# include <dirent.h>
|
||||
# define NAMLEN(dirent) strlen((dirent)->d_name)
|
||||
# ifdef VMS
|
||||
# if MK_OS_VMS
|
||||
/* its prototype is in vmsdir.h, which is not needed for HAVE_DIRENT_H */
|
||||
const char *vmsify (const char *name, int type);
|
||||
# endif
|
||||
@ -50,7 +50,7 @@ const char *vmsify (const char *name, int type);
|
||||
# define NAMLEN(d) _D_NAMLEN(d)
|
||||
#endif
|
||||
|
||||
#if (defined (POSIX) || defined (VMS) || defined (WINDOWS32)) && !defined (__GNU_LIBRARY__)
|
||||
#if (defined (POSIX) || MK_OS_VMS || MK_OS_W32) && !defined (__GNU_LIBRARY__)
|
||||
/* Posix does not require that the d_ino field be present, and some
|
||||
systems do not provide it. */
|
||||
# define REAL_DIR_ENTRY(dp) 1
|
||||
@ -60,7 +60,7 @@ const char *vmsify (const char *name, int type);
|
||||
# define FAKE_DIR_ENTRY(dp) (dp->d_ino = 1)
|
||||
#endif /* POSIX */
|
||||
|
||||
#ifdef __MSDOS__
|
||||
#if MK_OS_DOS
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
@ -76,12 +76,12 @@ dosify (const char *filename)
|
||||
char *df;
|
||||
int i;
|
||||
|
||||
if (filename == 0 || _USE_LFN)
|
||||
if (filename == NULL || _USE_LFN)
|
||||
return filename;
|
||||
|
||||
/* FIXME: what about filenames which violate
|
||||
8+3 constraints, like "config.h.in", or ".emacs"? */
|
||||
if (strpbrk (filename, "\"*+,;<=>?[\\]|") != 0)
|
||||
if (strpbrk (filename, "\"*+,;<=>?[\\]|") != NULL)
|
||||
return filename;
|
||||
|
||||
df = dos_filename;
|
||||
@ -105,19 +105,15 @@ dosify (const char *filename)
|
||||
++filename;
|
||||
if (*filename == '.')
|
||||
return filename;
|
||||
*df = 0;
|
||||
*df = '\0';
|
||||
return dos_filename;
|
||||
}
|
||||
#endif /* __MSDOS__ */
|
||||
#endif /* MK_OS_DOS */
|
||||
|
||||
#ifdef WINDOWS32
|
||||
#if MK_OS_W32
|
||||
#include "pathstuff.h"
|
||||
#endif
|
||||
|
||||
#ifdef _AMIGA
|
||||
#include <ctype.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CASE_INSENSITIVE_FS
|
||||
static const char *
|
||||
downcase (const char *filename)
|
||||
@ -125,8 +121,8 @@ downcase (const char *filename)
|
||||
static PATH_VAR (new_filename);
|
||||
char *df;
|
||||
|
||||
if (filename == 0)
|
||||
return 0;
|
||||
if (filename == NULL)
|
||||
return NULL;
|
||||
|
||||
df = new_filename;
|
||||
while (*filename != '\0')
|
||||
@ -135,13 +131,13 @@ downcase (const char *filename)
|
||||
++filename;
|
||||
}
|
||||
|
||||
*df = 0;
|
||||
*df = '\0';
|
||||
|
||||
return new_filename;
|
||||
}
|
||||
#endif /* HAVE_CASE_INSENSITIVE_FS */
|
||||
|
||||
#ifdef VMS
|
||||
#if MK_OS_VMS
|
||||
|
||||
static char *
|
||||
downcase_inplace(char *filename)
|
||||
@ -203,14 +199,14 @@ vmsstat_dir (const char *name, struct stat *st)
|
||||
DIR *dir;
|
||||
|
||||
dir = opendir (name);
|
||||
if (dir == 0)
|
||||
if (dir == NULL)
|
||||
return -1;
|
||||
closedir (dir);
|
||||
s = strchr (name, ':'); /* find device */
|
||||
if (s)
|
||||
{
|
||||
/* to keep the compiler happy we said "const char *name", now we cheat */
|
||||
*s++ = 0;
|
||||
*s++ = '\0';
|
||||
st->st_dev = (char *)vms_hash (name);
|
||||
h = vms_hash (s);
|
||||
*(s-1) = ':';
|
||||
@ -231,7 +227,7 @@ vmsstat_dir (const char *name, struct stat *st)
|
||||
# define stat(__path, __sbuf) vmsstat_dir (__path, __sbuf)
|
||||
|
||||
#endif /* _USE_STD_STAT */
|
||||
#endif /* VMS */
|
||||
#endif /* MK_OS_VMS */
|
||||
|
||||
/* Never have more than this many directories open at once. */
|
||||
|
||||
@ -248,8 +244,8 @@ static unsigned int open_directories = 0;
|
||||
struct directory_contents
|
||||
{
|
||||
dev_t dev; /* Device and inode numbers of this dir. */
|
||||
#ifdef WINDOWS32
|
||||
/* Inode means nothing on WINDOWS32. Even file key information is
|
||||
#if MK_OS_W32
|
||||
/* Inode means nothing on Windows32. Even file key information is
|
||||
* unreliable because it is random per file open and undefined for remote
|
||||
* filesystems. The most unique attribute I can come up with is the fully
|
||||
* qualified name of the directory. Beware though, this is also
|
||||
@ -262,12 +258,12 @@ struct directory_contents
|
||||
# define FS_NTFS 0x2
|
||||
# define FS_UNKNOWN 0x4
|
||||
#else
|
||||
# ifdef VMS_INO_T
|
||||
# if MK_OS_VMS_INO_T
|
||||
ino_t ino[3];
|
||||
# else
|
||||
ino_t ino;
|
||||
# endif
|
||||
#endif /* WINDOWS32 */
|
||||
#endif /* MK_OS_W32 */
|
||||
struct hash_table dirfiles; /* Files in this directory. */
|
||||
unsigned long counter; /* command_count value when last read. */
|
||||
DIR *dirstream; /* Stream reading this directory. */
|
||||
@ -281,9 +277,10 @@ clear_directory_contents (struct directory_contents *dc)
|
||||
{
|
||||
--open_directories;
|
||||
closedir (dc->dirstream);
|
||||
dc->dirstream = 0;
|
||||
dc->dirstream = NULL;
|
||||
}
|
||||
hash_free (&dc->dirfiles, 1);
|
||||
if (dc->dirfiles.ht_vec != NULL)
|
||||
hash_free (&dc->dirfiles, 1);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@ -294,12 +291,12 @@ directory_contents_hash_1 (const void *key_0)
|
||||
const struct directory_contents *key = key_0;
|
||||
unsigned long hash;
|
||||
|
||||
#ifdef WINDOWS32
|
||||
#if MK_OS_W32
|
||||
hash = 0;
|
||||
ISTRING_HASH_1 (key->path_key, hash);
|
||||
hash ^= ((unsigned int) key->dev << 4) ^ (unsigned int) key->ctime;
|
||||
#else
|
||||
# ifdef VMS_INO_T
|
||||
# if MK_OS_VMS_INO_T
|
||||
hash = (((unsigned int) key->dev << 4)
|
||||
^ ((unsigned int) key->ino[0]
|
||||
+ (unsigned int) key->ino[1]
|
||||
@ -307,7 +304,7 @@ directory_contents_hash_1 (const void *key_0)
|
||||
# else
|
||||
hash = ((unsigned int) key->dev << 4) ^ (unsigned int) key->ino;
|
||||
# endif
|
||||
#endif /* WINDOWS32 */
|
||||
#endif /* MK_OS_W32 */
|
||||
return hash;
|
||||
}
|
||||
|
||||
@ -317,12 +314,12 @@ directory_contents_hash_2 (const void *key_0)
|
||||
const struct directory_contents *key = key_0;
|
||||
unsigned long hash;
|
||||
|
||||
#ifdef WINDOWS32
|
||||
#if MK_OS_W32
|
||||
hash = 0;
|
||||
ISTRING_HASH_2 (key->path_key, hash);
|
||||
hash ^= ((unsigned int) key->dev << 4) ^ (unsigned int) ~key->ctime;
|
||||
#else
|
||||
# ifdef VMS_INO_T
|
||||
# if MK_OS_VMS_INO_T
|
||||
hash = (((unsigned int) key->dev << 4)
|
||||
^ ~((unsigned int) key->ino[0]
|
||||
+ (unsigned int) key->ino[1]
|
||||
@ -330,7 +327,7 @@ directory_contents_hash_2 (const void *key_0)
|
||||
# else
|
||||
hash = ((unsigned int) key->dev << 4) ^ (unsigned int) ~key->ino;
|
||||
# endif
|
||||
#endif /* WINDOWS32 */
|
||||
#endif /* MK_OS_W32 */
|
||||
|
||||
return hash;
|
||||
}
|
||||
@ -353,7 +350,7 @@ directory_contents_hash_cmp (const void *xv, const void *yv)
|
||||
const struct directory_contents *y = yv;
|
||||
int result;
|
||||
|
||||
#ifdef WINDOWS32
|
||||
#if MK_OS_W32
|
||||
ISTRING_COMPARE (x->path_key, y->path_key, result);
|
||||
if (result)
|
||||
return result;
|
||||
@ -361,7 +358,7 @@ directory_contents_hash_cmp (const void *xv, const void *yv)
|
||||
if (result)
|
||||
return result;
|
||||
#else
|
||||
# ifdef VMS_INO_T
|
||||
# if MK_OS_VMS_INO_T
|
||||
result = MAKECMP(x->ino[0], y->ino[0]);
|
||||
if (result)
|
||||
return result;
|
||||
@ -376,7 +373,7 @@ directory_contents_hash_cmp (const void *xv, const void *yv)
|
||||
if (result)
|
||||
return result;
|
||||
# endif
|
||||
#endif /* WINDOWS32 */
|
||||
#endif /* MK_OS_W32 */
|
||||
|
||||
return MAKECMP(x->dev, y->dev);
|
||||
}
|
||||
@ -456,7 +453,7 @@ dirfile_hash_cmp (const void *xv, const void *yv)
|
||||
#define DIRFILE_BUCKETS 107
|
||||
#endif
|
||||
|
||||
static int dir_contents_file_exists_p (struct directory_contents *dir,
|
||||
static int dir_contents_file_exists_p (struct directory *dir,
|
||||
const char *filename);
|
||||
static struct directory *find_directory (const char *name);
|
||||
|
||||
@ -474,7 +471,7 @@ find_directory (const char *name)
|
||||
|
||||
struct stat st;
|
||||
int r;
|
||||
#ifdef WINDOWS32
|
||||
#if MK_OS_W32
|
||||
char *w32_path;
|
||||
#endif
|
||||
|
||||
@ -502,7 +499,7 @@ find_directory (const char *name)
|
||||
size_t len = strlen (name);
|
||||
|
||||
dir = xmalloc (sizeof (struct directory));
|
||||
#if defined(HAVE_CASE_INSENSITIVE_FS) && defined(VMS)
|
||||
#if defined(HAVE_CASE_INSENSITIVE_FS) && MK_OS_VMS
|
||||
/* Todo: Why is this only needed on VMS? */
|
||||
{
|
||||
char *lname = downcase_inplace (xstrdup (name));
|
||||
@ -519,9 +516,9 @@ find_directory (const char *name)
|
||||
dir->counter = command_count;
|
||||
|
||||
/* See if the directory exists. */
|
||||
#if defined(WINDOWS32)
|
||||
#if MK_OS_W32
|
||||
{
|
||||
char tem[MAXPATHLEN], *tstart, *tend;
|
||||
char tem[MAX_PATH+1], *tstart, *tend;
|
||||
size_t len = strlen (name);
|
||||
|
||||
/* Remove any trailing slashes. Windows32 stat fails even on
|
||||
@ -530,9 +527,7 @@ find_directory (const char *name)
|
||||
tstart = tem;
|
||||
if (tstart[1] == ':')
|
||||
tstart += 2;
|
||||
for (tend = tem + (len - 1);
|
||||
tend > tstart && (*tend == '/' || *tend == '\\');
|
||||
tend--)
|
||||
for (tend = tem + (len - 1); tend > tstart && ISDIRSEP (*tend); tend--)
|
||||
*tend = '\0';
|
||||
|
||||
r = stat (tem, &st);
|
||||
@ -549,11 +544,11 @@ find_directory (const char *name)
|
||||
|
||||
memset (&dc_key, '\0', sizeof (dc_key));
|
||||
dc_key.dev = st.st_dev;
|
||||
#ifdef WINDOWS32
|
||||
#if MK_OS_W32
|
||||
dc_key.path_key = w32_path = w32ify (name, 1);
|
||||
dc_key.ctime = st.st_ctime;
|
||||
#else
|
||||
# ifdef VMS_INO_T
|
||||
# if MK_OS_VMS_INO_T
|
||||
dc_key.ino[0] = st.st_ino[0];
|
||||
dc_key.ino[1] = st.st_ino[1];
|
||||
dc_key.ino[2] = st.st_ino[2];
|
||||
@ -567,7 +562,7 @@ find_directory (const char *name)
|
||||
if (HASH_VACANT (dc))
|
||||
{
|
||||
/* Nope; this really is a directory we haven't seen before. */
|
||||
#ifdef WINDOWS32
|
||||
#if MK_OS_W32
|
||||
char fs_label[BUFSIZ];
|
||||
char fs_type[BUFSIZ];
|
||||
unsigned long fs_serno;
|
||||
@ -578,11 +573,11 @@ find_directory (const char *name)
|
||||
dc = xcalloc (sizeof (struct directory_contents));
|
||||
*dc = dc_key;
|
||||
|
||||
#ifdef WINDOWS32
|
||||
#if MK_OS_W32
|
||||
dc->path_key = xstrdup (w32_path);
|
||||
dc->mtime = st.st_mtime;
|
||||
|
||||
/* NTFS is the only WINDOWS32 filesystem that bumps mtime on a
|
||||
/* NTFS is the only Windows32 filesystem that bumps mtime on a
|
||||
directory when files are added/deleted from a directory. */
|
||||
w32_path[3] = '\0';
|
||||
if (GetVolumeInformation (w32_path, fs_label, sizeof (fs_label),
|
||||
@ -595,7 +590,7 @@ find_directory (const char *name)
|
||||
dc->fs_flags = FS_NTFS;
|
||||
else
|
||||
dc->fs_flags = FS_UNKNOWN;
|
||||
#endif /* WINDOWS32 */
|
||||
#endif /* MK_OS_W32 */
|
||||
|
||||
hash_insert_at (&directory_contents, dc, dc_slot);
|
||||
}
|
||||
@ -603,7 +598,7 @@ find_directory (const char *name)
|
||||
/* Point the name-hashed entry for DIR at its contents data. */
|
||||
dir->contents = dc;
|
||||
|
||||
/* If the contents have changed, we need to reseet. */
|
||||
/* If the contents have changed, we need to reseed. */
|
||||
if (dc->counter != command_count)
|
||||
{
|
||||
if (dc->counter)
|
||||
@ -612,10 +607,9 @@ find_directory (const char *name)
|
||||
dc->counter = command_count;
|
||||
|
||||
ENULLLOOP (dc->dirstream, opendir (name));
|
||||
if (dc->dirstream == 0)
|
||||
/* Couldn't open the directory. Mark this by setting the
|
||||
'files' member to a nil pointer. */
|
||||
dc->dirfiles.ht_vec = 0;
|
||||
if (dc->dirstream == NULL)
|
||||
/* Couldn't open the directory: mark this by setting files to NULL. */
|
||||
dc->dirfiles.ht_vec = NULL;
|
||||
else
|
||||
{
|
||||
hash_init (&dc->dirfiles, DIRFILE_BUCKETS,
|
||||
@ -625,7 +619,7 @@ find_directory (const char *name)
|
||||
if (open_directories == MAX_OPEN_DIRECTORIES)
|
||||
/* We have too many directories open already.
|
||||
Read the entire directory and then close it. */
|
||||
dir_contents_file_exists_p (dc, 0);
|
||||
dir_contents_file_exists_p (dir, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@ -636,21 +630,22 @@ find_directory (const char *name)
|
||||
FILENAME must contain no slashes. */
|
||||
|
||||
static int
|
||||
dir_contents_file_exists_p (struct directory_contents *dir,
|
||||
dir_contents_file_exists_p (struct directory *dir,
|
||||
const char *filename)
|
||||
{
|
||||
struct dirfile *df;
|
||||
struct dirent *d;
|
||||
#ifdef WINDOWS32
|
||||
struct directory_contents *dc = dir->contents;
|
||||
#if MK_OS_W32
|
||||
struct stat st;
|
||||
int rehash = 0;
|
||||
#endif
|
||||
|
||||
if (dir == 0 || dir->dirfiles.ht_vec == 0)
|
||||
if (dc == NULL || dc->dirfiles.ht_vec == NULL)
|
||||
/* The directory could not be stat'd or opened. */
|
||||
return 0;
|
||||
|
||||
#ifdef __MSDOS__
|
||||
#if MK_OS_DOS
|
||||
filename = dosify (filename);
|
||||
#endif
|
||||
|
||||
@ -658,11 +653,17 @@ dir_contents_file_exists_p (struct directory_contents *dir,
|
||||
filename = downcase (filename);
|
||||
#endif
|
||||
|
||||
#ifdef __EMX__
|
||||
if (filename != 0)
|
||||
_fnlwr (filename); /* lower case for FAT drives */
|
||||
#if MK_OS_OS2
|
||||
if (filename != NULL)
|
||||
{
|
||||
size_t len = strlen (filename);
|
||||
char *fname = alloca (len + 1);
|
||||
memcpy (fname, filename, len + 1);
|
||||
_fnlwr (fname); /* lower case for FAT drives */
|
||||
filename = fname;
|
||||
}
|
||||
#endif
|
||||
if (filename != 0)
|
||||
if (filename != NULL)
|
||||
{
|
||||
struct dirfile dirfile_key;
|
||||
|
||||
@ -673,7 +674,7 @@ dir_contents_file_exists_p (struct directory_contents *dir,
|
||||
}
|
||||
dirfile_key.name = filename;
|
||||
dirfile_key.length = strlen (filename);
|
||||
df = hash_find_item (&dir->dirfiles, &dirfile_key);
|
||||
df = hash_find_item (&dc->dirfiles, &dirfile_key);
|
||||
if (df)
|
||||
return !df->impossible;
|
||||
}
|
||||
@ -681,25 +682,25 @@ dir_contents_file_exists_p (struct directory_contents *dir,
|
||||
/* The file was not found in the hashed list.
|
||||
Try to read the directory further. */
|
||||
|
||||
if (dir->dirstream == 0)
|
||||
if (dc->dirstream == NULL)
|
||||
{
|
||||
#ifdef WINDOWS32
|
||||
#if MK_OS_W32
|
||||
/*
|
||||
* Check to see if directory has changed since last read. FAT
|
||||
* filesystems force a rehash always as mtime does not change
|
||||
* on directories (ugh!).
|
||||
*/
|
||||
if (dir->path_key)
|
||||
if (dc->path_key)
|
||||
{
|
||||
if ((dir->fs_flags & FS_FAT) != 0)
|
||||
if ((dc->fs_flags & FS_FAT) != 0)
|
||||
{
|
||||
dir->mtime = time ((time_t *) 0);
|
||||
dc->mtime = time (NULL);
|
||||
rehash = 1;
|
||||
}
|
||||
else if (stat (dir->path_key, &st) == 0 && st.st_mtime > dir->mtime)
|
||||
else if (stat (dc->path_key, &st) == 0 && st.st_mtime > dc->mtime)
|
||||
{
|
||||
/* reset date stamp to show most recent re-process. */
|
||||
dir->mtime = st.st_mtime;
|
||||
dc->mtime = st.st_mtime;
|
||||
rehash = 1;
|
||||
}
|
||||
|
||||
@ -708,8 +709,8 @@ dir_contents_file_exists_p (struct directory_contents *dir,
|
||||
return 0;
|
||||
|
||||
/* make sure directory can still be opened; if not return. */
|
||||
dir->dirstream = opendir (dir->path_key);
|
||||
if (!dir->dirstream)
|
||||
dc->dirstream = opendir (dc->path_key);
|
||||
if (!dc->dirstream)
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
@ -725,15 +726,15 @@ dir_contents_file_exists_p (struct directory_contents *dir,
|
||||
struct dirfile dirfile_key;
|
||||
struct dirfile **dirfile_slot;
|
||||
|
||||
ENULLLOOP (d, readdir (dir->dirstream));
|
||||
if (d == 0)
|
||||
ENULLLOOP (d, readdir (dc->dirstream));
|
||||
if (d == NULL)
|
||||
{
|
||||
if (errno)
|
||||
pfatal_with_name ("INTERNAL: readdir");
|
||||
OSS (fatal, NILF, "readdir %s: %s", dir->name, strerror (errno));
|
||||
break;
|
||||
}
|
||||
|
||||
#if defined(VMS) && defined(HAVE_DIRENT_H)
|
||||
#if MK_OS_VMS && defined(HAVE_DIRENT_H)
|
||||
/* In VMS we get file versions too, which have to be stripped off.
|
||||
Some versions of VMS return versions on Unix files even when
|
||||
the feature option to strip them is set. */
|
||||
@ -749,8 +750,8 @@ dir_contents_file_exists_p (struct directory_contents *dir,
|
||||
len = NAMLEN (d);
|
||||
dirfile_key.name = d->d_name;
|
||||
dirfile_key.length = len;
|
||||
dirfile_slot = (struct dirfile **) hash_find_slot (&dir->dirfiles, &dirfile_key);
|
||||
#ifdef WINDOWS32
|
||||
dirfile_slot = (struct dirfile **) hash_find_slot (&dc->dirfiles, &dirfile_key);
|
||||
#if MK_OS_W32
|
||||
/*
|
||||
* If re-reading a directory, don't cache files that have
|
||||
* already been discovered.
|
||||
@ -759,7 +760,7 @@ dir_contents_file_exists_p (struct directory_contents *dir,
|
||||
#endif
|
||||
{
|
||||
df = xmalloc (sizeof (struct dirfile));
|
||||
#if defined(HAVE_CASE_INSENSITIVE_FS) && defined(VMS)
|
||||
#if MK_OS_VMS && defined(HAVE_CASE_INSENSITIVE_FS)
|
||||
/* TODO: Why is this only needed on VMS? */
|
||||
df->name = strcache_add_len (downcase_inplace (d->d_name), len);
|
||||
#else
|
||||
@ -770,21 +771,22 @@ dir_contents_file_exists_p (struct directory_contents *dir,
|
||||
#endif
|
||||
df->length = len;
|
||||
df->impossible = 0;
|
||||
hash_insert_at (&dir->dirfiles, df, dirfile_slot);
|
||||
hash_insert_at (&dc->dirfiles, df, dirfile_slot);
|
||||
}
|
||||
/* Check if the name matches the one we're searching for. */
|
||||
if (filename != 0 && patheq (d->d_name, filename))
|
||||
if (filename != NULL && patheq (d->d_name, filename))
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* If the directory has been completely read in,
|
||||
close the stream and reset the pointer to nil. */
|
||||
if (d == 0)
|
||||
if (d == NULL)
|
||||
{
|
||||
--open_directories;
|
||||
closedir (dir->dirstream);
|
||||
dir->dirstream = 0;
|
||||
closedir (dc->dirstream);
|
||||
dc->dirstream = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -795,16 +797,11 @@ dir_contents_file_exists_p (struct directory_contents *dir,
|
||||
int
|
||||
dir_file_exists_p (const char *dirname, const char *filename)
|
||||
{
|
||||
#ifdef VMS
|
||||
if ((filename != NULL) && (dirname != NULL))
|
||||
{
|
||||
int want_vmsify;
|
||||
want_vmsify = (strpbrk (dirname, ":<[") != NULL);
|
||||
if (want_vmsify)
|
||||
filename = vmsify (filename, 0);
|
||||
}
|
||||
#if MK_OS_VMS
|
||||
if (filename && dirname && strpbrk (dirname, ":<[") != NULL)
|
||||
filename = vmsify (filename, 0);
|
||||
#endif
|
||||
return dir_contents_file_exists_p (find_directory (dirname)->contents,
|
||||
return dir_contents_file_exists_p (find_directory (dirname),
|
||||
filename);
|
||||
}
|
||||
|
||||
@ -823,23 +820,23 @@ file_exists_p (const char *name)
|
||||
#endif
|
||||
|
||||
dirend = strrchr (name, '/');
|
||||
#ifdef VMS
|
||||
if (dirend == 0)
|
||||
#if MK_OS_VMS
|
||||
if (dirend == NULL)
|
||||
{
|
||||
dirend = strrchr (name, ']');
|
||||
dirend == NULL ? dirend : dirend++;
|
||||
}
|
||||
if (dirend == 0)
|
||||
if (dirend == NULL)
|
||||
{
|
||||
dirend = strrchr (name, '>');
|
||||
dirend == NULL ? dirend : dirend++;
|
||||
}
|
||||
if (dirend == 0)
|
||||
if (dirend == NULL)
|
||||
{
|
||||
dirend = strrchr (name, ':');
|
||||
dirend == NULL ? dirend : dirend++;
|
||||
}
|
||||
#endif /* VMS */
|
||||
#endif /* MK_OS_VMS */
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
/* Forward and backslashes might be mixed. We need the rightmost one. */
|
||||
{
|
||||
@ -851,12 +848,8 @@ file_exists_p (const char *name)
|
||||
dirend = name + 1;
|
||||
}
|
||||
#endif /* HAVE_DOS_PATHS */
|
||||
if (dirend == 0)
|
||||
#ifndef _AMIGA
|
||||
if (dirend == NULL)
|
||||
return dir_file_exists_p (".", name);
|
||||
#else /* !AMIGA */
|
||||
return dir_file_exists_p ("", name);
|
||||
#endif /* AMIGA */
|
||||
|
||||
slash = dirend;
|
||||
if (dirend == name)
|
||||
@ -867,7 +860,7 @@ file_exists_p (const char *name)
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
/* d:/ and d: are *very* different... */
|
||||
if (dirend < name + 3 && name[1] == ':' &&
|
||||
(*dirend == '/' || *dirend == '\\' || *dirend == ':'))
|
||||
(ISDIRSEP (*dirend) || *dirend == ':'))
|
||||
dirend++;
|
||||
#endif
|
||||
p = alloca (dirend - name + 1);
|
||||
@ -875,7 +868,7 @@ file_exists_p (const char *name)
|
||||
p[dirend - name] = '\0';
|
||||
dirname = p;
|
||||
}
|
||||
#ifdef VMS
|
||||
#if MK_OS_VMS
|
||||
if (*slash == '/')
|
||||
slash++;
|
||||
#else
|
||||
@ -897,7 +890,7 @@ file_impossible (const char *filename)
|
||||
struct dirfile *new;
|
||||
|
||||
dirend = strrchr (p, '/');
|
||||
#ifdef VMS
|
||||
#if MK_OS_VMS
|
||||
if (dirend == NULL)
|
||||
{
|
||||
dirend = strrchr (p, ']');
|
||||
@ -925,12 +918,8 @@ file_impossible (const char *filename)
|
||||
dirend = p + 1;
|
||||
}
|
||||
#endif /* HAVE_DOS_PATHS */
|
||||
if (dirend == 0)
|
||||
#ifdef _AMIGA
|
||||
dir = find_directory ("");
|
||||
#else /* !AMIGA */
|
||||
if (dirend == NULL)
|
||||
dir = find_directory (".");
|
||||
#endif /* AMIGA */
|
||||
else
|
||||
{
|
||||
const char *dirname;
|
||||
@ -943,7 +932,7 @@ file_impossible (const char *filename)
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
/* d:/ and d: are *very* different... */
|
||||
if (dirend < p + 3 && p[1] == ':' &&
|
||||
(*dirend == '/' || *dirend == '\\' || *dirend == ':'))
|
||||
(ISDIRSEP (*dirend) || *dirend == ':'))
|
||||
dirend++;
|
||||
#endif
|
||||
cp = alloca (dirend - p + 1);
|
||||
@ -952,7 +941,7 @@ file_impossible (const char *filename)
|
||||
dirname = cp;
|
||||
}
|
||||
dir = find_directory (dirname);
|
||||
#ifdef VMS
|
||||
#if MK_OS_VMS
|
||||
if (*slash == '/')
|
||||
filename = p = slash + 1;
|
||||
else
|
||||
@ -962,22 +951,20 @@ file_impossible (const char *filename)
|
||||
#endif
|
||||
}
|
||||
|
||||
if (dir->contents == 0)
|
||||
if (dir->contents == NULL)
|
||||
/* The directory could not be stat'd. We allocate a contents
|
||||
structure for it, but leave it out of the contents hash table. */
|
||||
dir->contents = xcalloc (sizeof (struct directory_contents));
|
||||
|
||||
if (dir->contents->dirfiles.ht_vec == 0)
|
||||
{
|
||||
hash_init (&dir->contents->dirfiles, DIRFILE_BUCKETS,
|
||||
dirfile_hash_1, dirfile_hash_2, dirfile_hash_cmp);
|
||||
}
|
||||
if (dir->contents->dirfiles.ht_vec == NULL)
|
||||
hash_init (&dir->contents->dirfiles, DIRFILE_BUCKETS,
|
||||
dirfile_hash_1, dirfile_hash_2, dirfile_hash_cmp);
|
||||
|
||||
/* Make a new entry and put it in the table. */
|
||||
|
||||
new = xmalloc (sizeof (struct dirfile));
|
||||
new->length = strlen (filename);
|
||||
#if defined(HAVE_CASE_INSENSITIVE_FS) && defined(VMS)
|
||||
#if defined(HAVE_CASE_INSENSITIVE_FS) && MK_OS_VMS
|
||||
/* todo: Why is this only needed on VMS? */
|
||||
new->name = strcache_add_len (downcase (filename), new->length);
|
||||
#else
|
||||
@ -996,12 +983,12 @@ file_impossible_p (const char *filename)
|
||||
struct directory_contents *dir;
|
||||
struct dirfile *dirfile;
|
||||
struct dirfile dirfile_key;
|
||||
#ifdef VMS
|
||||
#if MK_OS_VMS
|
||||
int want_vmsify = 0;
|
||||
#endif
|
||||
|
||||
dirend = strrchr (filename, '/');
|
||||
#ifdef VMS
|
||||
#if MK_OS_VMS
|
||||
if (dirend == NULL)
|
||||
{
|
||||
want_vmsify = (strpbrk (filename, "]>:^") != NULL);
|
||||
@ -1023,12 +1010,8 @@ file_impossible_p (const char *filename)
|
||||
dirend = filename + 1;
|
||||
}
|
||||
#endif /* HAVE_DOS_PATHS */
|
||||
if (dirend == 0)
|
||||
#ifdef _AMIGA
|
||||
dir = find_directory ("")->contents;
|
||||
#else /* !AMIGA */
|
||||
if (dirend == NULL)
|
||||
dir = find_directory (".")->contents;
|
||||
#endif /* AMIGA */
|
||||
else
|
||||
{
|
||||
const char *dirname;
|
||||
@ -1041,7 +1024,7 @@ file_impossible_p (const char *filename)
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
/* d:/ and d: are *very* different... */
|
||||
if (dirend < filename + 3 && filename[1] == ':' &&
|
||||
(*dirend == '/' || *dirend == '\\' || *dirend == ':'))
|
||||
(ISDIRSEP (*dirend) || *dirend == ':'))
|
||||
dirend++;
|
||||
#endif
|
||||
cp = alloca (dirend - filename + 1);
|
||||
@ -1050,7 +1033,7 @@ file_impossible_p (const char *filename)
|
||||
dirname = cp;
|
||||
}
|
||||
dir = find_directory (dirname)->contents;
|
||||
#ifdef VMS
|
||||
#if MK_OS_VMS
|
||||
if (*slash == '/')
|
||||
filename = slash + 1;
|
||||
else
|
||||
@ -1060,17 +1043,17 @@ file_impossible_p (const char *filename)
|
||||
#endif
|
||||
}
|
||||
|
||||
if (dir == 0 || dir->dirfiles.ht_vec == 0)
|
||||
if (dir == NULL || dir->dirfiles.ht_vec == NULL)
|
||||
/* There are no files entered for this directory. */
|
||||
return 0;
|
||||
|
||||
#ifdef __MSDOS__
|
||||
#if MK_OS_DOS
|
||||
filename = dosify (filename);
|
||||
#endif
|
||||
#ifdef HAVE_CASE_INSENSITIVE_FS
|
||||
filename = downcase (filename);
|
||||
#endif
|
||||
#ifdef VMS
|
||||
#if MK_OS_VMS
|
||||
if (want_vmsify)
|
||||
filename = vmsify (filename, 1);
|
||||
#endif
|
||||
@ -1102,6 +1085,9 @@ print_dir_data_base (void)
|
||||
unsigned int impossible;
|
||||
struct directory **dir_slot;
|
||||
struct directory **dir_end;
|
||||
#if MK_OS_W32
|
||||
char buf[INTSTR_LENGTH + 1];
|
||||
#endif
|
||||
|
||||
puts (_("\n# Directories\n"));
|
||||
|
||||
@ -1114,27 +1100,22 @@ print_dir_data_base (void)
|
||||
struct directory *dir = *dir_slot;
|
||||
if (! HASH_VACANT (dir))
|
||||
{
|
||||
if (dir->contents == 0)
|
||||
if (dir->contents == NULL)
|
||||
printf (_("# %s: could not be stat'd.\n"), dir->name);
|
||||
else if (dir->contents->dirfiles.ht_vec == 0)
|
||||
{
|
||||
#ifdef WINDOWS32
|
||||
printf (_("# %s (key %s, mtime %I64u): could not be opened.\n"),
|
||||
dir->name, dir->contents->path_key,
|
||||
(unsigned long long)dir->contents->mtime);
|
||||
#else /* WINDOWS32 */
|
||||
#ifdef VMS_INO_T
|
||||
printf (_("# %s (device %d, inode [%d,%d,%d]): could not be opened.\n"),
|
||||
dir->name, dir->contents->dev,
|
||||
dir->contents->ino[0], dir->contents->ino[1],
|
||||
dir->contents->ino[2]);
|
||||
else if (dir->contents->dirfiles.ht_vec == NULL)
|
||||
#if MK_OS_W32
|
||||
printf (_("# %s (key %s, mtime %s): could not be opened.\n"),
|
||||
dir->name, dir->contents->path_key,
|
||||
make_ulltoa ((unsigned long long)dir->contents->mtime, buf));
|
||||
#elif defined(VMS_INO_T)
|
||||
printf (_("# %s (device %d, inode [%d,%d,%d]): could not be opened.\n"),
|
||||
dir->name, dir->contents->dev,
|
||||
dir->contents->ino[0], dir->contents->ino[1],
|
||||
dir->contents->ino[2]);
|
||||
#else
|
||||
printf (_("# %s (device %ld, inode %ld): could not be opened.\n"),
|
||||
dir->name, (long int) dir->contents->dev,
|
||||
(long int) dir->contents->ino);
|
||||
printf (_("# %s (device %ld, inode %ld): could not be opened.\n"),
|
||||
dir->name, (long) dir->contents->dev, (long) dir->contents->ino);
|
||||
#endif
|
||||
#endif /* WINDOWS32 */
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int f = 0;
|
||||
@ -1155,22 +1136,19 @@ print_dir_data_base (void)
|
||||
++f;
|
||||
}
|
||||
}
|
||||
#ifdef WINDOWS32
|
||||
printf (_("# %s (key %s, mtime %I64u): "),
|
||||
#if MK_OS_W32
|
||||
printf (_("# %s (key %s, mtime %s): "),
|
||||
dir->name, dir->contents->path_key,
|
||||
(unsigned long long)dir->contents->mtime);
|
||||
#else /* WINDOWS32 */
|
||||
#ifdef VMS_INO_T
|
||||
make_ulltoa ((unsigned long long)dir->contents->mtime, buf));
|
||||
#elif defined(VMS_INO_T)
|
||||
printf (_("# %s (device %d, inode [%d,%d,%d]): "),
|
||||
dir->name, dir->contents->dev,
|
||||
dir->contents->ino[0], dir->contents->ino[1],
|
||||
dir->contents->ino[2]);
|
||||
#else
|
||||
printf (_("# %s (device %ld, inode %ld): "),
|
||||
dir->name,
|
||||
printf (_("# %s (device %ld, inode %ld): "), dir->name,
|
||||
(long)dir->contents->dev, (long)dir->contents->ino);
|
||||
#endif
|
||||
#endif /* WINDOWS32 */
|
||||
if (f == 0)
|
||||
fputs (_("No"), stdout);
|
||||
else
|
||||
@ -1181,7 +1159,7 @@ print_dir_data_base (void)
|
||||
else
|
||||
printf ("%u", im);
|
||||
fputs (_(" impossibilities"), stdout);
|
||||
if (dir->contents->dirstream == 0)
|
||||
if (dir->contents->dirstream == NULL)
|
||||
puts (".");
|
||||
else
|
||||
puts (_(" so far."));
|
||||
@ -1215,34 +1193,34 @@ struct dirstream
|
||||
};
|
||||
|
||||
/* Forward declarations. */
|
||||
static __ptr_t open_dirstream (const char *);
|
||||
static struct dirent *read_dirstream (__ptr_t);
|
||||
static void *open_dirstream (const char *);
|
||||
static struct dirent *read_dirstream (void *);
|
||||
|
||||
static __ptr_t
|
||||
static void *
|
||||
open_dirstream (const char *directory)
|
||||
{
|
||||
struct dirstream *new;
|
||||
struct directory *dir = find_directory (directory);
|
||||
|
||||
if (dir->contents == 0 || dir->contents->dirfiles.ht_vec == 0)
|
||||
if (dir->contents == NULL || dir->contents->dirfiles.ht_vec == NULL)
|
||||
/* DIR->contents is nil if the directory could not be stat'd.
|
||||
DIR->contents->dirfiles is nil if it could not be opened. */
|
||||
return 0;
|
||||
return NULL;
|
||||
|
||||
/* Read all the contents of the directory now. There is no benefit
|
||||
in being lazy, since glob will want to see every file anyway. */
|
||||
|
||||
dir_contents_file_exists_p (dir->contents, 0);
|
||||
dir_contents_file_exists_p (dir, NULL);
|
||||
|
||||
new = xmalloc (sizeof (struct dirstream));
|
||||
new->contents = dir->contents;
|
||||
new->dirfile_slot = (struct dirfile **) new->contents->dirfiles.ht_vec;
|
||||
|
||||
return (__ptr_t) new;
|
||||
return new;
|
||||
}
|
||||
|
||||
static struct dirent *
|
||||
read_dirstream (__ptr_t stream)
|
||||
read_dirstream (void *stream)
|
||||
{
|
||||
static char *buf;
|
||||
static size_t bufsz;
|
||||
@ -1286,7 +1264,7 @@ read_dirstream (__ptr_t stream)
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* On 64 bit ReliantUNIX (5.44 and above) in LFS mode, stat() is actually a
|
||||
@ -1296,8 +1274,8 @@ read_dirstream (__ptr_t stream)
|
||||
* On MS-Windows, stat() "succeeds" for foo/bar/. where foo/bar is a
|
||||
* regular file; fix that here.
|
||||
*/
|
||||
#if !defined(stat) && !defined(WINDOWS32) || defined(VMS)
|
||||
# ifndef VMS
|
||||
#if !defined(stat) && !MK_OS_W32 || MK_OS_VMS
|
||||
# if !MK_OS_VMS
|
||||
# ifndef HAVE_SYS_STAT_H
|
||||
int stat (const char *path, struct stat *sbuf);
|
||||
# endif
|
||||
@ -1313,19 +1291,18 @@ static int
|
||||
local_stat (const char *path, struct stat *buf)
|
||||
{
|
||||
int e;
|
||||
#ifdef WINDOWS32
|
||||
#if MK_OS_W32
|
||||
size_t plen = strlen (path);
|
||||
|
||||
/* Make sure the parent of "." exists and is a directory, not a
|
||||
file. This is because 'stat' on Windows normalizes the argument
|
||||
foo/. => foo without checking first that foo is a directory. */
|
||||
if (plen > 2 && path[plen - 1] == '.'
|
||||
&& (path[plen - 2] == '/' || path[plen - 2] == '\\'))
|
||||
if (plen > 2 && path[plen - 1] == '.' && ISDIRSEP (path[plen - 2]))
|
||||
{
|
||||
char parent[MAXPATHLEN+1];
|
||||
char parent[MAX_PATH+1];
|
||||
|
||||
strncpy (parent, path, MAXPATHLEN);
|
||||
parent[MIN(plen - 2, MAXPATHLEN)] = '\0';
|
||||
strncpy (parent, path, MAX_PATH);
|
||||
parent[MIN(plen - 2, MAX_PATH)] = '\0';
|
||||
if (stat (parent, buf) < 0 || !_S_ISDIR (buf->st_mode))
|
||||
return -1;
|
||||
}
|
||||
@ -1337,8 +1314,8 @@ local_stat (const char *path, struct stat *buf)
|
||||
#endif
|
||||
|
||||
/* Similarly for lstat. */
|
||||
#if !defined(lstat) && !defined(WINDOWS32) || defined(VMS)
|
||||
# ifndef VMS
|
||||
#if !defined(lstat) && !MK_OS_W32 || MK_OS_VMS
|
||||
# if !MK_OS_VMS
|
||||
# ifndef HAVE_SYS_STAT_H
|
||||
int lstat (const char *path, struct stat *sbuf);
|
||||
# endif
|
||||
@ -1349,7 +1326,7 @@ int lstat (const char *path, struct stat *sbuf);
|
||||
# endif
|
||||
# endif
|
||||
# define local_lstat lstat
|
||||
#elif defined(WINDOWS32)
|
||||
#elif MK_OS_W32
|
||||
/* Windows doesn't support lstat(). */
|
||||
# define local_lstat local_stat
|
||||
#else
|
||||
|
409
src/expand.c
409
src/expand.c
@ -1,5 +1,5 @@
|
||||
/* Variable expansion functions for GNU Make.
|
||||
Copyright (C) 1988-2022 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988-2024 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
@ -12,7 +12,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "makeint.h"
|
||||
|
||||
@ -24,6 +24,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
#include "job.h"
|
||||
#include "variable.h"
|
||||
#include "rule.h"
|
||||
#include "warning.h"
|
||||
|
||||
/* Initially, any errors reported when expanding strings will be reported
|
||||
against the file where the error appears. */
|
||||
@ -46,29 +47,33 @@ const floc **expanding_var = &reading_file;
|
||||
static size_t variable_buffer_length;
|
||||
char *variable_buffer;
|
||||
|
||||
/* Subroutine of variable_expand and friends:
|
||||
The text to add is LENGTH chars starting at STRING to the variable_buffer.
|
||||
The text is added to the buffer at PTR, and the updated pointer into
|
||||
the buffer is returned as the value. Thus, the value returned by
|
||||
each call to variable_buffer_output should be the first argument to
|
||||
the following call. */
|
||||
/* Append LENGTH chars of STRING at PTR which must point into variable_buffer.
|
||||
The buffer will always be kept nul-terminated.
|
||||
The updated pointer into the buffer is returned as the value. Thus, the
|
||||
value returned by each call to variable_buffer_output should be the first
|
||||
argument to the following call. */
|
||||
|
||||
char *
|
||||
variable_buffer_output (char *ptr, const char *string, size_t length)
|
||||
{
|
||||
size_t newlen = length + (ptr - variable_buffer);
|
||||
|
||||
if ((newlen + VARIABLE_BUFFER_ZONE) > variable_buffer_length)
|
||||
assert (ptr >= variable_buffer);
|
||||
assert (ptr < variable_buffer + variable_buffer_length);
|
||||
|
||||
if (newlen + VARIABLE_BUFFER_ZONE + 1 > variable_buffer_length)
|
||||
{
|
||||
size_t offset = ptr - variable_buffer;
|
||||
variable_buffer_length = (newlen + 100 > 2 * variable_buffer_length
|
||||
? newlen + 100
|
||||
: 2 * variable_buffer_length);
|
||||
variable_buffer = xrealloc (variable_buffer, variable_buffer_length);
|
||||
variable_buffer = xrealloc (variable_buffer, variable_buffer_length + 1);
|
||||
ptr = variable_buffer + offset;
|
||||
}
|
||||
|
||||
return mempcpy (ptr, string, length);
|
||||
ptr = mempcpy (ptr, string, length);
|
||||
*ptr = '\0';
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* Return a pointer to the beginning of the variable buffer.
|
||||
@ -79,16 +84,58 @@ initialize_variable_output ()
|
||||
{
|
||||
/* If we don't have a variable output buffer yet, get one. */
|
||||
|
||||
if (variable_buffer == 0)
|
||||
if (!variable_buffer)
|
||||
{
|
||||
variable_buffer_length = 200;
|
||||
variable_buffer = xmalloc (variable_buffer_length);
|
||||
variable_buffer[0] = '\0';
|
||||
}
|
||||
|
||||
variable_buffer[0] = '\0';
|
||||
|
||||
return variable_buffer;
|
||||
}
|
||||
|
||||
/* Install a new variable_buffer context, returning the current one for
|
||||
safe-keeping. */
|
||||
|
||||
void
|
||||
install_variable_buffer (char **bufp, size_t *lenp)
|
||||
{
|
||||
*bufp = variable_buffer;
|
||||
*lenp = variable_buffer_length;
|
||||
|
||||
variable_buffer = NULL;
|
||||
initialize_variable_output ();
|
||||
}
|
||||
|
||||
/* Free the current variable_buffer and restore a previously-saved one.
|
||||
*/
|
||||
|
||||
void
|
||||
restore_variable_buffer (char *buf, size_t len)
|
||||
{
|
||||
free (variable_buffer);
|
||||
|
||||
variable_buffer = buf;
|
||||
variable_buffer_length = len;
|
||||
}
|
||||
|
||||
/* Restore a previously-saved variable_buffer context, and return the
|
||||
current one.
|
||||
*/
|
||||
|
||||
char *
|
||||
swap_variable_buffer (char *buf, size_t len)
|
||||
{
|
||||
char *p = variable_buffer;
|
||||
|
||||
variable_buffer = buf;
|
||||
variable_buffer_length = len;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
/* Recursively expand V. The returned string is malloc'd. */
|
||||
|
||||
static char *allocated_variable_append (const struct variable *v);
|
||||
@ -99,15 +146,16 @@ recursively_expand_for_file (struct variable *v, struct file *file)
|
||||
char *value;
|
||||
const floc *this_var;
|
||||
const floc **saved_varp;
|
||||
struct variable_set_list *save = 0;
|
||||
struct variable_set_list *savev = 0;
|
||||
int set_reading = 0;
|
||||
size_t nl = strlen (v->name);
|
||||
struct variable *parent = NULL;
|
||||
|
||||
/* If we're expanding to put into the environment of a shell function then
|
||||
ignore any recursion issues: for backward-compatibility we will use
|
||||
the value of the environment variable we were started with. */
|
||||
if (v->expanding && env_recursion)
|
||||
{
|
||||
size_t nl = strlen (v->name);
|
||||
char **ep;
|
||||
DB (DB_VERBOSE,
|
||||
(_("%s:%lu: not recursively expanding %s to export to shell function\n"),
|
||||
@ -116,7 +164,7 @@ recursively_expand_for_file (struct variable *v, struct file *file)
|
||||
/* We could create a hash for the original environment for speed, but a
|
||||
reasonably written makefile shouldn't hit this situation... */
|
||||
for (ep = environ; *ep != 0; ++ep)
|
||||
if ((*ep)[nl] == '=' && strncmp (*ep, v->name, nl) == 0)
|
||||
if (strncmp (*ep, v->name, nl) == 0 && (*ep)[nl] == '=')
|
||||
return xstrdup ((*ep) + nl + 1);
|
||||
|
||||
/* If there's nothing in the parent environment, use the empty string.
|
||||
@ -146,76 +194,184 @@ recursively_expand_for_file (struct variable *v, struct file *file)
|
||||
if (!v->exp_count)
|
||||
/* Expanding V causes infinite recursion. Lose. */
|
||||
OS (fatal, *expanding_var,
|
||||
_("Recursive variable '%s' references itself (eventually)"),
|
||||
_("recursive variable '%s' references itself (eventually)"),
|
||||
v->name);
|
||||
--v->exp_count;
|
||||
}
|
||||
|
||||
if (file)
|
||||
{
|
||||
save = current_variable_set_list;
|
||||
current_variable_set_list = file->variables;
|
||||
}
|
||||
install_file_context (file, &savev, NULL);
|
||||
|
||||
v->expanding = 1;
|
||||
if (v->append)
|
||||
{
|
||||
/* Find a parent definition which is marked override. */
|
||||
struct variable_set_list *sl;
|
||||
for (sl = current_variable_set_list; sl && !parent; sl = sl->next)
|
||||
{
|
||||
struct variable *vp = lookup_variable_in_set (v->name, nl, sl->set);
|
||||
if (vp && vp != v && vp->origin == o_override)
|
||||
parent = vp;
|
||||
}
|
||||
}
|
||||
|
||||
if (parent)
|
||||
/* PARENT is an override, V is appending. If V is also an override:
|
||||
override hello := first
|
||||
al%: override hello += second
|
||||
Then construct the value from its appended parts in the parent sets.
|
||||
Else if V is not an override:
|
||||
override hello := first
|
||||
al%: hello += second
|
||||
Then ignore the value of V and use the value of PARENT. */
|
||||
value = v->origin == o_override
|
||||
? allocated_variable_append (v)
|
||||
: xstrdup (parent->value);
|
||||
else if (v->origin == o_command || v->origin == o_env_override)
|
||||
/* Avoid appending to a pattern-specific variable, unless the origin of this
|
||||
pattern-specific variable beats or equals the origin of one of the parent
|
||||
definitions of this variable.
|
||||
This is needed, because if there is a command line definition or an env
|
||||
override, then the value defined in the makefile should only be appended
|
||||
in the case of a file override.
|
||||
In the presence of command line definition or env override and absence of
|
||||
makefile override, the value should be expanded, rather than appended. In
|
||||
this case, at parse time record_target_var already set the value of this
|
||||
pattern-specific variable to the value defined on the command line or to
|
||||
the env override value.
|
||||
User provided a command line definition or an env override.
|
||||
PARENT does not have an override directive, so ignore it. */
|
||||
value = allocated_expand_string (v->value);
|
||||
else if (v->append)
|
||||
/* Construct the value from its appended parts in the parent sets. */
|
||||
value = allocated_variable_append (v);
|
||||
else
|
||||
value = allocated_variable_expand (v->value);
|
||||
/* A definition without appending. */
|
||||
value = allocated_expand_string (v->value);
|
||||
v->expanding = 0;
|
||||
|
||||
if (set_reading)
|
||||
reading_file = 0;
|
||||
|
||||
if (file)
|
||||
current_variable_set_list = save;
|
||||
restore_file_context (savev, NULL);
|
||||
|
||||
expanding_var = saved_varp;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/* Expand a simple reference to variable NAME, which is LENGTH chars long. */
|
||||
/* Expand a simple reference to variable NAME, which is LENGTH chars long.
|
||||
The result is written to PTR which must point into the variable_buffer.
|
||||
Returns a pointer to the new end of the variable_buffer. */
|
||||
|
||||
#ifdef __GNUC__
|
||||
__inline
|
||||
#endif
|
||||
static char *
|
||||
reference_variable (char *o, const char *name, size_t length)
|
||||
char *
|
||||
expand_variable_output (char *ptr, const char *name, size_t length)
|
||||
{
|
||||
struct variable *v;
|
||||
unsigned int recursive;
|
||||
char *value;
|
||||
|
||||
v = lookup_variable (name, length);
|
||||
|
||||
if (v == 0)
|
||||
if (!v)
|
||||
warn_undefined (name, length);
|
||||
|
||||
/* If there's no variable by that name or it has no value, stop now. */
|
||||
if (v == 0 || (*v->value == '\0' && !v->append))
|
||||
return o;
|
||||
if (!v || (v->value[0] == '\0' && !v->append))
|
||||
return ptr;
|
||||
|
||||
value = (v->recursive ? recursively_expand (v) : v->value);
|
||||
/* Remember this since expansion could change it. */
|
||||
recursive = v->recursive;
|
||||
|
||||
o = variable_buffer_output (o, value, strlen (value));
|
||||
value = recursive ? recursively_expand (v) : v->value;
|
||||
|
||||
if (v->recursive)
|
||||
ptr = variable_buffer_output (ptr, value, strlen (value));
|
||||
|
||||
if (recursive)
|
||||
free (value);
|
||||
|
||||
return o;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* Expand a simple reference to variable NAME, which is LENGTH chars long.
|
||||
The result is written to BUF which must point into the variable_buffer.
|
||||
If BUF is NULL, start at the beginning of the current variable_buffer.
|
||||
Returns a pointer to the START of the expanded value of the variable.
|
||||
The returned value is located inside variable_buffer.
|
||||
The returned value is valid until the next call to one of the functions
|
||||
which use variable_buffer. expand_variable_buf may reallocate
|
||||
variable_buffer and render the passed-in BUF invalid. */
|
||||
|
||||
|
||||
char *
|
||||
expand_variable_buf (char *buf, const char *name, size_t length)
|
||||
{
|
||||
size_t offs;
|
||||
|
||||
if (!buf)
|
||||
buf = initialize_variable_output ();
|
||||
|
||||
assert (buf >= variable_buffer);
|
||||
assert (buf < variable_buffer + variable_buffer_length);
|
||||
offs = buf - variable_buffer;
|
||||
|
||||
expand_variable_output (buf, name, length);
|
||||
return variable_buffer + offs;
|
||||
}
|
||||
|
||||
/* Expand a simple reference to variable NAME, which is LENGTH chars long.
|
||||
Returns an allocated buffer containing the value. */
|
||||
|
||||
char *
|
||||
allocated_expand_variable (const char *name, size_t length)
|
||||
{
|
||||
char *obuf;
|
||||
size_t olen;
|
||||
|
||||
install_variable_buffer (&obuf, &olen);
|
||||
|
||||
expand_variable_output (variable_buffer, name, length);
|
||||
|
||||
return swap_variable_buffer (obuf, olen);
|
||||
}
|
||||
|
||||
/* Expand a simple reference to variable NAME, which is LENGTH chars long.
|
||||
Error messages refer to the file and line where FILE's commands were found.
|
||||
Expansion uses FILE's variable set list.
|
||||
Returns an allocated buffer containing the value. */
|
||||
|
||||
char *
|
||||
allocated_expand_variable_for_file (const char *name, size_t length, struct file *file)
|
||||
{
|
||||
char *result;
|
||||
struct variable_set_list *savev;
|
||||
const floc *savef;
|
||||
|
||||
if (!file)
|
||||
return allocated_expand_variable (name, length);
|
||||
|
||||
install_file_context (file, &savev, &savef);
|
||||
|
||||
result = allocated_expand_variable (name, length);
|
||||
|
||||
restore_file_context (savev, savef);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Scan STRING for variable references and expansion-function calls. Only
|
||||
LENGTH bytes of STRING are actually scanned. If LENGTH is -1, scan until
|
||||
a null byte is found.
|
||||
LENGTH bytes of STRING are actually scanned.
|
||||
If LENGTH is SIZE_MAX, scan until a null byte is found.
|
||||
|
||||
Write the results to LINE, which must point into 'variable_buffer'. If
|
||||
LINE is NULL, start at the beginning of the buffer.
|
||||
Return a pointer to LINE, or to the beginning of the buffer if LINE is
|
||||
Write the results to BUF, which must point into variable_buffer. If
|
||||
BUF is NULL, start at the beginning of the current variable_buffer.
|
||||
|
||||
Return a pointer to BUF, or to the beginning of the new buffer if BUF is
|
||||
NULL.
|
||||
*/
|
||||
char *
|
||||
variable_expand_string (char *line, const char *string, size_t length)
|
||||
expand_string_buf (char *buf, const char *string, size_t length)
|
||||
{
|
||||
struct variable *v;
|
||||
const char *p, *p1;
|
||||
@ -223,16 +379,13 @@ variable_expand_string (char *line, const char *string, size_t length)
|
||||
char *o;
|
||||
size_t line_offset;
|
||||
|
||||
if (!line)
|
||||
line = initialize_variable_output ();
|
||||
o = line;
|
||||
line_offset = line - variable_buffer;
|
||||
if (!buf)
|
||||
buf = initialize_variable_output ();
|
||||
o = buf;
|
||||
line_offset = buf - variable_buffer;
|
||||
|
||||
if (length == 0)
|
||||
{
|
||||
variable_buffer_output (o, "", 1);
|
||||
return variable_buffer;
|
||||
}
|
||||
return variable_buffer;
|
||||
|
||||
/* We need a copy of STRING: due to eval, it's possible that it will get
|
||||
freed as we process it (it might be the value of a variable that's reset
|
||||
@ -271,47 +424,40 @@ variable_expand_string (char *line, const char *string, size_t length)
|
||||
{
|
||||
char openparen = *p;
|
||||
char closeparen = (openparen == '(') ? ')' : '}';
|
||||
const char *begp;
|
||||
const char *beg = p + 1;
|
||||
char *op;
|
||||
char *abeg = NULL;
|
||||
const char *end, *colon;
|
||||
|
||||
op = o;
|
||||
begp = p;
|
||||
if (handle_function (&op, &begp))
|
||||
{
|
||||
o = op;
|
||||
p = begp;
|
||||
break;
|
||||
}
|
||||
if (handle_function (&o, &p))
|
||||
break;
|
||||
|
||||
/* Is there a variable reference inside the parens or braces?
|
||||
If so, expand it before expanding the entire reference. */
|
||||
|
||||
end = strchr (beg, closeparen);
|
||||
if (end == 0)
|
||||
if (end == NULL)
|
||||
/* Unterminated variable reference. */
|
||||
O (fatal, *expanding_var, _("unterminated variable reference"));
|
||||
p1 = lindex (beg, end, '$');
|
||||
if (p1 != 0)
|
||||
if (p1 != NULL)
|
||||
{
|
||||
/* BEG now points past the opening paren or brace.
|
||||
Count parens or braces until it is matched. */
|
||||
int count = 0;
|
||||
int count = 1;
|
||||
for (p = beg; *p != '\0'; ++p)
|
||||
{
|
||||
if (*p == openparen)
|
||||
++count;
|
||||
else if (*p == closeparen && --count < 0)
|
||||
else if (*p == closeparen && --count == 0)
|
||||
break;
|
||||
}
|
||||
/* If COUNT is >= 0, there were unmatched opening parens
|
||||
/* If COUNT is > 0, there were unmatched opening parens
|
||||
or braces, so we go to the simple case of a variable name
|
||||
such as '$($(a)'. */
|
||||
if (count < 0)
|
||||
if (count == 0)
|
||||
{
|
||||
abeg = expand_argument (beg, p); /* Expand the name. */
|
||||
/* Expand the name. */
|
||||
abeg = expand_argument (beg, p);
|
||||
beg = abeg;
|
||||
end = strchr (beg, '\0');
|
||||
}
|
||||
@ -401,7 +547,7 @@ variable_expand_string (char *line, const char *string, size_t length)
|
||||
if (colon == 0)
|
||||
/* This is an ordinary variable reference.
|
||||
Look up the value of the variable. */
|
||||
o = reference_variable (o, beg, end - beg);
|
||||
o = expand_variable_output (o, beg, end - beg);
|
||||
|
||||
free (abeg);
|
||||
}
|
||||
@ -413,7 +559,7 @@ variable_expand_string (char *line, const char *string, size_t length)
|
||||
|
||||
/* A $ followed by a random char is a variable reference:
|
||||
$a is equivalent to $(a). */
|
||||
o = reference_variable (o, p, 1);
|
||||
o = expand_variable_output (o, p, 1);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -426,21 +572,10 @@ variable_expand_string (char *line, const char *string, size_t length)
|
||||
|
||||
free (save);
|
||||
|
||||
variable_buffer_output (o, "", 1);
|
||||
return (variable_buffer + line_offset);
|
||||
}
|
||||
|
||||
/* Scan LINE for variable references and expansion-function calls.
|
||||
Build in 'variable_buffer' the result of expanding the references and calls.
|
||||
Return the address of the resulting string, which is null-terminated
|
||||
and is valid only until the next time this function is called. */
|
||||
|
||||
char *
|
||||
variable_expand (const char *line)
|
||||
{
|
||||
return variable_expand_string (NULL, line, SIZE_MAX);
|
||||
}
|
||||
|
||||
/* Expand an argument for an expansion function.
|
||||
The text starting at STR and ending at END is variable-expanded
|
||||
into a null-terminated string that is returned as the value.
|
||||
@ -457,7 +592,7 @@ expand_argument (const char *str, const char *end)
|
||||
return xstrdup ("");
|
||||
|
||||
if (!end || *end == '\0')
|
||||
return allocated_variable_expand (str);
|
||||
return allocated_expand_string (str);
|
||||
|
||||
if (end - str + 1 > 1000)
|
||||
tmp = alloc = xmalloc (end - str + 1);
|
||||
@ -467,44 +602,53 @@ expand_argument (const char *str, const char *end)
|
||||
memcpy (tmp, str, end - str);
|
||||
tmp[end - str] = '\0';
|
||||
|
||||
r = allocated_variable_expand (tmp);
|
||||
r = allocated_expand_string (tmp);
|
||||
|
||||
free (alloc);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Expand LINE for FILE. Error messages refer to the file and line where
|
||||
FILE's commands were found. Expansion uses FILE's variable set list. */
|
||||
|
||||
/* Expand STRING for FILE, into the current variable_buffer.
|
||||
Error messages refer to the file and line where FILE's commands were found.
|
||||
Expansion uses FILE's variable set list. */
|
||||
|
||||
char *
|
||||
variable_expand_for_file (const char *line, struct file *file)
|
||||
expand_string_for_file (const char *string, struct file *file)
|
||||
{
|
||||
char *result;
|
||||
struct variable_set_list *savev;
|
||||
const floc *savef;
|
||||
|
||||
if (file == 0)
|
||||
return variable_expand (line);
|
||||
if (!file)
|
||||
return expand_string (string);
|
||||
|
||||
savev = current_variable_set_list;
|
||||
current_variable_set_list = file->variables;
|
||||
install_file_context (file, &savev, &savef);
|
||||
|
||||
savef = reading_file;
|
||||
if (file->cmds && file->cmds->fileinfo.filenm)
|
||||
reading_file = &file->cmds->fileinfo;
|
||||
else
|
||||
reading_file = 0;
|
||||
result = expand_string (string);
|
||||
|
||||
result = variable_expand (line);
|
||||
|
||||
current_variable_set_list = savev;
|
||||
reading_file = savef;
|
||||
restore_file_context (savev, savef);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Like expand_string_for_file, but the returned string is malloc'd. */
|
||||
|
||||
char *
|
||||
allocated_expand_string_for_file (const char *string, struct file *file)
|
||||
{
|
||||
char *obuf;
|
||||
size_t olen;
|
||||
|
||||
install_variable_buffer (&obuf, &olen);
|
||||
|
||||
expand_string_for_file (string, file);
|
||||
|
||||
return swap_variable_buffer (obuf, olen);
|
||||
}
|
||||
|
||||
/* Like allocated_variable_expand, but for += target-specific variables.
|
||||
/* Like allocated_expand_string, but for += target-specific variables.
|
||||
First recursively construct the variable value from its appended parts in
|
||||
any upper variable sets. Then expand the resulting value. */
|
||||
|
||||
@ -546,7 +690,7 @@ variable_append (const char *name, size_t length,
|
||||
if (! v->recursive)
|
||||
return variable_buffer_output (buf, v->value, strlen (v->value));
|
||||
|
||||
buf = variable_expand_string (buf, v->value, strlen (v->value));
|
||||
buf = expand_string_buf (buf, v->value, strlen (v->value));
|
||||
return (buf + strlen (buf));
|
||||
}
|
||||
|
||||
@ -554,68 +698,13 @@ variable_append (const char *name, size_t length,
|
||||
static char *
|
||||
allocated_variable_append (const struct variable *v)
|
||||
{
|
||||
char *val;
|
||||
|
||||
/* Construct the appended variable value. */
|
||||
char *obuf;
|
||||
size_t olen;
|
||||
|
||||
char *obuf = variable_buffer;
|
||||
size_t olen = variable_buffer_length;
|
||||
install_variable_buffer (&obuf, &olen);
|
||||
|
||||
variable_buffer = 0;
|
||||
variable_append (v->name, strlen (v->name), current_variable_set_list, 1);
|
||||
|
||||
val = variable_append (v->name, strlen (v->name),
|
||||
current_variable_set_list, 1);
|
||||
variable_buffer_output (val, "", 1);
|
||||
val = variable_buffer;
|
||||
|
||||
variable_buffer = obuf;
|
||||
variable_buffer_length = olen;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
/* Like variable_expand_for_file, but the returned string is malloc'd.
|
||||
This function is called a lot. It wants to be efficient. */
|
||||
|
||||
char *
|
||||
allocated_variable_expand_for_file (const char *line, struct file *file)
|
||||
{
|
||||
char *value;
|
||||
|
||||
char *obuf = variable_buffer;
|
||||
size_t olen = variable_buffer_length;
|
||||
|
||||
variable_buffer = 0;
|
||||
|
||||
value = variable_expand_for_file (line, file);
|
||||
|
||||
variable_buffer = obuf;
|
||||
variable_buffer_length = olen;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/* Install a new variable_buffer context, returning the current one for
|
||||
safe-keeping. */
|
||||
|
||||
void
|
||||
install_variable_buffer (char **bufp, size_t *lenp)
|
||||
{
|
||||
*bufp = variable_buffer;
|
||||
*lenp = variable_buffer_length;
|
||||
|
||||
variable_buffer = 0;
|
||||
initialize_variable_output ();
|
||||
}
|
||||
|
||||
/* Restore a previously-saved variable_buffer setting (free the current one).
|
||||
*/
|
||||
|
||||
void
|
||||
restore_variable_buffer (char *buf, size_t len)
|
||||
{
|
||||
free (variable_buffer);
|
||||
|
||||
variable_buffer = buf;
|
||||
variable_buffer_length = len;
|
||||
return swap_variable_buffer (obuf, olen);
|
||||
}
|
||||
|
148
src/file.c
148
src/file.c
@ -1,5 +1,5 @@
|
||||
/* Target file management for GNU Make.
|
||||
Copyright (C) 1988-2022 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988-2024 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
@ -12,7 +12,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "makeint.h"
|
||||
|
||||
@ -26,6 +26,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
#include "debug.h"
|
||||
#include "hash.h"
|
||||
#include "shuffle.h"
|
||||
#include "rule.h"
|
||||
|
||||
|
||||
/* Remember whether snap_deps has been invoked: we need this to be sure we
|
||||
@ -60,12 +61,17 @@ file_hash_cmp (const void *x, const void *y)
|
||||
|
||||
static struct hash_table files;
|
||||
|
||||
/* We can't free files we take out of the hash table, because they are still
|
||||
likely pointed to in various places. The check_renamed() will be used if
|
||||
we come across these, to find the new correct file. This is mainly to
|
||||
prevent leak checkers from complaining. */
|
||||
static struct file **rehashed_files = NULL;
|
||||
static size_t rehashed_files_len = 0;
|
||||
#define REHASHED_FILES_INCR 5
|
||||
|
||||
/* Whether or not .SECONDARY with no prerequisites was given. */
|
||||
static int all_secondary = 0;
|
||||
|
||||
/* Whether or not .NOTINTERMEDIATE with no prerequisites was given. */
|
||||
static int no_intermediates = 0;
|
||||
|
||||
/* Access the hash table of all file records.
|
||||
lookup_file given a name, return the struct file * for that name,
|
||||
or nil if there is none.
|
||||
@ -76,7 +82,7 @@ lookup_file (const char *name)
|
||||
{
|
||||
struct file *f;
|
||||
struct file file_key;
|
||||
#ifdef VMS
|
||||
#if MK_OS_VMS
|
||||
int want_vmsify;
|
||||
#ifndef WANT_CASE_SENSITIVE_TARGETS
|
||||
char *lname;
|
||||
@ -88,7 +94,7 @@ lookup_file (const char *name)
|
||||
/* This is also done in parse_file_seq, so this is redundant
|
||||
for names read from makefiles. It is here for names passed
|
||||
on the command line. */
|
||||
#ifdef VMS
|
||||
#if MK_OS_VMS
|
||||
want_vmsify = (strpbrk (name, "]>:^") != NULL);
|
||||
# ifndef WANT_CASE_SENSITIVE_TARGETS
|
||||
if (*name != '.')
|
||||
@ -108,20 +114,10 @@ lookup_file (const char *name)
|
||||
while (name[0] == '<' && name[1] == '>' && name[2] != '\0')
|
||||
name += 2;
|
||||
#endif
|
||||
while (name[0] == '.'
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
&& (name[1] == '/' || name[1] == '\\')
|
||||
#else
|
||||
&& name[1] == '/'
|
||||
#endif
|
||||
&& name[2] != '\0')
|
||||
while (name[0] == '.' && ISDIRSEP (name[1]) && name[2] != '\0')
|
||||
{
|
||||
name += 2;
|
||||
while (*name == '/'
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
|| *name == '\\'
|
||||
#endif
|
||||
)
|
||||
while (ISDIRSEP (*name))
|
||||
/* Skip following slashes: ".//foo" is "foo", not "/foo". */
|
||||
++name;
|
||||
}
|
||||
@ -129,12 +125,8 @@ lookup_file (const char *name)
|
||||
if (*name == '\0')
|
||||
{
|
||||
/* It was all slashes after a dot. */
|
||||
#if defined(_AMIGA)
|
||||
name = "";
|
||||
#else
|
||||
name = "./";
|
||||
#endif
|
||||
#if defined(VMS)
|
||||
#if MK_OS_VMS
|
||||
/* TODO - This section is probably not needed. */
|
||||
if (want_vmsify)
|
||||
name = "[]";
|
||||
@ -142,7 +134,7 @@ lookup_file (const char *name)
|
||||
}
|
||||
file_key.hname = name;
|
||||
f = hash_find_item (&files, &file_key);
|
||||
#if defined(VMS) && !defined(WANT_CASE_SENSITIVE_TARGETS)
|
||||
#if MK_OS_VMS && !defined(WANT_CASE_SENSITIVE_TARGETS)
|
||||
if (*name != '.')
|
||||
free (lname);
|
||||
#endif
|
||||
@ -166,7 +158,7 @@ enter_file (const char *name)
|
||||
assert (*name != '\0');
|
||||
assert (! verify_flag || strcache_iscached (name));
|
||||
|
||||
#if defined(VMS) && !defined(WANT_CASE_SENSITIVE_TARGETS)
|
||||
#if MK_OS_VMS && !defined(WANT_CASE_SENSITIVE_TARGETS)
|
||||
if (*name != '.')
|
||||
{
|
||||
const char *n;
|
||||
@ -234,8 +226,7 @@ rehash_file (struct file *from_file, const char *to_hname)
|
||||
|
||||
/* Find the end of the renamed list for the "from" file. */
|
||||
file_key.hname = from_file->hname;
|
||||
while (from_file->renamed != 0)
|
||||
from_file = from_file->renamed;
|
||||
check_renamed (from_file);
|
||||
if (file_hash_cmp (from_file, &file_key))
|
||||
/* hname changed unexpectedly!! */
|
||||
abort ();
|
||||
@ -279,19 +270,19 @@ rehash_file (struct file *from_file, const char *to_hname)
|
||||
if (to_file->cmds->fileinfo.filenm != 0)
|
||||
error (&from_file->cmds->fileinfo,
|
||||
l + strlen (to_file->cmds->fileinfo.filenm) + INTSTR_LENGTH,
|
||||
_("Recipe was specified for file '%s' at %s:%lu,"),
|
||||
_("recipe was specified for file '%s' at %s:%lu,"),
|
||||
from_file->name, from_file->cmds->fileinfo.filenm,
|
||||
from_file->cmds->fileinfo.lineno);
|
||||
else
|
||||
error (&from_file->cmds->fileinfo, l,
|
||||
_("Recipe for file '%s' was found by implicit rule search,"),
|
||||
_("recipe for file '%s' was found by implicit rule search,"),
|
||||
from_file->name);
|
||||
l += strlen (to_hname);
|
||||
error (&from_file->cmds->fileinfo, l,
|
||||
_("but '%s' is now considered the same file as '%s'."),
|
||||
_("but '%s' is now considered the same file as '%s'"),
|
||||
from_file->name, to_hname);
|
||||
error (&from_file->cmds->fileinfo, l,
|
||||
_("Recipe for '%s' will be ignored in favor of the one for '%s'."),
|
||||
_("recipe for '%s' will be ignored in favor of the one for '%s'"),
|
||||
from_file->name, to_hname);
|
||||
}
|
||||
}
|
||||
@ -344,10 +335,17 @@ rehash_file (struct file *from_file, const char *to_hname)
|
||||
MERGE (notintermediate);
|
||||
MERGE (ignore_vpath);
|
||||
MERGE (snapped);
|
||||
MERGE (suffix);
|
||||
#undef MERGE
|
||||
|
||||
to_file->builtin = 0;
|
||||
from_file->renamed = to_file;
|
||||
|
||||
if (rehashed_files_len % REHASHED_FILES_INCR == 0)
|
||||
rehashed_files = xrealloc (rehashed_files,
|
||||
sizeof (struct file *) * (rehashed_files_len + REHASHED_FILES_INCR));
|
||||
|
||||
rehashed_files[rehashed_files_len++] = from_file;
|
||||
}
|
||||
|
||||
/* Rename FILE to NAME. This is not as simple as resetting
|
||||
@ -378,7 +376,7 @@ remove_intermediates (int sig)
|
||||
int doneany = 0;
|
||||
|
||||
/* If there's no way we will ever remove anything anyway, punt early. */
|
||||
if (question_flag || touch_flag || all_secondary)
|
||||
if (question_flag || touch_flag || all_secondary || no_intermediates)
|
||||
return;
|
||||
|
||||
if (sig && just_print_flag)
|
||||
@ -414,7 +412,7 @@ remove_intermediates (int sig)
|
||||
{
|
||||
if (sig)
|
||||
OS (error, NILF,
|
||||
_("*** Deleting intermediate file '%s'"), f->name);
|
||||
_("*** deleting intermediate file '%s'"), f->name);
|
||||
else
|
||||
{
|
||||
if (! doneany)
|
||||
@ -434,7 +432,10 @@ remove_intermediates (int sig)
|
||||
}
|
||||
if (status < 0)
|
||||
{
|
||||
perror_with_name ("\nunlink: ", f->name);
|
||||
if (doneany)
|
||||
fputs ("\n", stdout);
|
||||
fflush (stdout);
|
||||
perror_with_name ("unlink: ", f->name);
|
||||
/* Start printing over. */
|
||||
doneany = 0;
|
||||
}
|
||||
@ -653,7 +654,7 @@ expand_deps (struct file *f)
|
||||
set_file_variables (f, d->stem ? d->stem : f->stem);
|
||||
|
||||
/* Perform second expansion. */
|
||||
p = variable_expand_for_file (d->name, f);
|
||||
p = expand_string_for_file (d->name, f);
|
||||
|
||||
/* Free the un-expanded name. */
|
||||
free ((char*)d->name);
|
||||
@ -705,7 +706,7 @@ struct dep *
|
||||
expand_extra_prereqs (const struct variable *extra)
|
||||
{
|
||||
struct dep *d;
|
||||
struct dep *prereqs = extra ? split_prereqs (variable_expand (extra->value)) : NULL;
|
||||
struct dep *prereqs = extra ? split_prereqs (expand_string (extra->value)) : NULL;
|
||||
|
||||
for (d = prereqs; d; d = d->next)
|
||||
{
|
||||
@ -726,6 +727,7 @@ snap_file (const void *item, void *arg)
|
||||
{
|
||||
struct file *f = (struct file*)item;
|
||||
struct dep *prereqs = NULL;
|
||||
struct dep *d;
|
||||
|
||||
/* If we're not doing second expansion then reset updating. */
|
||||
if (!second_expansion)
|
||||
@ -741,18 +743,26 @@ snap_file (const void *item, void *arg)
|
||||
/* If .NOTINTERMEDIATE is set with no deps, mark all targets as
|
||||
notintermediate, unless the target is a prereq of .INTERMEDIATE. */
|
||||
if (no_intermediates && !f->intermediate && !f->secondary)
|
||||
f->notintermediate = 1;
|
||||
f->notintermediate = 1;
|
||||
|
||||
/* If .EXTRA_PREREQS is set, add them as ignored by automatic variables. */
|
||||
if (f->variables)
|
||||
prereqs = expand_extra_prereqs (lookup_variable_in_set (STRING_SIZE_TUPLE(".EXTRA_PREREQS"), f->variables->set));
|
||||
|
||||
{
|
||||
prereqs = expand_extra_prereqs (lookup_variable_in_set (
|
||||
STRING_SIZE_TUPLE(".EXTRA_PREREQS"), f->variables->set));
|
||||
if (second_expansion)
|
||||
for (d = prereqs; d; d = d->next)
|
||||
{
|
||||
if (!d->name)
|
||||
d->name = xstrdup (d->file->name);
|
||||
d->need_2nd_expansion = 1;
|
||||
}
|
||||
}
|
||||
else if (f->is_target)
|
||||
prereqs = copy_dep_chain (arg);
|
||||
|
||||
if (prereqs)
|
||||
{
|
||||
struct dep *d;
|
||||
for (d = prereqs; d; d = d->next)
|
||||
if (streq (f->name, dep_name (d)))
|
||||
/* Skip circular dependencies. */
|
||||
@ -820,7 +830,7 @@ snap_deps (void)
|
||||
else
|
||||
no_intermediates = 1;
|
||||
|
||||
/* The same file connot be both .INTERMEDIATE and .NOTINTERMEDIATE.
|
||||
/* The same file cannot be both .INTERMEDIATE and .NOTINTERMEDIATE.
|
||||
However, it is possible for a file to be .INTERMEDIATE and also match a
|
||||
.NOTINTERMEDIATE pattern. In that case, the intermediate file has
|
||||
priority over the notintermediate pattern. This priority is enforced by
|
||||
@ -953,7 +963,7 @@ file_timestamp_cons (const char *fname, time_t stamp, long int ns)
|
||||
ts = s <= OLD_MTIME ? ORDINARY_MTIME_MIN : ORDINARY_MTIME_MAX;
|
||||
file_timestamp_sprintf (buf, ts);
|
||||
OSS (error, NILF,
|
||||
_("%s: Timestamp out of range; substituting %s"), f, buf);
|
||||
_("%s: timestamp out of range: substituting %s"), f, buf);
|
||||
}
|
||||
|
||||
return ts;
|
||||
@ -1018,21 +1028,22 @@ file_timestamp_sprintf (char *p, FILE_TIMESTAMP ts)
|
||||
struct tm *tm = localtime (&t);
|
||||
|
||||
if (tm)
|
||||
sprintf (p, "%04d-%02d-%02d %02d:%02d:%02d",
|
||||
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
{
|
||||
intmax_t year = tm->tm_year;
|
||||
p += sprintf (p, "%04" PRIdMAX "-%02d-%02d %02d:%02d:%02d",
|
||||
year + 1900, tm->tm_mon + 1, tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
}
|
||||
else if (t < 0)
|
||||
sprintf (p, "%ld", (long) t);
|
||||
p += sprintf (p, "%" PRIdMAX, (intmax_t) t);
|
||||
else
|
||||
sprintf (p, "%lu", (unsigned long) t);
|
||||
p += strlen (p);
|
||||
p += sprintf (p, "%" PRIuMAX, (uintmax_t) t);
|
||||
|
||||
/* Append nanoseconds as a fraction, but remove trailing zeros. We don't
|
||||
know the actual timestamp resolution, since clock_getres applies only to
|
||||
local times, whereas this timestamp might come from a remote filesystem.
|
||||
So removing trailing zeros is the best guess that we can do. */
|
||||
sprintf (p, ".%09d", FILE_TIMESTAMP_NS (ts));
|
||||
p += strlen (p) - 1;
|
||||
p += sprintf (p, ".%09d", FILE_TIMESTAMP_NS (ts)) - 1;
|
||||
while (*p == '0')
|
||||
p--;
|
||||
p += *p != '.';
|
||||
@ -1042,7 +1053,7 @@ file_timestamp_sprintf (char *p, FILE_TIMESTAMP ts)
|
||||
|
||||
/* Print the data base of files. */
|
||||
|
||||
void
|
||||
static void
|
||||
print_prereqs (const struct dep *deps)
|
||||
{
|
||||
const struct dep *ood = 0;
|
||||
@ -1118,6 +1129,9 @@ print_file (const void *item)
|
||||
puts (_("# File is a prerequisite of .NOTINTERMEDIATE."));
|
||||
if (f->secondary)
|
||||
puts (_("# File is secondary (prerequisite of .SECONDARY)."));
|
||||
if (f->is_explicit)
|
||||
puts (_("# File is explicitly mentioned."));
|
||||
|
||||
if (f->also_make != 0)
|
||||
{
|
||||
const struct dep *d;
|
||||
@ -1193,6 +1207,34 @@ print_file_data_base (void)
|
||||
fputs (_("\n# files hash-table stats:\n# "), stdout);
|
||||
hash_print_stats (&files, stdout);
|
||||
}
|
||||
|
||||
static void
|
||||
print_target (const void *item)
|
||||
{
|
||||
const struct file *f = item;
|
||||
|
||||
if (!f->is_target || f->suffix)
|
||||
return;
|
||||
|
||||
/* Ignore any special targets, as defined by POSIX. */
|
||||
if (f->name[0] == '.' && isupper ((unsigned char)f->name[1]))
|
||||
{
|
||||
const char *cp = f->name + 1;
|
||||
while (*(++cp) != '\0')
|
||||
if (!isupper ((unsigned char)*cp))
|
||||
break;
|
||||
if (*cp == '\0')
|
||||
return;
|
||||
}
|
||||
|
||||
puts (f->name);
|
||||
}
|
||||
|
||||
void
|
||||
print_targets (void)
|
||||
{
|
||||
hash_map (&files, print_target);
|
||||
}
|
||||
|
||||
/* Verify the integrity of the data base of files. */
|
||||
|
||||
@ -1200,7 +1242,7 @@ print_file_data_base (void)
|
||||
do{ \
|
||||
if (_p->_n && _p->_n[0] && !strcache_iscached (_p->_n)) \
|
||||
error (NULL, strlen (_p->name) + CSTRLEN (# _n) + strlen (_p->_n), \
|
||||
_("%s: Field '%s' not cached: %s"), _p->name, # _n, _p->_n); \
|
||||
_("%s: field '%s' not cached: %s"), _p->name, # _n, _p->_n); \
|
||||
}while(0)
|
||||
|
||||
static void
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Definition of target file data structures for GNU Make.
|
||||
Copyright (C) 1988-2022 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988-2024 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
@ -12,7 +12,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
|
||||
/* Structure that represents the info on one file
|
||||
@ -113,6 +113,7 @@ struct file
|
||||
--shuffle passes through the graph. */
|
||||
unsigned int snapped:1; /* True if the deps of this file have been
|
||||
secondary expanded. */
|
||||
unsigned int suffix:1; /* True if this is a suffix rule. */
|
||||
};
|
||||
|
||||
|
||||
@ -134,8 +135,8 @@ void notice_finished_file (struct file *file);
|
||||
void init_hash_files (void);
|
||||
void verify_file_data_base (void);
|
||||
char *build_target_list (char *old_list);
|
||||
void print_prereqs (const struct dep *deps);
|
||||
void print_file_data_base (void);
|
||||
void print_targets (void);
|
||||
int try_implicit_rule (struct file *file, unsigned int depth);
|
||||
int stemlen_compare (const void *v1, const void *v2);
|
||||
|
||||
@ -212,6 +213,8 @@ FILE_TIMESTAMP f_mtime (struct file *file, int search);
|
||||
<< FILE_TIMESTAMP_LO_BITS) \
|
||||
+ ORDINARY_MTIME_MIN + FILE_TIMESTAMPS_PER_S - 1)
|
||||
|
||||
#define is_ordinary_mtime(_t) ((_t) >= ORDINARY_MTIME_MIN && (_t) <= ORDINARY_MTIME_MAX)
|
||||
|
||||
/* Modtime value to use for 'infinitely new'. We used to get the current time
|
||||
from the system and use that whenever we wanted 'new'. But that causes
|
||||
trouble when the machine running make and the machine holding a file have
|
||||
|
396
src/function.c
396
src/function.c
@ -1,5 +1,5 @@
|
||||
/* Builtin function expansion for GNU Make.
|
||||
Copyright (C) 1988-2022 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988-2024 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
@ -12,7 +12,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "makeint.h"
|
||||
#include "filedef.h"
|
||||
@ -23,10 +23,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
#include "commands.h"
|
||||
#include "debug.h"
|
||||
|
||||
#ifdef _AMIGA
|
||||
#include "amiga.h"
|
||||
#endif
|
||||
|
||||
|
||||
struct function_table_entry
|
||||
{
|
||||
@ -524,7 +520,7 @@ func_notdir_suffix (char *o, char **argv, const char *funcname)
|
||||
int is_suffix = funcname[0] == 's';
|
||||
int is_notdir = !is_suffix;
|
||||
int stop = MAP_DIRSEP | (is_suffix ? MAP_DOT : 0);
|
||||
#ifdef VMS
|
||||
#if MK_OS_VMS
|
||||
/* For VMS list_iterator points to a comma separated list. To use the common
|
||||
[find_]next_token, create a local copy and replace the commas with
|
||||
spaces. Obviously, there is a problem if there is a ',' in the VMS filename
|
||||
@ -569,7 +565,7 @@ func_notdir_suffix (char *o, char **argv, const char *funcname)
|
||||
|
||||
if (is_notdir || p >= p2)
|
||||
{
|
||||
#ifdef VMS
|
||||
#if MK_OS_VMS
|
||||
if (vms_comma_separator)
|
||||
o = variable_buffer_output (o, ",", 1);
|
||||
else
|
||||
@ -600,7 +596,7 @@ func_basename_dir (char *o, char **argv, const char *funcname)
|
||||
int is_basename = funcname[0] == 'b';
|
||||
int is_dir = !is_basename;
|
||||
int stop = MAP_DIRSEP | (is_basename ? MAP_DOT : 0) | MAP_NUL;
|
||||
#ifdef VMS
|
||||
#if MK_OS_VMS
|
||||
/* As in func_notdir_suffix ... */
|
||||
char *vms_p3 = alloca (strlen(p3) + 1);
|
||||
int i;
|
||||
@ -629,7 +625,7 @@ func_basename_dir (char *o, char **argv, const char *funcname)
|
||||
o = variable_buffer_output (o, p2, 2);
|
||||
#endif
|
||||
else if (is_dir)
|
||||
#ifdef VMS
|
||||
#if MK_OS_VMS
|
||||
{
|
||||
extern int vms_report_unix_paths;
|
||||
if (vms_report_unix_paths)
|
||||
@ -638,17 +634,13 @@ func_basename_dir (char *o, char **argv, const char *funcname)
|
||||
o = variable_buffer_output (o, "[]", 2);
|
||||
}
|
||||
#else
|
||||
#ifndef _AMIGA
|
||||
o = variable_buffer_output (o, "./", 2);
|
||||
#else
|
||||
; /* Just a nop... */
|
||||
#endif /* AMIGA */
|
||||
#endif /* !VMS */
|
||||
#endif /* !MK_OS_VMS */
|
||||
else
|
||||
/* The entire name is the basename. */
|
||||
o = variable_buffer_output (o, p2, len);
|
||||
|
||||
#ifdef VMS
|
||||
#if MK_OS_VMS
|
||||
if (vms_comma_separator)
|
||||
o = variable_buffer_output (o, ",", 1);
|
||||
else
|
||||
@ -745,8 +737,7 @@ func_words (char *o, char **argv, const char *funcname UNUSED)
|
||||
while (find_next_token (&word_iterator, NULL) != 0)
|
||||
++i;
|
||||
|
||||
sprintf (buf, "%u", i);
|
||||
o = variable_buffer_output (o, buf, strlen (buf));
|
||||
o = variable_buffer_output (o, buf, sprintf (buf, "%u", i));
|
||||
|
||||
return o;
|
||||
}
|
||||
@ -816,20 +807,18 @@ func_word (char *o, char **argv, const char *funcname UNUSED)
|
||||
static char *
|
||||
func_wordlist (char *o, char **argv, const char *funcname UNUSED)
|
||||
{
|
||||
char buf[INTSTR_LENGTH + 1];
|
||||
long long start, stop, count;
|
||||
const char* badfirst = _("invalid first argument to 'wordlist' function");
|
||||
const char* badsecond = _("invalid second argument to 'wordlist' function");
|
||||
|
||||
start = parse_numeric (argv[0],
|
||||
_("invalid first argument to 'wordlist' function"));
|
||||
stop = parse_numeric (argv[1],
|
||||
_("invalid second argument to 'wordlist' function"));
|
||||
|
||||
start = parse_numeric (argv[0], badfirst);
|
||||
if (start < 1)
|
||||
ON (fatal, *expanding_var,
|
||||
"invalid first argument to 'wordlist' function: '%lld'", start);
|
||||
OSS (fatal, *expanding_var, "%s: '%s'", badfirst, make_lltoa (start, buf));
|
||||
|
||||
stop = parse_numeric (argv[1], badsecond);
|
||||
if (stop < 0)
|
||||
ON (fatal, *expanding_var,
|
||||
"invalid second argument to 'wordlist' function: '%lld'", stop);
|
||||
OSS (fatal, *expanding_var, "%s: '%s'", badsecond, make_lltoa (stop, buf));
|
||||
|
||||
count = stop - start + 1;
|
||||
|
||||
@ -895,7 +884,7 @@ func_foreach (char *o, char **argv, const char *funcname UNUSED)
|
||||
free (var->value);
|
||||
var->value = xstrndup (p, len);
|
||||
|
||||
result = allocated_variable_expand (body);
|
||||
result = allocated_expand_string (body);
|
||||
|
||||
o = variable_buffer_output (o, result, strlen (result));
|
||||
o = variable_buffer_output (o, " ", 1);
|
||||
@ -925,8 +914,6 @@ func_let (char *o, char **argv, const char *funcname UNUSED)
|
||||
const char *vp;
|
||||
const char *vp_next = varnames;
|
||||
const char *list_iterator = list;
|
||||
char *p;
|
||||
size_t len;
|
||||
size_t vlen;
|
||||
|
||||
push_new_variable_scope ();
|
||||
@ -936,8 +923,9 @@ func_let (char *o, char **argv, const char *funcname UNUSED)
|
||||
NEXT_TOKEN (vp_next);
|
||||
while (*vp_next != '\0')
|
||||
{
|
||||
p = find_next_token (&list_iterator, &len);
|
||||
if (*list_iterator != '\0')
|
||||
size_t len;
|
||||
char *p = find_next_token (&list_iterator, &len);
|
||||
if (p && *list_iterator != '\0')
|
||||
{
|
||||
++list_iterator;
|
||||
p[len] = '\0';
|
||||
@ -955,7 +943,7 @@ func_let (char *o, char **argv, const char *funcname UNUSED)
|
||||
/* Expand the body in the context of the arguments, adding the result to
|
||||
the variable buffer. */
|
||||
|
||||
o = variable_expand_string (o, body, SIZE_MAX);
|
||||
o = expand_string_buf (o, body, SIZE_MAX);
|
||||
|
||||
pop_variable_scope ();
|
||||
free (varnames);
|
||||
@ -987,12 +975,13 @@ a_word_hash_2 (const void *key)
|
||||
static int
|
||||
a_word_hash_cmp (const void *x, const void *y)
|
||||
{
|
||||
int result = (int) ((struct a_word const *) x)->length - ((struct a_word const *) y)->length;
|
||||
if (result)
|
||||
return result;
|
||||
return_STRING_N_COMPARE (((struct a_word const *) x)->str,
|
||||
((struct a_word const *) y)->str,
|
||||
((struct a_word const *) y)->length);
|
||||
const struct a_word *ax = x;
|
||||
const struct a_word *ay = y;
|
||||
|
||||
if (ax->length != ay->length)
|
||||
return ax->length > ay->length ? 1 : -1;
|
||||
|
||||
return_STRING_N_COMPARE (ax->str, ay->str, ax->length);
|
||||
}
|
||||
|
||||
struct a_pattern
|
||||
@ -1011,7 +1000,7 @@ func_filter_filterout (char *o, char **argv, const char *funcname)
|
||||
struct a_pattern *patterns;
|
||||
struct a_pattern *pat_end;
|
||||
struct a_pattern *pp;
|
||||
size_t pat_count = 0, word_count = 0;
|
||||
unsigned long pat_count = 0, word_count = 0;
|
||||
|
||||
struct hash_table a_word_table;
|
||||
int is_filter = funcname[CSTRLEN ("filter")] == '\0';
|
||||
@ -1184,16 +1173,17 @@ func_error (char *o, char **argv, const char *funcname)
|
||||
case 'i':
|
||||
{
|
||||
size_t len = strlen (argv[0]);
|
||||
char *msg = alloca (len + 2);
|
||||
char *msg = xmalloc (len + 2);
|
||||
memcpy (msg, argv[0], len);
|
||||
msg[len] = '\n';
|
||||
msg[len + 1] = '\0';
|
||||
outputs (0, msg);
|
||||
free (msg);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
OS (fatal, *expanding_var, "Internal error: func_error: '%s'", funcname);
|
||||
OS (fatal, *expanding_var, "INTERNAL: func_error: '%s'", funcname);
|
||||
}
|
||||
|
||||
/* The warning function expands to the empty string. */
|
||||
@ -1337,6 +1327,8 @@ func_intcmp (char *o, char **argv, const char *funcname UNUSED)
|
||||
cmp = (llen > rlen) - (llen < rlen);
|
||||
if (cmp == 0)
|
||||
cmp = memcmp (lnum, rnum, llen);
|
||||
if (lsign < 0)
|
||||
cmp *= -1;
|
||||
}
|
||||
|
||||
argv += 2;
|
||||
@ -1529,12 +1521,8 @@ func_and (char *o, char **argv, const char *funcname UNUSED)
|
||||
static char *
|
||||
func_wildcard (char *o, char **argv, const char *funcname UNUSED)
|
||||
{
|
||||
#ifdef _AMIGA
|
||||
o = wildcard_expansion (argv[0], o);
|
||||
#else
|
||||
char *p = string_glob (argv[0]);
|
||||
o = variable_buffer_output (o, p, strlen (p));
|
||||
#endif
|
||||
return o;
|
||||
}
|
||||
|
||||
@ -1631,7 +1619,7 @@ shell_completed (int exit_code, int exit_sig)
|
||||
define_variable_cname (".SHELLSTATUS", buf, o_override, 0);
|
||||
}
|
||||
|
||||
#ifdef WINDOWS32
|
||||
#if MK_OS_W32
|
||||
/*untested*/
|
||||
|
||||
#include <windows.h>
|
||||
@ -1682,11 +1670,11 @@ windows32_openpipe (int *pipedes, int errfd, pid_t *pid_p, char **command_argv,
|
||||
if (hIn == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
ON (error, NILF,
|
||||
_("windows32_openpipe: DuplicateHandle(In) failed (e=%lu)\n"), e);
|
||||
_("windows32_openpipe: DuplicateHandle(In) failed (e=%lu)"), e);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
tmpErr = (HANDLE)_get_osfhandle (errfd);
|
||||
tmpErr = get_handle_for_fd (errfd);
|
||||
if (DuplicateHandle (GetCurrentProcess (), tmpErr,
|
||||
GetCurrentProcess (), &hErr,
|
||||
0, TRUE, DUPLICATE_SAME_ACCESS) == FALSE)
|
||||
@ -1706,14 +1694,14 @@ windows32_openpipe (int *pipedes, int errfd, pid_t *pid_p, char **command_argv,
|
||||
if (hErr == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
ON (error, NILF,
|
||||
_("windows32_openpipe: DuplicateHandle(Err) failed (e=%lu)\n"), e);
|
||||
_("windows32_openpipe: DuplicateHandle(Err) failed (e=%lu)"), e);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (! CreatePipe (&hChildOutRd, &hChildOutWr, &saAttr, 0))
|
||||
{
|
||||
ON (error, NILF, _("CreatePipe() failed (e=%lu)\n"), GetLastError());
|
||||
ON (error, NILF, _("CreatePipe() failed (e=%lu)"), GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1721,7 +1709,7 @@ windows32_openpipe (int *pipedes, int errfd, pid_t *pid_p, char **command_argv,
|
||||
|
||||
if (!hProcess)
|
||||
{
|
||||
O (error, NILF, _("windows32_openpipe(): process_init_fd() failed\n"));
|
||||
O (error, NILF, _("windows32_openpipe(): process_init_fd() failed"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1761,7 +1749,7 @@ windows32_openpipe (int *pipedes, int errfd, pid_t *pid_p, char **command_argv,
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __MSDOS__
|
||||
#if MK_OS_DOS
|
||||
FILE *
|
||||
msdos_openpipe (int* pipedes, int *pidp, char *text)
|
||||
{
|
||||
@ -1820,7 +1808,7 @@ msdos_openpipe (int* pipedes, int *pidp, char *text)
|
||||
Do shell spawning, with the naughty bits for different OSes.
|
||||
*/
|
||||
|
||||
#ifdef VMS
|
||||
#if MK_OS_VMS
|
||||
|
||||
/* VMS can't do $(shell ...) */
|
||||
|
||||
@ -1835,22 +1823,21 @@ func_shell_base (char *o, char **argv, int trim_newlines)
|
||||
#define func_shell 0
|
||||
|
||||
#else
|
||||
#ifndef _AMIGA
|
||||
char *
|
||||
func_shell_base (char *o, char **argv, int trim_newlines)
|
||||
{
|
||||
struct childbase child = {0};
|
||||
char *batch_filename = NULL;
|
||||
int errfd;
|
||||
#ifdef __MSDOS__
|
||||
#if MK_OS_DOS
|
||||
FILE *fpipe;
|
||||
#endif
|
||||
char **command_argv = NULL;
|
||||
int pipedes[2];
|
||||
pid_t pid;
|
||||
|
||||
#ifndef __MSDOS__
|
||||
#ifdef WINDOWS32
|
||||
#if !MK_OS_DOS
|
||||
#if MK_OS_W32
|
||||
/* Reset just_print_flag. This is needed on Windows when batch files
|
||||
are used to run the commands, because we normally refrain from
|
||||
creating batch files under -n. */
|
||||
@ -1863,12 +1850,12 @@ func_shell_base (char *o, char **argv, int trim_newlines)
|
||||
&batch_filename);
|
||||
if (command_argv == 0)
|
||||
{
|
||||
#ifdef WINDOWS32
|
||||
#if MK_OS_W32
|
||||
just_print_flag = j_p_f;
|
||||
#endif
|
||||
return o;
|
||||
}
|
||||
#endif /* !__MSDOS__ */
|
||||
#endif /* !MK_OS_DOS */
|
||||
|
||||
/* Set up the output in case the shell writes something. */
|
||||
output_start ();
|
||||
@ -1878,7 +1865,7 @@ func_shell_base (char *o, char **argv, int trim_newlines)
|
||||
|
||||
child.environment = target_environment (NULL, 0);
|
||||
|
||||
#if defined(__MSDOS__)
|
||||
#if MK_OS_DOS
|
||||
fpipe = msdos_openpipe (pipedes, &pid, argv[0]);
|
||||
if (pipedes[0] < 0)
|
||||
{
|
||||
@ -1887,7 +1874,7 @@ func_shell_base (char *o, char **argv, int trim_newlines)
|
||||
goto done;
|
||||
}
|
||||
|
||||
#elif defined(WINDOWS32)
|
||||
#elif MK_OS_W32
|
||||
windows32_openpipe (pipedes, errfd, &pid, command_argv, child.environment);
|
||||
/* Restore the value of just_print_flag. */
|
||||
just_print_flag = j_p_f;
|
||||
@ -1933,7 +1920,7 @@ func_shell_base (char *o, char **argv, int trim_newlines)
|
||||
|
||||
/* Record the PID for reap_children. */
|
||||
shell_function_pid = pid;
|
||||
#ifndef __MSDOS__
|
||||
#if !MK_OS_DOS
|
||||
shell_function_completed = 0;
|
||||
|
||||
/* Close the write side of the pipe. We test for -1, since
|
||||
@ -1964,7 +1951,7 @@ func_shell_base (char *o, char **argv, int trim_newlines)
|
||||
buffer[i] = '\0';
|
||||
|
||||
/* Close the read side of the pipe. */
|
||||
#ifdef __MSDOS__
|
||||
#if MK_OS_DOS
|
||||
if (fpipe)
|
||||
{
|
||||
int st = pclose (fpipe);
|
||||
@ -2009,100 +1996,12 @@ func_shell_base (char *o, char **argv, int trim_newlines)
|
||||
return o;
|
||||
}
|
||||
|
||||
#else /* _AMIGA */
|
||||
|
||||
/* Do the Amiga version of func_shell. */
|
||||
|
||||
char *
|
||||
func_shell_base (char *o, char **argv, int trim_newlines)
|
||||
{
|
||||
/* Amiga can't fork nor spawn, but I can start a program with
|
||||
redirection of my choice. However, this means that we
|
||||
don't have an opportunity to reopen stdout to trap it. Thus,
|
||||
we save our own stdout onto a new descriptor and dup a temp
|
||||
file's descriptor onto our stdout temporarily. After we
|
||||
spawn the shell program, we dup our own stdout back to the
|
||||
stdout descriptor. The buffer reading is the same as above,
|
||||
except that we're now reading from a file. */
|
||||
|
||||
#include <dos/dos.h>
|
||||
#include <proto/dos.h>
|
||||
|
||||
BPTR child_stdout;
|
||||
char tmp_output[FILENAME_MAX];
|
||||
size_t maxlen = 200, i;
|
||||
int cc;
|
||||
char * buffer, * ptr;
|
||||
char ** aptr;
|
||||
size_t len = 0;
|
||||
char* batch_filename = NULL;
|
||||
|
||||
/* Construct the argument list. */
|
||||
command_argv = construct_command_argv (argv[0], NULL, NULL, 0,
|
||||
&batch_filename);
|
||||
if (command_argv == 0)
|
||||
return o;
|
||||
|
||||
/* Note the mktemp() is a security hole, but this only runs on Amiga.
|
||||
Ideally we would use get_tmpfile(), but this uses a special Open(), not
|
||||
fopen(), and I'm not familiar enough with the code to mess with it. */
|
||||
strcpy (tmp_output, "t:MakeshXXXXXXXX");
|
||||
mktemp (tmp_output);
|
||||
child_stdout = Open (tmp_output, MODE_NEWFILE);
|
||||
|
||||
for (aptr=command_argv; *aptr; aptr++)
|
||||
len += strlen (*aptr) + 1;
|
||||
|
||||
buffer = xmalloc (len + 1);
|
||||
ptr = buffer;
|
||||
|
||||
for (aptr=command_argv; *aptr; aptr++)
|
||||
{
|
||||
strcpy (ptr, *aptr);
|
||||
ptr += strlen (ptr) + 1;
|
||||
*(ptr++) = ' ';
|
||||
*ptr = '\0';
|
||||
}
|
||||
|
||||
ptr[-1] = '\n';
|
||||
|
||||
Execute (buffer, NULL, child_stdout);
|
||||
free (buffer);
|
||||
|
||||
Close (child_stdout);
|
||||
|
||||
child_stdout = Open (tmp_output, MODE_OLDFILE);
|
||||
|
||||
buffer = xmalloc (maxlen);
|
||||
i = 0;
|
||||
do
|
||||
{
|
||||
if (i == maxlen)
|
||||
{
|
||||
maxlen += 512;
|
||||
buffer = xrealloc (buffer, maxlen + 1);
|
||||
}
|
||||
|
||||
cc = Read (child_stdout, &buffer[i], maxlen - i);
|
||||
if (cc > 0)
|
||||
i += cc;
|
||||
} while (cc > 0);
|
||||
|
||||
Close (child_stdout);
|
||||
|
||||
fold_newlines (buffer, &i, trim_newlines);
|
||||
o = variable_buffer_output (o, buffer, i);
|
||||
free (buffer);
|
||||
return o;
|
||||
}
|
||||
#endif /* _AMIGA */
|
||||
|
||||
static char *
|
||||
func_shell (char *o, char **argv, const char *funcname UNUSED)
|
||||
{
|
||||
return func_shell_base (o, argv, 1);
|
||||
}
|
||||
#endif /* !VMS */
|
||||
#endif /* !MK_OS_VMS */
|
||||
|
||||
#ifdef EXPERIMENTAL
|
||||
|
||||
@ -2113,7 +2012,8 @@ static char *
|
||||
func_eq (char *o, char **argv, char *funcname UNUSED)
|
||||
{
|
||||
int result = ! strcmp (argv[0], argv[1]);
|
||||
o = variable_buffer_output (o, result ? "1" : "", result);
|
||||
if (result)
|
||||
o = variable_buffer_output (o, "1", 1);
|
||||
return o;
|
||||
}
|
||||
|
||||
@ -2128,7 +2028,8 @@ func_not (char *o, char **argv, char *funcname UNUSED)
|
||||
int result = 0;
|
||||
NEXT_TOKEN (s);
|
||||
result = ! (*s);
|
||||
o = variable_buffer_output (o, result ? "1" : "", result);
|
||||
if (result)
|
||||
o = variable_buffer_output (o, "1", 1);
|
||||
return o;
|
||||
}
|
||||
#endif
|
||||
@ -2136,7 +2037,7 @@ func_not (char *o, char **argv, char *funcname UNUSED)
|
||||
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
# ifdef __CYGWIN__
|
||||
# define IS_ABSOLUTE(n) ((n[0] && n[1] == ':') || STOP_SET (n[0], MAP_DIRSEP))
|
||||
# define IS_ABSOLUTE(n) ((n[0] && n[1] == ':') || ISDIRSEP (n[0]))
|
||||
# else
|
||||
# define IS_ABSOLUTE(n) (n[0] && n[1] == ':')
|
||||
# endif
|
||||
@ -2170,9 +2071,9 @@ abspath (const char *name, char *apath)
|
||||
strcpy (apath, starting_directory);
|
||||
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
if (STOP_SET (name[0], MAP_DIRSEP))
|
||||
if (ISDIRSEP (name[0]))
|
||||
{
|
||||
if (STOP_SET (name[1], MAP_DIRSEP))
|
||||
if (ISDIRSEP (name[1]))
|
||||
{
|
||||
/* A UNC. Don't prepend a drive letter. */
|
||||
apath[0] = name[0];
|
||||
@ -2192,7 +2093,7 @@ abspath (const char *name, char *apath)
|
||||
else
|
||||
{
|
||||
#if defined(__CYGWIN__) && defined(HAVE_DOS_PATHS)
|
||||
if (STOP_SET (name[0], MAP_DIRSEP))
|
||||
if (ISDIRSEP (name[0]))
|
||||
root_len = 1;
|
||||
#endif
|
||||
memcpy (apath, name, root_len);
|
||||
@ -2201,14 +2102,14 @@ abspath (const char *name, char *apath)
|
||||
/* Get past the root, since we already copied it. */
|
||||
name += root_len;
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
if (! STOP_SET (apath[root_len - 1], MAP_DIRSEP))
|
||||
if (! ISDIRSEP (apath[root_len - 1]))
|
||||
{
|
||||
/* Convert d:foo into d:./foo and increase root_len. */
|
||||
apath[2] = '.';
|
||||
apath[3] = '/';
|
||||
dest++;
|
||||
root_len++;
|
||||
/* strncpy above copied one character too many. */
|
||||
/* memcpy above copied one character too many. */
|
||||
name--;
|
||||
}
|
||||
else
|
||||
@ -2218,10 +2119,10 @@ abspath (const char *name, char *apath)
|
||||
|
||||
for (start = end = name; *start != '\0'; start = end)
|
||||
{
|
||||
size_t len;
|
||||
ptrdiff_t len;
|
||||
|
||||
/* Skip sequence of multiple path-separators. */
|
||||
while (STOP_SET (*start, MAP_DIRSEP))
|
||||
while (ISDIRSEP (*start))
|
||||
++start;
|
||||
|
||||
/* Find end of path component. */
|
||||
@ -2238,15 +2139,15 @@ abspath (const char *name, char *apath)
|
||||
{
|
||||
/* Back up to previous component, ignore if at root already. */
|
||||
if (dest > apath + root_len)
|
||||
for (--dest; ! STOP_SET (dest[-1], MAP_DIRSEP); --dest)
|
||||
for (--dest; ! ISDIRSEP (dest[-1]); --dest)
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (! STOP_SET (dest[-1], MAP_DIRSEP))
|
||||
if (! ISDIRSEP (dest[-1]))
|
||||
*dest++ = '/';
|
||||
|
||||
if (dest + len >= apath_limit)
|
||||
if (apath_limit - dest <= len)
|
||||
return NULL;
|
||||
|
||||
dest = mempcpy (dest, start, len);
|
||||
@ -2255,7 +2156,7 @@ abspath (const char *name, char *apath)
|
||||
}
|
||||
|
||||
/* Unless it is root strip trailing separator. */
|
||||
if (dest > apath + root_len && STOP_SET (dest[-1], MAP_DIRSEP))
|
||||
if (dest > apath + root_len && ISDIRSEP (dest[-1]))
|
||||
--dest;
|
||||
|
||||
*dest = '\0';
|
||||
@ -2277,13 +2178,13 @@ func_realpath (char *o, char **argv, const char *funcname UNUSED)
|
||||
{
|
||||
if (len < GET_PATH_MAX)
|
||||
{
|
||||
char *rp;
|
||||
char *rp, *inend;
|
||||
struct stat st;
|
||||
PATH_VAR (in);
|
||||
PATH_VAR (out);
|
||||
|
||||
strncpy (in, path, len);
|
||||
in[len] = '\0';
|
||||
inend = mempcpy (in, path, len);
|
||||
*inend = '\0';
|
||||
|
||||
#ifdef HAVE_REALPATH
|
||||
ENULLLOOP (rp, realpath (in, out));
|
||||
@ -2328,6 +2229,10 @@ func_file (char *o, char **argv, const char *funcname UNUSED)
|
||||
|
||||
if (fn[0] == '>')
|
||||
{
|
||||
size_t len;
|
||||
const char *end;
|
||||
const char *start;
|
||||
char *nm;
|
||||
FILE *fp;
|
||||
const char *mode = "w";
|
||||
|
||||
@ -2338,14 +2243,21 @@ func_file (char *o, char **argv, const char *funcname UNUSED)
|
||||
mode = "a";
|
||||
++fn;
|
||||
}
|
||||
NEXT_TOKEN (fn);
|
||||
|
||||
if (fn[0] == '\0')
|
||||
start = next_token (fn);
|
||||
|
||||
if (start[0] == '\0')
|
||||
O (fatal, *expanding_var, _("file: missing filename"));
|
||||
|
||||
ENULLLOOP (fp, fopen (fn, mode));
|
||||
end = end_of_token (start);
|
||||
len = end - start;
|
||||
nm = alloca (len + 1);
|
||||
memcpy (nm, start, len);
|
||||
nm[len] = '\0';
|
||||
|
||||
ENULLLOOP (fp, fopen (nm, mode));
|
||||
if (fp == NULL)
|
||||
OSS (fatal, reading_file, _("open: %s: %s"), fn, strerror (errno));
|
||||
OSS (fatal, reading_file, _("open: %s: %s"), nm, strerror (errno));
|
||||
|
||||
/* We've changed the contents of a directory, possibly.
|
||||
Another option would be to look up the directory we changed and reset
|
||||
@ -2358,30 +2270,44 @@ func_file (char *o, char **argv, const char *funcname UNUSED)
|
||||
int nl = l == 0 || argv[1][l-1] != '\n';
|
||||
|
||||
if (fputs (argv[1], fp) == EOF || (nl && fputc ('\n', fp) == EOF))
|
||||
OSS (fatal, reading_file, _("write: %s: %s"), fn, strerror (errno));
|
||||
OSS (fatal, reading_file, _("write: %s: %s"), nm, strerror (errno));
|
||||
}
|
||||
if (fclose (fp))
|
||||
OSS (fatal, reading_file, _("close: %s: %s"), fn, strerror (errno));
|
||||
OSS (fatal, reading_file, _("close: %s: %s"), nm, strerror (errno));
|
||||
}
|
||||
else if (fn[0] == '<')
|
||||
{
|
||||
size_t n = 0;
|
||||
size_t len;
|
||||
const char *end;
|
||||
const char *start;
|
||||
char *nm;
|
||||
FILE *fp;
|
||||
|
||||
++fn;
|
||||
NEXT_TOKEN (fn);
|
||||
if (fn[0] == '\0')
|
||||
start = next_token (fn + 1);
|
||||
|
||||
if (start[0] == '\0')
|
||||
O (fatal, *expanding_var, _("file: missing filename"));
|
||||
|
||||
if (argv[1])
|
||||
O (fatal, *expanding_var, _("file: too many arguments"));
|
||||
|
||||
ENULLLOOP (fp, fopen (fn, "r"));
|
||||
end = end_of_token (start);
|
||||
len = end - start;
|
||||
nm = alloca (len + 1);
|
||||
memcpy (nm, start, len);
|
||||
nm[len] = '\0';
|
||||
|
||||
ENULLLOOP (fp, fopen (nm, "r"));
|
||||
if (fp == NULL)
|
||||
{
|
||||
if (errno == ENOENT)
|
||||
return o;
|
||||
OSS (fatal, reading_file, _("open: %s: %s"), fn, strerror (errno));
|
||||
{
|
||||
DB (DB_VERBOSE, (_("file: Failed to open '%s': %s\n"),
|
||||
nm, strerror (errno)));
|
||||
return o;
|
||||
}
|
||||
OSS (fatal, reading_file, _("open: %s: %s"), nm, strerror (errno));
|
||||
}
|
||||
|
||||
while (1)
|
||||
@ -2395,12 +2321,12 @@ func_file (char *o, char **argv, const char *funcname UNUSED)
|
||||
}
|
||||
if (ferror (fp))
|
||||
if (errno != EINTR)
|
||||
OSS (fatal, reading_file, _("read: %s: %s"), fn, strerror (errno));
|
||||
OSS (fatal, reading_file, _("read: %s: %s"), nm, strerror (errno));
|
||||
if (feof (fp))
|
||||
break;
|
||||
}
|
||||
if (fclose (fp))
|
||||
OSS (fatal, reading_file, _("close: %s: %s"), fn, strerror (errno));
|
||||
OSS (fatal, reading_file, _("close: %s: %s"), nm, strerror (errno));
|
||||
|
||||
/* Remove trailing newline. */
|
||||
if (n && o[-1] == '\n')
|
||||
@ -2427,9 +2353,9 @@ func_abspath (char *o, char **argv, const char *funcname UNUSED)
|
||||
{
|
||||
PATH_VAR (in);
|
||||
PATH_VAR (out);
|
||||
char *inend = mempcpy (in, path, len);
|
||||
|
||||
strncpy (in, path, len);
|
||||
in[len] = '\0';
|
||||
*inend = '\0';
|
||||
|
||||
if (abspath (in, out))
|
||||
{
|
||||
@ -2465,67 +2391,65 @@ static char *func_call (char *o, char **argv, const char *funcname);
|
||||
#define FT_ENTRY(_name, _min, _max, _exp, _func) \
|
||||
{ { (_func) }, STRING_SIZE_TUPLE(_name), (_min), (_max), (_exp), 0, 0 }
|
||||
|
||||
static struct function_table_entry function_table_init[] =
|
||||
static const struct function_table_entry function_table_init[] =
|
||||
{
|
||||
/* Name MIN MAX EXP? Function */
|
||||
FT_ENTRY ("abspath", 0, 1, 1, func_abspath),
|
||||
FT_ENTRY ("addprefix", 2, 2, 1, func_addsuffix_addprefix),
|
||||
FT_ENTRY ("addsuffix", 2, 2, 1, func_addsuffix_addprefix),
|
||||
FT_ENTRY ("and", 1, 0, 0, func_and),
|
||||
FT_ENTRY ("basename", 0, 1, 1, func_basename_dir),
|
||||
FT_ENTRY ("call", 1, 0, 1, func_call),
|
||||
FT_ENTRY ("dir", 0, 1, 1, func_basename_dir),
|
||||
FT_ENTRY ("notdir", 0, 1, 1, func_notdir_suffix),
|
||||
FT_ENTRY ("subst", 3, 3, 1, func_subst),
|
||||
FT_ENTRY ("suffix", 0, 1, 1, func_notdir_suffix),
|
||||
FT_ENTRY ("error", 0, 1, 1, func_error),
|
||||
FT_ENTRY ("eval", 0, 1, 1, func_eval),
|
||||
FT_ENTRY ("file", 1, 2, 1, func_file),
|
||||
FT_ENTRY ("filter", 2, 2, 1, func_filter_filterout),
|
||||
FT_ENTRY ("filter-out", 2, 2, 1, func_filter_filterout),
|
||||
FT_ENTRY ("findstring", 2, 2, 1, func_findstring),
|
||||
FT_ENTRY ("firstword", 0, 1, 1, func_firstword),
|
||||
FT_ENTRY ("flavor", 0, 1, 1, func_flavor),
|
||||
FT_ENTRY ("foreach", 3, 3, 0, func_foreach),
|
||||
FT_ENTRY ("if", 2, 3, 0, func_if),
|
||||
FT_ENTRY ("info", 0, 1, 1, func_error),
|
||||
FT_ENTRY ("intcmp", 2, 5, 0, func_intcmp),
|
||||
FT_ENTRY ("join", 2, 2, 1, func_join),
|
||||
FT_ENTRY ("lastword", 0, 1, 1, func_lastword),
|
||||
FT_ENTRY ("let", 3, 3, 0, func_let),
|
||||
FT_ENTRY ("notdir", 0, 1, 1, func_notdir_suffix),
|
||||
FT_ENTRY ("or", 1, 0, 0, func_or),
|
||||
FT_ENTRY ("origin", 0, 1, 1, func_origin),
|
||||
FT_ENTRY ("patsubst", 3, 3, 1, func_patsubst),
|
||||
FT_ENTRY ("realpath", 0, 1, 1, func_realpath),
|
||||
FT_ENTRY ("shell", 0, 1, 1, func_shell),
|
||||
FT_ENTRY ("sort", 0, 1, 1, func_sort),
|
||||
FT_ENTRY ("strip", 0, 1, 1, func_strip),
|
||||
FT_ENTRY ("subst", 3, 3, 1, func_subst),
|
||||
FT_ENTRY ("suffix", 0, 1, 1, func_notdir_suffix),
|
||||
FT_ENTRY ("value", 0, 1, 1, func_value),
|
||||
FT_ENTRY ("warning", 0, 1, 1, func_error),
|
||||
FT_ENTRY ("wildcard", 0, 1, 1, func_wildcard),
|
||||
FT_ENTRY ("word", 2, 2, 1, func_word),
|
||||
FT_ENTRY ("wordlist", 3, 3, 1, func_wordlist),
|
||||
FT_ENTRY ("words", 0, 1, 1, func_words),
|
||||
FT_ENTRY ("origin", 0, 1, 1, func_origin),
|
||||
FT_ENTRY ("foreach", 3, 3, 0, func_foreach),
|
||||
FT_ENTRY ("let", 3, 3, 0, func_let),
|
||||
FT_ENTRY ("call", 1, 0, 1, func_call),
|
||||
FT_ENTRY ("info", 0, 1, 1, func_error),
|
||||
FT_ENTRY ("error", 0, 1, 1, func_error),
|
||||
FT_ENTRY ("warning", 0, 1, 1, func_error),
|
||||
FT_ENTRY ("intcmp", 2, 5, 0, func_intcmp),
|
||||
FT_ENTRY ("if", 2, 3, 0, func_if),
|
||||
FT_ENTRY ("or", 1, 0, 0, func_or),
|
||||
FT_ENTRY ("and", 1, 0, 0, func_and),
|
||||
FT_ENTRY ("value", 0, 1, 1, func_value),
|
||||
FT_ENTRY ("eval", 0, 1, 1, func_eval),
|
||||
FT_ENTRY ("file", 1, 2, 1, func_file),
|
||||
#ifdef EXPERIMENTAL
|
||||
FT_ENTRY ("eq", 2, 2, 1, func_eq),
|
||||
FT_ENTRY ("not", 0, 1, 1, func_not),
|
||||
#endif
|
||||
};
|
||||
|
||||
#define FUNCTION_TABLE_ENTRIES (sizeof (function_table_init) / sizeof (struct function_table_entry))
|
||||
|
||||
|
||||
/* These must come after the definition of function_table. */
|
||||
|
||||
static char *
|
||||
expand_builtin_function (char *o, int argc, char **argv,
|
||||
expand_builtin_function (char *o, unsigned int argc, char **argv,
|
||||
const struct function_table_entry *entry_p)
|
||||
{
|
||||
char *p;
|
||||
|
||||
if (argc < (int)entry_p->minimum_args)
|
||||
if (argc < entry_p->minimum_args)
|
||||
fatal (*expanding_var, strlen (entry_p->name),
|
||||
_("insufficient number of arguments (%d) to function '%s'"),
|
||||
_("insufficient number of arguments (%u) to function '%s'"),
|
||||
argc, entry_p->name);
|
||||
|
||||
/* I suppose technically some function could do something with no arguments,
|
||||
@ -2561,7 +2485,8 @@ expand_builtin_function (char *o, int argc, char **argv,
|
||||
/* Check for a function invocation in *STRINGP. *STRINGP points at the
|
||||
opening ( or { and is not null-terminated. If a function invocation
|
||||
is found, expand it into the buffer at *OP, updating *OP, incrementing
|
||||
*STRINGP past the reference and returning nonzero. If not, return zero. */
|
||||
*STRINGP past the reference, and return nonzero.
|
||||
If no function is found, return zero and don't change *OP or *STRINGP. */
|
||||
|
||||
int
|
||||
handle_function (char **op, const char **stringp)
|
||||
@ -2574,7 +2499,7 @@ handle_function (char **op, const char **stringp)
|
||||
int count = 0;
|
||||
char *abeg = NULL;
|
||||
char **argv, **argvp;
|
||||
int nargs;
|
||||
unsigned int nargs;
|
||||
|
||||
beg = *stringp + 1;
|
||||
|
||||
@ -2589,10 +2514,10 @@ handle_function (char **op, const char **stringp)
|
||||
beg += entry_p->len;
|
||||
NEXT_TOKEN (beg);
|
||||
|
||||
/* Find the end of the function invocation, counting nested use of
|
||||
whichever kind of parens we use. Since we're looking, count commas
|
||||
to get a rough estimate of how many arguments we might have. The
|
||||
count might be high, but it'll never be low. */
|
||||
/* Find the end of the function invocation, counting nested use of whichever
|
||||
kind of parens we use. Don't use skip_reference so we can count commas
|
||||
to get a rough estimate of how many arguments we might have. The count
|
||||
might be high, but it'll never be low. */
|
||||
|
||||
for (nargs=1, end=beg; *end != '\0'; ++end)
|
||||
if (!STOP_SET (*end, MAP_VARSEP|MAP_COMMA))
|
||||
@ -2686,11 +2611,10 @@ handle_function (char **op, const char **stringp)
|
||||
static char *
|
||||
func_call (char *o, char **argv, const char *funcname UNUSED)
|
||||
{
|
||||
static int max_args = 0;
|
||||
static unsigned int max_args = 0;
|
||||
char *fname;
|
||||
char *body;
|
||||
size_t flen;
|
||||
int i;
|
||||
unsigned int i;
|
||||
int saved_args;
|
||||
const struct function_table_entry *entry_p;
|
||||
struct variable *v;
|
||||
@ -2726,13 +2650,6 @@ func_call (char *o, char **argv, const char *funcname UNUSED)
|
||||
if (v == 0 || *v->value == '\0')
|
||||
return o;
|
||||
|
||||
body = alloca (flen + 4);
|
||||
body[0] = '$';
|
||||
body[1] = '(';
|
||||
memcpy (body + 2, fname, flen);
|
||||
body[flen+2] = ')';
|
||||
body[flen+3] = '\0';
|
||||
|
||||
/* Set up arguments $(1) .. $(N). $(0) is the function name. */
|
||||
|
||||
push_new_variable_scope ();
|
||||
@ -2741,8 +2658,7 @@ func_call (char *o, char **argv, const char *funcname UNUSED)
|
||||
{
|
||||
char num[INTSTR_LENGTH];
|
||||
|
||||
sprintf (num, "%d", i);
|
||||
define_variable (num, strlen (num), *argv, o_automatic, 0);
|
||||
define_variable (num, sprintf (num, "%u", i), *argv, o_automatic, 0);
|
||||
}
|
||||
|
||||
/* If the number of arguments we have is < max_args, it means we're inside
|
||||
@ -2754,18 +2670,17 @@ func_call (char *o, char **argv, const char *funcname UNUSED)
|
||||
{
|
||||
char num[INTSTR_LENGTH];
|
||||
|
||||
sprintf (num, "%d", i);
|
||||
define_variable (num, strlen (num), "", o_automatic, 0);
|
||||
define_variable (num, sprintf (num, "%u", i), "", o_automatic, 0);
|
||||
}
|
||||
|
||||
/* Expand the body in the context of the arguments, adding the result to
|
||||
/* Expand the function in the context of the arguments, adding the result to
|
||||
the variable buffer. */
|
||||
|
||||
v->exp_count = EXP_COUNT_MAX;
|
||||
|
||||
saved_args = max_args;
|
||||
max_args = i;
|
||||
o = variable_expand_string (o, body, flen+3);
|
||||
o = expand_variable_output (o, fname, flen);
|
||||
max_args = saved_args;
|
||||
|
||||
v->exp_count = 0;
|
||||
@ -2789,20 +2704,20 @@ define_new_function (const floc *flocp, const char *name,
|
||||
len = e - name;
|
||||
|
||||
if (len == 0)
|
||||
O (fatal, flocp, _("Empty function name"));
|
||||
O (fatal, flocp, _("empty function name"));
|
||||
if (*name == '.' || *e != '\0')
|
||||
OS (fatal, flocp, _("Invalid function name: %s"), name);
|
||||
OS (fatal, flocp, _("invalid function name: %s"), name);
|
||||
if (len > 255)
|
||||
OS (fatal, flocp, _("Function name too long: %s"), name);
|
||||
OS (fatal, flocp, _("function name too long: %s"), name);
|
||||
if (min > 255)
|
||||
ONS (fatal, flocp,
|
||||
_("Invalid minimum argument count (%u) for function %s"), min, name);
|
||||
_("invalid minimum argument count (%u) for function %s"), min, name);
|
||||
if (max > 255 || (max && max < min))
|
||||
ONS (fatal, flocp,
|
||||
_("Invalid maximum argument count (%u) for function %s"), max, name);
|
||||
_("invalid maximum argument count (%u) for function %s"), max, name);
|
||||
|
||||
ent = xmalloc (sizeof (struct function_table_entry));
|
||||
ent->name = name;
|
||||
ent->name = strcache_add (name);
|
||||
ent->len = (unsigned char) len;
|
||||
ent->minimum_args = (unsigned char) min;
|
||||
ent->maximum_args = (unsigned char) max;
|
||||
@ -2812,15 +2727,16 @@ define_new_function (const floc *flocp, const char *name,
|
||||
ent->adds_command = 1;
|
||||
ent->fptr.alloc_func_ptr = func;
|
||||
|
||||
hash_insert (&function_table, ent);
|
||||
ent = hash_insert (&function_table, ent);
|
||||
free (ent);
|
||||
}
|
||||
|
||||
void
|
||||
hash_init_function_table (void)
|
||||
{
|
||||
hash_init (&function_table, FUNCTION_TABLE_ENTRIES * 2,
|
||||
hash_init (&function_table, ARRAYLEN (function_table_init) * 2,
|
||||
function_table_entry_hash_1, function_table_entry_hash_2,
|
||||
function_table_entry_hash_cmp);
|
||||
hash_load (&function_table, function_table_init,
|
||||
FUNCTION_TABLE_ENTRIES, sizeof (struct function_table_entry));
|
||||
ARRAYLEN (function_table_init), sizeof (struct function_table_entry));
|
||||
}
|
||||
|
33
src/getopt.c
33
src/getopt.c
@ -3,7 +3,7 @@ NOTE: getopt is now part of the C library, so if you don't know what
|
||||
"Keep this file name-space clean" means, talk to drepper@gnu.org
|
||||
before changing it!
|
||||
|
||||
Copyright (C) 1987-2022 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2024 Free Software Foundation, Inc.
|
||||
|
||||
NOTE: The canonical source of this file is maintained with the GNU C Library.
|
||||
Bugs can be reported to bug-glibc@gnu.org.
|
||||
@ -18,7 +18,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
|
||||
Ditto for AIX 3.2 and <stdlib.h>. */
|
||||
@ -68,7 +68,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
# include <unistd.h>
|
||||
#endif /* GNU C library. */
|
||||
|
||||
#ifdef VMS
|
||||
#if MK_OS_VMS
|
||||
# include <unixlib.h>
|
||||
# if HAVE_STRING_H - 0
|
||||
# include <string.h>
|
||||
@ -436,6 +436,10 @@ _getopt_initialize (int argc, char *const *argv, const char *optstring)
|
||||
nonoption_flags_len = 0;
|
||||
#endif
|
||||
|
||||
/* Make the compiler happy. */
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
return optstring;
|
||||
}
|
||||
|
||||
@ -677,17 +681,18 @@ _getopt_internal (int argc, char *const *argv, const char *optstring,
|
||||
else
|
||||
{
|
||||
if (opterr)
|
||||
if (argv[optind - 1][1] == '-')
|
||||
/* --option */
|
||||
fprintf (stderr,
|
||||
_("%s: option '--%s' doesn't allow an argument\n"),
|
||||
argv[0], pfound->name);
|
||||
else
|
||||
/* +option or -option */
|
||||
fprintf (stderr,
|
||||
_("%s: option '%c%s' doesn't allow an argument\n"),
|
||||
argv[0], argv[optind - 1][0], pfound->name);
|
||||
|
||||
{
|
||||
if (argv[optind - 1][1] == '-')
|
||||
/* --option */
|
||||
fprintf (stderr,
|
||||
_("%s: option '--%s' doesn't allow an argument\n"),
|
||||
argv[0], pfound->name);
|
||||
else
|
||||
/* +option or -option */
|
||||
fprintf (stderr,
|
||||
_("%s: option '%c%s' doesn't allow an argument\n"),
|
||||
argv[0], argv[optind - 1][0], pfound->name);
|
||||
}
|
||||
nextchar += strlen (nextchar);
|
||||
|
||||
optopt = pfound->val;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Declarations for getopt.
|
||||
Copyright (C) 1989-2022 Free Software Foundation, Inc.
|
||||
Copyright (C) 1989-2024 Free Software Foundation, Inc.
|
||||
|
||||
NOTE: The canonical source of this file is maintained with the GNU C Library.
|
||||
Bugs can be reported to bug-glibc@gnu.org.
|
||||
@ -14,7 +14,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _GETOPT_H
|
||||
#define _GETOPT_H 1
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* getopt_long and getopt_long_only entry points for GNU getopt.
|
||||
Copyright (C) 1987-1994, 1996-2022 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-1994, 1996-2024 Free Software Foundation, Inc.
|
||||
|
||||
NOTE: The canonical source of this file is maintained with the GNU C Library.
|
||||
Bugs can be reported to bug-glibc@gnu.org.
|
||||
@ -14,7 +14,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Convenience header for conditional use of GNU <libintl.h>.
|
||||
Copyright (C) 1995-2022 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995-2024 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
@ -12,7 +12,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _LIBGETTEXT_H
|
||||
#define _LIBGETTEXT_H 1
|
||||
|
@ -1,5 +1,5 @@
|
||||
;; Contents of the (gnu make) Guile module
|
||||
;; Copyright (C) 2011-2022 Free Software Foundation, Inc.
|
||||
;; Contents of the (GNU Make) Guile module
|
||||
;; Copyright (C) 2011-2024 Free Software Foundation, Inc.
|
||||
;; This file is part of GNU Make.
|
||||
;;
|
||||
;; GNU Make is free software; you can redistribute it and/or modify it under
|
||||
@ -13,11 +13,11 @@
|
||||
;; details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License along
|
||||
;; with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
;; with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
(define (to-string-maybe x)
|
||||
(cond
|
||||
;; In GNU make, "false" is the empty string
|
||||
;; In GNU Make, "false" is the empty string
|
||||
((or (not x)
|
||||
(unspecified? x)
|
||||
(variable? x)
|
||||
@ -45,7 +45,7 @@
|
||||
(walk x)
|
||||
(string-join (reverse! acc))))
|
||||
|
||||
;; Return the value of the GNU make variable V
|
||||
;; Return the value of the GNU Make variable V
|
||||
(define (gmk-var v)
|
||||
(gmk-expand (format #f "$(~a)" (obj-to-str v))))
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
/* External interfaces usable by dynamic objects loaded into GNU Make.
|
||||
--THIS API IS A "TECHNOLOGY PREVIEW" ONLY. IT IS NOT A STABLE INTERFACE--
|
||||
|
||||
Copyright (C) 2013-2022 Free Software Foundation, Inc.
|
||||
Copyright (C) 2013-2024 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
@ -14,11 +13,13 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _GNUMAKE_H_
|
||||
#define _GNUMAKE_H_
|
||||
|
||||
#define GMK_ABI_VERSION 1
|
||||
|
||||
/* Specify the location of elements read from makefiles. */
|
||||
typedef struct
|
||||
{
|
||||
@ -28,6 +29,23 @@ typedef struct
|
||||
|
||||
typedef char *(*gmk_func_ptr)(const char *nm, unsigned int argc, char **argv);
|
||||
|
||||
/* When an object is loaded by GNU Make, a setup method will be invoked.
|
||||
The name of the method is either derived from the filename of the object,
|
||||
or specified explicitly in the makefile. It has the signature:
|
||||
|
||||
int <setup_fn> (unsigned int abi_version, const gmk_floc *flocp);
|
||||
|
||||
The abi_version will be set to GMK_ABI_VERSION.
|
||||
|
||||
When an object is unloaded by GNU Make, an unload method will be invoked.
|
||||
The name of the method is derived from the filename of the object, with
|
||||
_gmk_unload appended. It has the signature:
|
||||
|
||||
void <object>_gmk_unload (void);
|
||||
|
||||
There will only be one unload method invoked regardless of the number of
|
||||
setup methods within the object. */
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifdef GMK_BUILDING_MAKE
|
||||
# define GMK_EXPORT __declspec(dllexport)
|
||||
@ -38,26 +56,26 @@ typedef char *(*gmk_func_ptr)(const char *nm, unsigned int argc, char **argv);
|
||||
# define GMK_EXPORT
|
||||
#endif
|
||||
|
||||
/* Free memory returned by the gmk_expand() function. */
|
||||
/* Free memory returned by the gmk_expand() and gmk_free() functions. */
|
||||
GMK_EXPORT void gmk_free (char *str);
|
||||
|
||||
/* Allocate memory in GNU make's context. */
|
||||
/* Allocate memory in GNU Make's context. */
|
||||
GMK_EXPORT char *gmk_alloc (unsigned int len);
|
||||
|
||||
/* Run $(eval ...) on the provided string BUFFER. */
|
||||
GMK_EXPORT void gmk_eval (const char *buffer, const gmk_floc *floc);
|
||||
|
||||
/* Run GNU make expansion on the provided string STR.
|
||||
/* Run GNU Make expansion on the provided string STR.
|
||||
Returns an allocated buffer that the caller must free with gmk_free(). */
|
||||
GMK_EXPORT char *gmk_expand (const char *str);
|
||||
|
||||
/* Register a new GNU make function NAME (maximum of 255 chars long).
|
||||
/* 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
|
||||
the appropriate arguments.
|
||||
|
||||
The return value of FUNC must be either NULL, in which case it expands to
|
||||
the empty string, or a pointer to the result of the expansion in a string
|
||||
created by gmk_alloc(). GNU make will free the memory when it's done.
|
||||
created by gmk_alloc(). GNU Make will free the memory when it's done.
|
||||
|
||||
MIN_ARGS is the minimum number of arguments the function requires.
|
||||
MAX_ARGS is the maximum number of arguments (or 0 if there's no maximum).
|
||||
|
20
src/guile.c
20
src/guile.c
@ -1,5 +1,5 @@
|
||||
/* GNU Guile interface for GNU Make.
|
||||
Copyright (C) 2011-2022 Free Software Foundation, Inc.
|
||||
Copyright (C) 2011-2024 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
@ -12,7 +12,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "makeint.h"
|
||||
|
||||
@ -47,7 +47,7 @@ cvt_scm_to_str (SCM obj)
|
||||
return scm_to_locale_string (scm_call_1 (obj_to_str, obj));
|
||||
}
|
||||
|
||||
/* Perform the GNU make expansion function. */
|
||||
/* Perform the GNU Make expansion function. */
|
||||
static SCM
|
||||
guile_expand_wrapper (SCM obj)
|
||||
{
|
||||
@ -65,7 +65,7 @@ guile_expand_wrapper (SCM obj)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Perform the GNU make eval function. */
|
||||
/* Perform the GNU Make eval function. */
|
||||
static SCM
|
||||
guile_eval_wrapper (SCM obj)
|
||||
{
|
||||
@ -77,24 +77,24 @@ guile_eval_wrapper (SCM obj)
|
||||
return SCM_BOOL_F;
|
||||
}
|
||||
|
||||
/* Invoked by scm_c_define_module(), in the context of the GNU make module. */
|
||||
/* Invoked by scm_c_define_module(), in the context of the GNU Make module. */
|
||||
static void
|
||||
guile_define_module (void *data UNUSED)
|
||||
{
|
||||
/* Ingest the predefined Guile module for GNU make. */
|
||||
/* Ingest the predefined Guile module for GNU Make. */
|
||||
#include "gmk-default.h"
|
||||
|
||||
/* Register a subr for GNU make's eval capability. */
|
||||
/* Register a subr for GNU Make's eval capability. */
|
||||
scm_c_define_gsubr ("gmk-expand", 1, 0, 0, (GSUBR_TYPE) guile_expand_wrapper);
|
||||
|
||||
/* Register a subr for GNU make's eval capability. */
|
||||
/* Register a subr for GNU Make's eval capability. */
|
||||
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);
|
||||
}
|
||||
|
||||
/* Initialize the GNU make Guile module. */
|
||||
/* Initialize the GNU Make Guile module. */
|
||||
static void *
|
||||
guile_init (void *arg UNUSED)
|
||||
{
|
||||
@ -104,7 +104,7 @@ guile_init (void *arg UNUSED)
|
||||
/* Get a reference to the object-to-string translator, for later. */
|
||||
obj_to_str = scm_variable_ref (scm_c_module_lookup (make_mod, "obj-to-str"));
|
||||
|
||||
/* Import the GNU make module exports into the generic space. */
|
||||
/* Import the GNU Make module exports into the generic space. */
|
||||
scm_c_eval_string ("(use-modules (gnu make))");
|
||||
|
||||
return NULL;
|
||||
|
28
src/hash.c
28
src/hash.c
@ -12,7 +12,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "makeint.h"
|
||||
#include "hash.h"
|
||||
@ -33,7 +33,7 @@ static unsigned long round_up_2 __P((unsigned long rough));
|
||||
potentially hit every slot in the table during collision
|
||||
resolution. */
|
||||
|
||||
void *hash_deleted_item = &hash_deleted_item;
|
||||
const void *hash_deleted_item = &hash_deleted_item;
|
||||
|
||||
/* Force the table size to be a power of two, possibly rounding up the
|
||||
given size. */
|
||||
@ -65,10 +65,10 @@ hash_init (struct hash_table *ht, unsigned long size,
|
||||
/* Load an array of items into 'ht'. */
|
||||
|
||||
void
|
||||
hash_load (struct hash_table *ht, void *item_table,
|
||||
hash_load (struct hash_table *ht, const void *item_table,
|
||||
unsigned long cardinality, unsigned long size)
|
||||
{
|
||||
char *items = (char *) item_table;
|
||||
const char *items = (const char *) item_table;
|
||||
while (cardinality--)
|
||||
{
|
||||
hash_insert (ht, items);
|
||||
@ -361,7 +361,7 @@ round_up_2 (unsigned long n)
|
||||
#define sum_get_unaligned_32(r, p) \
|
||||
do { \
|
||||
unsigned int val; \
|
||||
memcpy(&val, (p), 4); \
|
||||
memcpy (&val, (p), 4); \
|
||||
r += val; \
|
||||
} while(0);
|
||||
|
||||
@ -413,13 +413,16 @@ jhash(unsigned const char *k, int length)
|
||||
#define UINTSZ sizeof (unsigned int)
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
/* The ifs are ordered from the first byte in memory to the last. */
|
||||
/* The ifs are ordered from the first byte in memory to the last.
|
||||
Help the compiler optimize by using static memcpy length. */
|
||||
#define sum_up_to_nul(r, p, plen, flag) \
|
||||
do { \
|
||||
unsigned int val = 0; \
|
||||
size_t pn = (plen); \
|
||||
size_t n = pn < UINTSZ ? pn : UINTSZ; \
|
||||
memcpy (&val, (p), n); \
|
||||
if (pn >= UINTSZ) \
|
||||
memcpy (&val, (p), UINTSZ); \
|
||||
else \
|
||||
memcpy (&val, (p), pn); \
|
||||
if ((val & 0xFF000000) == 0) \
|
||||
flag = 1; \
|
||||
else if ((val & 0xFF0000) == 0) \
|
||||
@ -432,13 +435,16 @@ jhash(unsigned const char *k, int length)
|
||||
#else
|
||||
/* First detect the presence of zeroes. If there is none, we can
|
||||
sum the 4 bytes directly. Otherwise, the ifs are ordered as in the
|
||||
big endian case, from the first byte in memory to the last. */
|
||||
big endian case, from the first byte in memory to the last.
|
||||
Help the compiler optimize by using static memcpy length. */
|
||||
#define sum_up_to_nul(r, p, plen, flag) \
|
||||
do { \
|
||||
unsigned int val = 0; \
|
||||
size_t pn = (plen); \
|
||||
size_t n = pn < UINTSZ ? pn : UINTSZ; \
|
||||
memcpy (&val, (p), n); \
|
||||
if (pn >= UINTSZ) \
|
||||
memcpy (&val, (p), UINTSZ); \
|
||||
else \
|
||||
memcpy (&val, (p), pn); \
|
||||
flag = ((val - 0x01010101) & ~val) & 0x80808080; \
|
||||
if (!flag) \
|
||||
r += val; \
|
||||
|
@ -12,7 +12,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _hash_h_
|
||||
#define _hash_h_
|
||||
@ -20,7 +20,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#if defined __cplusplus || (defined __STDC__ && __STDC__) || defined WINDOWS32
|
||||
#if defined __cplusplus || (defined __STDC__ && __STDC__) || MK_OS_W32
|
||||
# if !defined __GLIBC__ || !defined __P
|
||||
# undef __P
|
||||
# define __P(protos) protos
|
||||
@ -57,7 +57,7 @@ typedef int (*qsort_cmp_t) __P((void const *, void const *));
|
||||
|
||||
void hash_init __P((struct hash_table *ht, unsigned long size,
|
||||
hash_func_t hash_1, hash_func_t hash_2, hash_cmp_func_t hash_cmp));
|
||||
void hash_load __P((struct hash_table *ht, void *item_table,
|
||||
void hash_load __P((struct hash_table *ht, const void *item_table,
|
||||
unsigned long cardinality, unsigned long size));
|
||||
void **hash_find_slot __P((struct hash_table *ht, void const *key));
|
||||
void *hash_find_item __P((struct hash_table *ht, void const *key));
|
||||
@ -76,7 +76,7 @@ void **hash_dump __P((struct hash_table *ht, void **vector_0, qsort_cmp_t compar
|
||||
extern unsigned jhash(unsigned char const *key, int n);
|
||||
extern unsigned jhash_string(unsigned char const *key);
|
||||
|
||||
extern void *hash_deleted_item;
|
||||
extern const void *hash_deleted_item;
|
||||
#define HASH_VACANT(item) ((item) == 0 || (void *) (item) == hash_deleted_item)
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Implicit rule searching for GNU Make.
|
||||
Copyright (C) 1988-2022 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988-2024 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
@ -12,7 +12,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "makeint.h"
|
||||
#include "filedef.h"
|
||||
@ -87,12 +87,10 @@ get_next_word (const char *buffer, size_t *length)
|
||||
return 0;
|
||||
|
||||
|
||||
/* We already found the first value of "c", above. */
|
||||
while (1)
|
||||
{
|
||||
char closeparen;
|
||||
int count;
|
||||
|
||||
/* Each time through the loop, "c" has the current char
|
||||
and "p" points to the next char. */
|
||||
switch (c)
|
||||
{
|
||||
case '\0':
|
||||
@ -101,31 +99,8 @@ get_next_word (const char *buffer, size_t *length)
|
||||
goto done_word;
|
||||
|
||||
case '$':
|
||||
c = *(p++);
|
||||
if (c == '$')
|
||||
break;
|
||||
|
||||
/* This is a variable reference, so read it to the matching
|
||||
close paren. */
|
||||
|
||||
if (c == '(')
|
||||
closeparen = ')';
|
||||
else if (c == '{')
|
||||
closeparen = '}';
|
||||
else
|
||||
/* This is a single-letter variable reference. */
|
||||
break;
|
||||
|
||||
for (count = 0; *p != '\0'; ++p)
|
||||
{
|
||||
if (*p == c)
|
||||
++count;
|
||||
else if (*p == closeparen && --count < 0)
|
||||
{
|
||||
++p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* This is a variable reference, so skip it. */
|
||||
p = skip_reference (p);
|
||||
break;
|
||||
|
||||
case '|':
|
||||
@ -234,7 +209,9 @@ pattern_search (struct file *file, int archive,
|
||||
We may replace % by $(*F) for second expansion, increasing the length. */
|
||||
size_t deplen = namelen + max_pattern_dep_length + 4;
|
||||
char *depname = alloca (deplen);
|
||||
#ifndef NDEBUG
|
||||
char *dend = depname + deplen;
|
||||
#endif
|
||||
|
||||
/* The start and length of the stem of FILENAME for the current rule. */
|
||||
const char *stem = 0;
|
||||
@ -270,6 +247,8 @@ pattern_search (struct file *file, int archive,
|
||||
|
||||
PATH_VAR (stem_str); /* @@ Need to get rid of stem, stemlen, etc. */
|
||||
|
||||
++depth;
|
||||
|
||||
#ifndef NO_ARCHIVES
|
||||
if (archive || ar_name (filename))
|
||||
lastslash = 0;
|
||||
@ -280,7 +259,7 @@ pattern_search (struct file *file, int archive,
|
||||
but not counting any slash at the end. (foo/bar/ counts as
|
||||
bar/ in directory foo/, not empty in directory foo/bar/.) */
|
||||
lastslash = memrchr (filename, '/', namelen - 1);
|
||||
#ifdef VMS
|
||||
#if MK_OS_VMS
|
||||
if (lastslash == NULL)
|
||||
lastslash = strrchr (filename, ']');
|
||||
if (lastslash == NULL)
|
||||
@ -353,7 +332,7 @@ pattern_search (struct file *file, int archive,
|
||||
check_lastslash = 0;
|
||||
if (lastslash)
|
||||
{
|
||||
#ifdef VMS
|
||||
#if MK_OS_VMS
|
||||
check_lastslash = strpbrk (target, "/]>:") == NULL;
|
||||
#else
|
||||
check_lastslash = strchr (target, '/') == 0;
|
||||
@ -702,7 +681,7 @@ pattern_search (struct file *file, int archive,
|
||||
}
|
||||
|
||||
/* Perform the 2nd expansion. */
|
||||
p = variable_expand_for_file (depname, file);
|
||||
p = expand_string_for_file (depname, file);
|
||||
dptr = &dl;
|
||||
|
||||
/* Parse the results into a deps list. */
|
||||
@ -891,7 +870,7 @@ pattern_search (struct file *file, int archive,
|
||||
|
||||
if (pattern_search (int_file,
|
||||
0,
|
||||
depth + 1,
|
||||
depth,
|
||||
recursions + 1,
|
||||
allow_compat_rules))
|
||||
{
|
||||
@ -1006,7 +985,7 @@ pattern_search (struct file *file, int archive,
|
||||
f->also_make = imf->also_make;
|
||||
f->is_target = 1;
|
||||
f->is_explicit |= imf->is_explicit || pat->is_explicit;
|
||||
f->notintermediate |= imf->notintermediate;
|
||||
f->notintermediate |= imf->notintermediate || no_intermediates;
|
||||
f->intermediate |= !f->is_explicit && !f->notintermediate;
|
||||
f->tried_implicit = 1;
|
||||
|
||||
@ -1088,7 +1067,7 @@ pattern_search (struct file *file, int archive,
|
||||
{
|
||||
if (f->precious)
|
||||
file->precious = 1;
|
||||
if (f->notintermediate)
|
||||
if (f->notintermediate || no_intermediates)
|
||||
file->notintermediate = 1;
|
||||
}
|
||||
}
|
||||
@ -1121,7 +1100,7 @@ pattern_search (struct file *file, int archive,
|
||||
{
|
||||
if (f->precious)
|
||||
new->file->precious = 1;
|
||||
if (f->notintermediate)
|
||||
if (f->notintermediate || no_intermediates)
|
||||
new->file->notintermediate = 1;
|
||||
}
|
||||
|
||||
@ -1137,6 +1116,8 @@ pattern_search (struct file *file, int archive,
|
||||
free (tryrules);
|
||||
free (deplist);
|
||||
|
||||
--depth;
|
||||
|
||||
if (rule)
|
||||
{
|
||||
DBS (DB_IMPLICIT, (_("Found implicit rule '%s' for '%s'.\n"),
|
||||
|
10
src/job.h
10
src/job.h
@ -1,5 +1,5 @@
|
||||
/* Definitions for managing subprocesses in GNU Make.
|
||||
Copyright (C) 1992-2022 Free Software Foundation, Inc.
|
||||
Copyright (C) 1992-2024 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
@ -12,13 +12,13 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "output.h"
|
||||
|
||||
/* Structure describing a running or dead child process. */
|
||||
|
||||
#ifdef VMS
|
||||
#if MK_OS_VMS
|
||||
#define VMSCHILD \
|
||||
char *comname; /* Temporary command file name */ \
|
||||
int efn; /* Completion event flag number */ \
|
||||
@ -80,11 +80,7 @@ char **construct_command_argv (char *line, char **restp, struct file *file,
|
||||
|
||||
pid_t child_execute_job (struct childbase *child, int good_stdin, char **argv);
|
||||
|
||||
#ifdef _AMIGA
|
||||
void exec_command (char **argv) NORETURN;
|
||||
#else
|
||||
pid_t exec_command (char **argv, char **envp);
|
||||
#endif
|
||||
|
||||
void unblock_all_sigs (void);
|
||||
|
||||
|
300
src/load.c
300
src/load.c
@ -1,5 +1,5 @@
|
||||
/* Loading dynamic objects for GNU Make.
|
||||
Copyright (C) 2012-2022 Free Software Foundation, Inc.
|
||||
Copyright (C) 2012-2024 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
@ -12,7 +12,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "makeint.h"
|
||||
|
||||
@ -24,8 +24,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define SYMBOL_EXTENSION "_gmk_setup"
|
||||
|
||||
#include "debug.h"
|
||||
#include "filedef.h"
|
||||
#include "variable.h"
|
||||
@ -35,21 +33,33 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
# define RTLD_GLOBAL 0
|
||||
#endif
|
||||
|
||||
#define GMK_SETUP "_gmk_setup"
|
||||
#define GMK_UNLOAD "_gmk_unload"
|
||||
|
||||
typedef int (*setup_func_t)(unsigned int abi, const floc *flocp);
|
||||
typedef void (*unload_func_t)(void);
|
||||
|
||||
struct load_list
|
||||
{
|
||||
struct load_list *next;
|
||||
const char *name;
|
||||
void *dlp;
|
||||
unload_func_t unload;
|
||||
};
|
||||
|
||||
static struct load_list *loaded_syms = NULL;
|
||||
|
||||
static load_func_t
|
||||
static setup_func_t
|
||||
load_object (const floc *flocp, int noerror, const char *ldname,
|
||||
const char *symname)
|
||||
const char *setupnm)
|
||||
{
|
||||
static void *global_dl = NULL;
|
||||
load_func_t symp;
|
||||
char *buf;
|
||||
const char *fp;
|
||||
char *endp;
|
||||
void *dlp;
|
||||
struct load_list *new;
|
||||
setup_func_t symp;
|
||||
|
||||
if (! global_dl)
|
||||
{
|
||||
@ -57,66 +67,101 @@ load_object (const floc *flocp, int noerror, const char *ldname,
|
||||
if (! global_dl)
|
||||
{
|
||||
const char *err = dlerror ();
|
||||
OS (fatal, flocp, _("Failed to open global symbol table: %s"), err);
|
||||
OS (fatal, flocp, _("failed to open global symbol table: %s"), err);
|
||||
}
|
||||
}
|
||||
|
||||
symp = (load_func_t) dlsym (global_dl, symname);
|
||||
/* Find the prefix of the ldname. */
|
||||
fp = strrchr (ldname, '/');
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
if (fp)
|
||||
{
|
||||
const char *fp2 = strchr (fp, '\\');
|
||||
|
||||
if (fp2 > fp)
|
||||
fp = fp2;
|
||||
}
|
||||
else
|
||||
fp = strrchr (ldname, '\\');
|
||||
/* The (improbable) case of d:foo. */
|
||||
if (fp && *fp && fp[1] == ':')
|
||||
fp++;
|
||||
#endif
|
||||
if (!fp)
|
||||
fp = ldname;
|
||||
else
|
||||
++fp;
|
||||
|
||||
endp = buf = alloca (strlen (fp) + CSTRLEN (GMK_UNLOAD) + 1);
|
||||
while (isalnum ((unsigned char) *fp) || *fp == '_')
|
||||
*(endp++) = *(fp++);
|
||||
|
||||
/* If we didn't find a symbol name yet, construct it from the prefix. */
|
||||
if (! setupnm)
|
||||
{
|
||||
memcpy (endp, GMK_SETUP, CSTRLEN (GMK_SETUP) + 1);
|
||||
setupnm = buf;
|
||||
}
|
||||
|
||||
DB (DB_VERBOSE, (_("Loading symbol %s from %s\n"), setupnm, ldname));
|
||||
|
||||
symp = (setup_func_t) dlsym (global_dl, setupnm);
|
||||
if (symp)
|
||||
return symp;
|
||||
|
||||
/* If the path has no "/", try the current directory first. */
|
||||
dlp = NULL;
|
||||
if (! strchr (ldname, '/')
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
&& ! strchr (ldname, '\\')
|
||||
#endif
|
||||
)
|
||||
dlp = dlopen (concat (2, "./", ldname), RTLD_LAZY|RTLD_GLOBAL);
|
||||
|
||||
/* If we haven't opened it yet, try the default search path. */
|
||||
if (! dlp)
|
||||
dlp = dlopen (ldname, RTLD_LAZY|RTLD_GLOBAL);
|
||||
|
||||
/* Still no? Then fail. */
|
||||
if (! dlp)
|
||||
{
|
||||
const char *err = dlerror ();
|
||||
if (noerror)
|
||||
DB (DB_BASIC, ("%s\n", err));
|
||||
else
|
||||
OS (error, flocp, "%s", err);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DB (DB_VERBOSE, (_("Loaded shared object %s\n"), ldname));
|
||||
|
||||
/* Assert that the GPL license symbol is defined. */
|
||||
symp = (setup_func_t) dlsym (dlp, "plugin_is_GPL_compatible");
|
||||
if (! symp)
|
||||
OS (fatal, flocp,
|
||||
_("loaded object %s is not declared to be GPL compatible"), ldname);
|
||||
|
||||
symp = (setup_func_t) dlsym (dlp, setupnm);
|
||||
if (! symp)
|
||||
{
|
||||
struct load_list *new;
|
||||
void *dlp = NULL;
|
||||
|
||||
/* If the path has no "/", try the current directory first. */
|
||||
if (! strchr (ldname, '/')
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
&& ! strchr (ldname, '\\')
|
||||
#endif
|
||||
)
|
||||
dlp = dlopen (concat (2, "./", ldname), RTLD_LAZY|RTLD_GLOBAL);
|
||||
|
||||
/* If we haven't opened it yet, try the default search path. */
|
||||
if (! dlp)
|
||||
dlp = dlopen (ldname, RTLD_LAZY|RTLD_GLOBAL);
|
||||
|
||||
/* Still no? Then fail. */
|
||||
if (! dlp)
|
||||
{
|
||||
const char *err = dlerror ();
|
||||
if (noerror)
|
||||
DB (DB_BASIC, ("%s\n", err));
|
||||
else
|
||||
OS (error, flocp, "%s", err);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DB (DB_VERBOSE, (_("Loaded shared object %s\n"), ldname));
|
||||
|
||||
/* Assert that the GPL license symbol is defined. */
|
||||
symp = (load_func_t) dlsym (dlp, "plugin_is_GPL_compatible");
|
||||
if (! symp)
|
||||
OS (fatal, flocp,
|
||||
_("Loaded object %s is not declared to be GPL compatible"),
|
||||
ldname);
|
||||
|
||||
symp = (load_func_t) dlsym (dlp, symname);
|
||||
if (! symp)
|
||||
{
|
||||
const char *err = dlerror ();
|
||||
OSSS (fatal, flocp, _("Failed to load symbol %s from %s: %s"),
|
||||
symname, ldname, err);
|
||||
}
|
||||
|
||||
/* Add this symbol to a trivial lookup table. This is not efficient but
|
||||
it's highly unlikely we'll be loading lots of objects, and we only
|
||||
need it to look them up on unload, if we rebuild them. */
|
||||
new = xmalloc (sizeof (struct load_list));
|
||||
new->name = xstrdup (ldname);
|
||||
new->dlp = dlp;
|
||||
new->next = loaded_syms;
|
||||
loaded_syms = new;
|
||||
const char *err = dlerror ();
|
||||
OSSS (fatal, flocp, _("failed to load symbol %s from %s: %s"),
|
||||
setupnm, ldname, err);
|
||||
}
|
||||
|
||||
new = xcalloc (sizeof (struct load_list));
|
||||
new->next = loaded_syms;
|
||||
loaded_syms = new;
|
||||
new->name = ldname;
|
||||
new->dlp = dlp;
|
||||
|
||||
/* Compute the name of the unload function and look it up. */
|
||||
memcpy (endp, GMK_UNLOAD, CSTRLEN (GMK_UNLOAD) + 1);
|
||||
|
||||
new->unload = (unload_func_t) dlsym (dlp, buf);
|
||||
if (new->unload)
|
||||
DB (DB_VERBOSE, (_("Detected symbol %s in %s\n"), buf, ldname));
|
||||
|
||||
return symp;
|
||||
}
|
||||
|
||||
@ -124,12 +169,11 @@ int
|
||||
load_file (const floc *flocp, struct file *file, int noerror)
|
||||
{
|
||||
const char *ldname = file->name;
|
||||
size_t nmlen = strlen (ldname);
|
||||
char *new = alloca (nmlen + CSTRLEN (SYMBOL_EXTENSION) + 1);
|
||||
char *symname = NULL;
|
||||
char *buf;
|
||||
char *setupnm = NULL;
|
||||
const char *fp;
|
||||
int r;
|
||||
load_func_t symp;
|
||||
setup_func_t symp;
|
||||
|
||||
/* Break the input into an object file name and a symbol name. If no symbol
|
||||
name was provided, compute one from the object file name. */
|
||||
@ -148,18 +192,18 @@ load_file (const floc *flocp, struct file *file, int noerror)
|
||||
|
||||
++fp;
|
||||
if (fp == ep)
|
||||
OS (fatal, flocp, _("Empty symbol name for load: %s"), ldname);
|
||||
OS (fatal, flocp, _("empty symbol name for load: %s"), ldname);
|
||||
|
||||
/* Make a copy of the ldname part. */
|
||||
memcpy (new, ldname, l);
|
||||
new[l] = '\0';
|
||||
ldname = new;
|
||||
nmlen = l;
|
||||
buf = alloca (strlen (ldname) + 1);
|
||||
memcpy (buf, ldname, l);
|
||||
buf[l] = '\0';
|
||||
ldname = buf;
|
||||
|
||||
/* Make a copy of the symbol name part. */
|
||||
symname = new + l + 1;
|
||||
memcpy (symname, fp, ep - fp);
|
||||
symname[ep - fp] = '\0';
|
||||
setupnm = buf + l + 1;
|
||||
memcpy (setupnm, fp, ep - fp);
|
||||
setupnm[ep - fp] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
@ -173,49 +217,21 @@ load_file (const floc *flocp, struct file *file, int noerror)
|
||||
if (file && file->loaded)
|
||||
return -1;
|
||||
|
||||
/* If we didn't find a symbol name yet, construct it from the ldname. */
|
||||
if (! symname)
|
||||
{
|
||||
char *p = new;
|
||||
|
||||
fp = strrchr (ldname, '/');
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
if (fp)
|
||||
{
|
||||
const char *fp2 = strchr (fp, '\\');
|
||||
|
||||
if (fp2 > fp)
|
||||
fp = fp2;
|
||||
}
|
||||
else
|
||||
fp = strrchr (ldname, '\\');
|
||||
/* The (improbable) case of d:foo. */
|
||||
if (fp && *fp && fp[1] == ':')
|
||||
fp++;
|
||||
#endif
|
||||
if (!fp)
|
||||
fp = ldname;
|
||||
else
|
||||
++fp;
|
||||
while (isalnum ((unsigned char) *fp) || *fp == '_')
|
||||
*(p++) = *(fp++);
|
||||
strcpy (p, SYMBOL_EXTENSION);
|
||||
symname = new;
|
||||
}
|
||||
|
||||
DB (DB_VERBOSE, (_("Loading symbol %s from %s\n"), symname, ldname));
|
||||
|
||||
/* Load it! */
|
||||
symp = load_object (flocp, noerror, ldname, symname);
|
||||
symp = load_object (flocp, noerror, ldname, setupnm);
|
||||
if (! symp)
|
||||
return 0;
|
||||
|
||||
/* Invoke the symbol. */
|
||||
r = (*symp) (flocp);
|
||||
/* Invoke the setup function. */
|
||||
{
|
||||
unsigned int abi = GMK_ABI_VERSION;
|
||||
r = (*symp) (abi, flocp);
|
||||
}
|
||||
|
||||
/* If the load didn't fail, add the file to the .LOADED variable. */
|
||||
if (r)
|
||||
do_variable_definition(flocp, ".LOADED", ldname, o_file, f_append_value, 0);
|
||||
do_variable_definition(flocp, ".LOADED", ldname, o_file, f_append_value, 0,
|
||||
s_global);
|
||||
|
||||
return r;
|
||||
}
|
||||
@ -223,22 +239,53 @@ load_file (const floc *flocp, struct file *file, int noerror)
|
||||
int
|
||||
unload_file (const char *name)
|
||||
{
|
||||
int rc = 0;
|
||||
struct load_list *d;
|
||||
struct load_list **dp = &loaded_syms;
|
||||
|
||||
for (d = loaded_syms; d != NULL; d = d->next)
|
||||
if (streq (d->name, name) && d->dlp)
|
||||
{
|
||||
DB (DB_VERBOSE, (_("Unloading shared object %s\n"), name));
|
||||
rc = dlclose (d->dlp);
|
||||
if (rc)
|
||||
perror_with_name ("dlclose: ", d->name);
|
||||
else
|
||||
d->dlp = NULL;
|
||||
break;
|
||||
}
|
||||
/* Unload and remove the entry for this file. */
|
||||
while (*dp != NULL)
|
||||
{
|
||||
struct load_list *d = *dp;
|
||||
|
||||
return rc;
|
||||
if (streq (d->name, name))
|
||||
{
|
||||
int rc;
|
||||
|
||||
DB (DB_VERBOSE, (_("Unloading shared object %s\n"), name));
|
||||
|
||||
if (d->unload)
|
||||
(*d->unload) ();
|
||||
|
||||
rc = dlclose (d->dlp);
|
||||
if (rc)
|
||||
perror_with_name ("dlclose: ", d->name);
|
||||
|
||||
*dp = d->next;
|
||||
free (d);
|
||||
return rc;
|
||||
}
|
||||
|
||||
dp = &d->next;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
unload_all ()
|
||||
{
|
||||
while (loaded_syms)
|
||||
{
|
||||
struct load_list *d = loaded_syms;
|
||||
loaded_syms = loaded_syms->next;
|
||||
|
||||
if (d->unload)
|
||||
(*d->unload) ();
|
||||
|
||||
if (dlclose (d->dlp))
|
||||
perror_with_name ("dlclose: ", d->name);
|
||||
|
||||
free (d);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
@ -248,7 +295,7 @@ load_file (const floc *flocp, struct file *file UNUSED, int noerror)
|
||||
{
|
||||
if (! noerror)
|
||||
O (fatal, flocp,
|
||||
_("The 'load' operation is not supported on this platform"));
|
||||
_("'load' is not supported on this platform"));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -256,7 +303,12 @@ load_file (const floc *flocp, struct file *file UNUSED, int noerror)
|
||||
int
|
||||
unload_file (const char *name UNUSED)
|
||||
{
|
||||
O (fatal, NILF, "INTERNAL: Cannot unload when load is not supported");
|
||||
O (fatal, NILF, "INTERNAL: cannot unload when load is not supported");
|
||||
}
|
||||
|
||||
void
|
||||
unload_all ()
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* MAKE_LOAD */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* API for GNU Make dynamic objects.
|
||||
Copyright (C) 2013-2022 Free Software Foundation, Inc.
|
||||
Copyright (C) 2013-2024 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
@ -12,7 +12,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "makeint.h"
|
||||
|
||||
@ -70,7 +70,7 @@ gmk_eval (const char *buffer, const gmk_floc *gfloc)
|
||||
char *
|
||||
gmk_expand (const char *ref)
|
||||
{
|
||||
return allocated_variable_expand (ref);
|
||||
return allocated_expand_string (ref);
|
||||
}
|
||||
|
||||
/* Register a function to be called from makefiles. */
|
||||
|
1146
src/main.c
1146
src/main.c
File diff suppressed because it is too large
Load Diff
245
src/makeint.h
245
src/makeint.h
@ -1,5 +1,5 @@
|
||||
/* Miscellaneous global declarations and portability cruft for GNU Make.
|
||||
Copyright (C) 1988-2022 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988-2024 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
@ -12,34 +12,12 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* We use <config.h> instead of "config.h" so that a compilation
|
||||
using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
|
||||
(which it would do because makeint.h was found in $srcdir). */
|
||||
#include <config.h>
|
||||
#undef HAVE_CONFIG_H
|
||||
#define HAVE_CONFIG_H 1
|
||||
|
||||
/* Specify we want GNU source code. This must be defined before any
|
||||
system headers are included. */
|
||||
|
||||
#define _GNU_SOURCE 1
|
||||
|
||||
/* AIX requires this to be the first thing in the file. */
|
||||
#if HAVE_ALLOCA_H
|
||||
# include <alloca.h>
|
||||
#else
|
||||
# ifdef _AIX
|
||||
#pragma alloca
|
||||
# else
|
||||
# if !defined(__GNUC__) && !defined(WINDOWS32)
|
||||
# ifndef alloca /* predefined by HP cc +Olibcalls */
|
||||
char *alloca ();
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Some versions of GCC (e.g., 10.x) set the warn_unused_result attribute on
|
||||
__builtin_alloca. This causes alloca(0) to fail and is not easily worked
|
||||
@ -66,12 +44,12 @@ char *alloca ();
|
||||
Be sure to use the local one, and not one installed on the system.
|
||||
Define GMK_BUILDING_MAKE for proper selection of dllexport/dllimport
|
||||
declarations for MS-Windows. */
|
||||
#ifdef WINDOWS32
|
||||
#if MK_OS_W32
|
||||
# define GMK_BUILDING_MAKE
|
||||
#endif
|
||||
#include "gnumake.h"
|
||||
|
||||
#ifdef CRAY
|
||||
#ifdef CRAY
|
||||
/* This must happen before #include <signal.h> so
|
||||
that the declaration therein is changed. */
|
||||
# define signal bsdsignal
|
||||
@ -82,18 +60,12 @@ char *alloca ();
|
||||
# define __NO_STRING_INLINES
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#ifdef HAVE_SYS_TIMEB_H
|
||||
/* SCO 3.2 "devsys 4.2" has a prototype for 'ftime' in <time.h> that bombs
|
||||
unless <sys/timeb.h> has been included first. */
|
||||
# include <sys/timeb.h>
|
||||
#endif
|
||||
#if HAVE_SYS_TIME_H
|
||||
# include <sys/time.h>
|
||||
#endif
|
||||
@ -105,7 +77,23 @@ char *alloca ();
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
/* Define macros specifying which OS we are building for. */
|
||||
#if __gnu_hurd__
|
||||
# define MK_OS_HURD 1
|
||||
#endif
|
||||
#if __CYGWIN__
|
||||
# define MK_OS_CYGWIN 1
|
||||
#endif
|
||||
#if defined(__MVS__)
|
||||
# define MK_OS_ZOS 1
|
||||
#endif
|
||||
|
||||
#if defined(__EMX__)
|
||||
# define MK_OS_OS2 1
|
||||
#endif
|
||||
|
||||
#ifdef __VMS
|
||||
# define MK_OS_VMS 1
|
||||
/* In strict ANSI mode, VMS compilers should not be defining the
|
||||
VMS macro. Define it here instead of a bulk edit for the correct code.
|
||||
*/
|
||||
@ -114,11 +102,11 @@ extern int errno;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
/* Ultrix's unistd.h always defines _POSIX_VERSION, but you only get
|
||||
POSIX.1 behavior with 'cc -YPOSIX', which predefines POSIX itself! */
|
||||
# if defined (_POSIX_VERSION) && !defined (ultrix) && !defined (VMS)
|
||||
# if defined (_POSIX_VERSION) && !defined (ultrix) && !MK_OS_VMS
|
||||
# define POSIX 1
|
||||
# endif
|
||||
#endif
|
||||
@ -144,31 +132,25 @@ extern int errno;
|
||||
# include <vfork.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIMITS_H
|
||||
#ifdef HAVE_LIMITS_H
|
||||
# include <limits.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_PARAM_H
|
||||
#ifdef HAVE_SYS_PARAM_H
|
||||
# include <sys/param.h>
|
||||
#endif
|
||||
|
||||
#ifndef PATH_MAX
|
||||
# ifndef POSIX
|
||||
# ifdef MAXPATHLEN
|
||||
# define PATH_MAX MAXPATHLEN
|
||||
# else
|
||||
/* Some systems (HURD) have fully dynamic pathnames with no maximum.
|
||||
Ideally we'd support this but it will take some work. */
|
||||
# define PATH_MAX 4096
|
||||
# endif
|
||||
#endif
|
||||
#ifndef MAXPATHLEN
|
||||
# define MAXPATHLEN 1024
|
||||
#endif
|
||||
|
||||
#ifdef PATH_MAX
|
||||
# define GET_PATH_MAX PATH_MAX
|
||||
# define PATH_VAR(var) char var[PATH_MAX+1]
|
||||
#else
|
||||
# define NEED_GET_PATH_MAX 1
|
||||
# define GET_PATH_MAX (get_path_max ())
|
||||
# define PATH_VAR(var) char *var = alloca (GET_PATH_MAX+1)
|
||||
unsigned int get_path_max (void);
|
||||
#endif
|
||||
#define GET_PATH_MAX PATH_MAX
|
||||
#define PATH_VAR(var) char var[PATH_MAX+1]
|
||||
|
||||
#ifndef CHAR_BIT
|
||||
# define CHAR_BIT 8
|
||||
@ -178,6 +160,10 @@ unsigned int get_path_max (void);
|
||||
# define USHRT_MAX 65535
|
||||
#endif
|
||||
|
||||
#ifndef SIZE_MAX
|
||||
# define SIZE_MAX ((size_t)~(size_t)0)
|
||||
#endif
|
||||
|
||||
/* Nonzero if the integer type T is signed.
|
||||
Use <= to avoid GCC warnings about always-false expressions. */
|
||||
#define INTEGER_TYPE_SIGNED(t) ((t) -1 <= 0)
|
||||
@ -208,7 +194,7 @@ unsigned int get_path_max (void);
|
||||
# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
|
||||
#endif
|
||||
|
||||
#ifdef VMS
|
||||
#if MK_OS_VMS
|
||||
# include <fcntl.h>
|
||||
# include <types.h>
|
||||
# include <unixlib.h>
|
||||
@ -250,8 +236,6 @@ extern int vms_unix_simulation;
|
||||
# ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
# define ANSI_STRING 1
|
||||
# else
|
||||
# include <strings.h>
|
||||
# endif
|
||||
# ifdef HAVE_MEMORY_H
|
||||
# include <memory.h>
|
||||
@ -277,16 +261,16 @@ void exit (int) NORETURN;
|
||||
# define EXIT_FAILURE 1
|
||||
#endif
|
||||
|
||||
#ifndef ANSI_STRING
|
||||
#ifndef ANSI_STRING
|
||||
|
||||
/* SCO Xenix has a buggy macro definition in <string.h>. */
|
||||
#undef strerror
|
||||
#undef strerror
|
||||
#if !defined(__DECC)
|
||||
char *strerror (int errnum);
|
||||
#endif
|
||||
|
||||
#endif /* !ANSI_STRING. */
|
||||
#undef ANSI_STRING
|
||||
#undef ANSI_STRING
|
||||
|
||||
#if HAVE_INTTYPES_H
|
||||
# include <inttypes.h>
|
||||
@ -294,6 +278,25 @@ char *strerror (int errnum);
|
||||
#if HAVE_STDINT_H
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_STRINGS_H
|
||||
# include <strings.h> /* Needed for strcasecmp / strncasecmp. */
|
||||
#endif
|
||||
|
||||
#if defined _MSC_VER || defined __MINGW32__
|
||||
# define MK_PRI64_PREFIX "I64"
|
||||
#else
|
||||
# define MK_PRI64_PREFIX "ll"
|
||||
#endif
|
||||
#ifndef PRIdMAX
|
||||
# define PRIdMAX MK_PRI64_PREFIX "d"
|
||||
#endif
|
||||
#ifndef PRIuMAX
|
||||
# define PRIuMAX MK_PRI64_PREFIX "u"
|
||||
#endif
|
||||
#ifndef SCNdMAX
|
||||
# define SCNdMAX PRIdMAX
|
||||
#endif
|
||||
#define FILE_TIMESTAMP uintmax_t
|
||||
|
||||
#if !defined(HAVE_STRSIGNAL)
|
||||
@ -360,7 +363,7 @@ extern mode_t umask (mode_t);
|
||||
# include <direct.h>
|
||||
#endif
|
||||
|
||||
#ifdef WINDOWS32
|
||||
#if MK_OS_W32
|
||||
# include <fcntl.h>
|
||||
# include <malloc.h>
|
||||
# define pipe(_p) _pipe((_p), 512, O_BINARY)
|
||||
@ -390,14 +393,17 @@ extern int unixy_shell;
|
||||
# endif
|
||||
|
||||
/* Include only the minimal stuff from windows.h. */
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
#endif /* WINDOWS32 */
|
||||
# ifndef WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# endif
|
||||
#endif /* MK_OS_W32 */
|
||||
|
||||
/* ALL_SET() evaluates the second argument twice. */
|
||||
#define ANY_SET(_v,_m) (((_v)&(_m)) != 0)
|
||||
#define NONE_SET(_v,_m) (! ANY_SET ((_v),(_m)))
|
||||
#define ALL_SET(_v,_m) (((_v)&(_m)) == (_m))
|
||||
|
||||
/* Bitmasks for the STOPCHAR array. */
|
||||
#define MAP_NUL 0x0001
|
||||
#define MAP_BLANK 0x0002 /* space, TAB */
|
||||
#define MAP_NEWLINE 0x0004
|
||||
@ -417,7 +423,7 @@ extern int unixy_shell;
|
||||
/* The set of characters which are directory separators is OS-specific. */
|
||||
#define MAP_DIRSEP 0x8000
|
||||
|
||||
#ifdef VMS
|
||||
#if MK_OS_VMS
|
||||
# define MAP_VMSCOMMA MAP_COMMA
|
||||
#else
|
||||
# define MAP_VMSCOMMA 0x0000
|
||||
@ -434,7 +440,7 @@ extern int unixy_shell;
|
||||
# define PATH_SEPARATOR_CHAR ';'
|
||||
# define MAP_PATHSEP MAP_SEMI
|
||||
#elif !defined(PATH_SEPARATOR_CHAR)
|
||||
# if defined (VMS)
|
||||
# if MK_OS_VMS
|
||||
# define PATH_SEPARATOR_CHAR (vms_comma_separator ? ',' : ':')
|
||||
# define MAP_PATHSEP (vms_comma_separator ? MAP_COMMA : MAP_SEMI)
|
||||
# else
|
||||
@ -447,6 +453,7 @@ extern int unixy_shell;
|
||||
# define MAP_PATHSEP MAP_SEMI
|
||||
#elif PATH_SEPARATOR_CHAR == ','
|
||||
# define MAP_PATHSEP MAP_COMMA
|
||||
|
||||
#else
|
||||
# error "Unknown PATH_SEPARATOR_CHAR"
|
||||
#endif
|
||||
@ -462,6 +469,18 @@ extern int unixy_shell;
|
||||
/* Move S past all whitespace (including newlines). */
|
||||
#define NEXT_TOKEN(s) while (ISSPACE (*(s))) ++(s)
|
||||
|
||||
/* True if C is a directory separator on the current system. */
|
||||
#define ISDIRSEP(c) STOP_SET((c),MAP_DIRSEP)
|
||||
|
||||
/* True if S starts with a drive specifier. */
|
||||
#if defined(HAVE_DOS_PATHS)
|
||||
# define HAS_DRIVESPEC(_s) ((((_s)[0] >= 'a' && (_s)[0] <= 'z') \
|
||||
|| ((_s)[0] >= 'A' && (_s)[0] <= 'Z')) \
|
||||
&& (_s)[1] == ':')
|
||||
#else
|
||||
# define HAS_DRIVESPEC(_s) 0
|
||||
#endif
|
||||
|
||||
/* We can't run setrlimit when using posix_spawn. */
|
||||
#if defined(HAVE_SYS_RESOURCE_H) && defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT) && !defined(USE_POSIX_SPAWN)
|
||||
# define SET_STACK_SIZE
|
||||
@ -475,8 +494,13 @@ extern struct rlimit stack_limit;
|
||||
|
||||
#define NILF ((floc *)0)
|
||||
|
||||
/* Number of elements in an array. */
|
||||
#define ARRAYLEN(_a) (sizeof (_a) / sizeof ((_a)[0]))
|
||||
|
||||
/* Number of characters in a string constant. Does NOT include the \0 byte. */
|
||||
#define CSTRLEN(_s) (sizeof (_s)-1)
|
||||
|
||||
/* Only usable when NOT calling a macro: only use it for local functions. */
|
||||
#define STRING_SIZE_TUPLE(_s) (_s), CSTRLEN(_s)
|
||||
|
||||
/* The number of bytes needed to represent the largest signed and unsigned
|
||||
@ -492,6 +516,15 @@ extern struct rlimit stack_limit;
|
||||
# define TTYNAME(_f) DEFAULT_TTYNAME
|
||||
#endif
|
||||
|
||||
#if MK_OS_VMS
|
||||
# define DEFAULT_TMPDIR "/sys$scratch/"
|
||||
#elif defined(P_tmpdir)
|
||||
# define DEFAULT_TMPDIR P_tmpdir
|
||||
#else
|
||||
# define DEFAULT_TMPDIR "/tmp"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
struct file;
|
||||
@ -511,7 +544,9 @@ void error (const floc *flocp, size_t length, const char *fmt, ...)
|
||||
ATTRIBUTE ((__format__ (__printf__, 3, 4)));
|
||||
void fatal (const floc *flocp, size_t length, const char *fmt, ...)
|
||||
ATTRIBUTE ((noreturn, __format__ (__printf__, 3, 4)));
|
||||
void out_of_memory () NORETURN;
|
||||
char *format (const char *prefix, size_t length, const char *fmt, ...)
|
||||
ATTRIBUTE ((__format__ (__printf__, 3, 4)));
|
||||
void out_of_memory (void) NORETURN;
|
||||
|
||||
/* When adding macros to this list be sure to update the value of
|
||||
XGETTEXT_OPTIONS in the po/Makevars file. */
|
||||
@ -529,13 +564,23 @@ void out_of_memory () NORETURN;
|
||||
#define ONS(_t,_a,_f,_n,_s) _t((_a), INTSTR_LENGTH + strlen (_s), \
|
||||
(_f), (_n), (_s))
|
||||
|
||||
void decode_env_switches (const char*, size_t line);
|
||||
enum variable_origin;
|
||||
struct variable;
|
||||
|
||||
void reset_makeflags (enum variable_origin origin);
|
||||
struct variable *define_makeflags (int makefile);
|
||||
int should_print_dir (void);
|
||||
void temp_stdin_unlink (void);
|
||||
void die (int) NORETURN;
|
||||
void pfatal_with_name (const char *) NORETURN;
|
||||
void perror_with_name (const char *, const char *);
|
||||
#define xstrlen(_s) ((_s)==NULL ? 0 : strlen (_s))
|
||||
unsigned int make_toui (const char*, const char**);
|
||||
pid_t make_pid ();
|
||||
char *make_lltoa (long long, char *);
|
||||
char *make_ulltoa (unsigned long long, char *);
|
||||
void make_seed (unsigned int);
|
||||
unsigned int make_rand (void);
|
||||
pid_t make_pid (void);
|
||||
void *xmalloc (size_t);
|
||||
void *xcalloc (size_t);
|
||||
void *xrealloc (void *, size_t);
|
||||
@ -544,13 +589,14 @@ char *xstrndup (const char *, size_t);
|
||||
char *find_next_token (const char **, size_t *);
|
||||
char *next_token (const char *);
|
||||
char *end_of_token (const char *);
|
||||
char *skip_reference (const char *);
|
||||
void collapse_continuations (char *);
|
||||
char *lindex (const char *, const char *, int);
|
||||
int alpha_compare (const void *, const void *);
|
||||
void print_spaces (unsigned int);
|
||||
char *find_percent (char *);
|
||||
const char *find_percent_cached (const char **);
|
||||
char *get_tmppath ();
|
||||
const char *get_tmpdir (void);
|
||||
int get_tmpfd (char **);
|
||||
FILE *get_tmpfile (char **);
|
||||
ssize_t writebuf (int, const void *, size_t);
|
||||
@ -566,15 +612,16 @@ void ar_parse_name (const char *, char **, char **);
|
||||
int ar_touch (const char *);
|
||||
time_t ar_member_date (const char *);
|
||||
|
||||
typedef long int (*ar_member_func_t) (int desc, const char *mem, int truncated,
|
||||
typedef intmax_t (*ar_member_func_t) (int desc, const char *mem, int truncated,
|
||||
long int hdrpos, long int datapos,
|
||||
long int size, long int date, int uid,
|
||||
long int size, intmax_t date, int uid,
|
||||
int gid, unsigned int mode,
|
||||
const void *arg);
|
||||
|
||||
long int ar_scan (const char *archive, ar_member_func_t function, const void *arg);
|
||||
intmax_t ar_scan (const char *archive, ar_member_func_t function,
|
||||
const void *arg);
|
||||
int ar_name_equal (const char *name, const char *mem, int truncated);
|
||||
#ifndef VMS
|
||||
#if !MK_OS_VMS
|
||||
int ar_member_touch (const char *arname, const char *memname);
|
||||
#endif
|
||||
#endif
|
||||
@ -617,33 +664,37 @@ const char *strcache_add_len (const char *str, size_t len);
|
||||
int guile_gmake_setup (const floc *flocp);
|
||||
|
||||
/* Loadable object support. Sets to the strcached name of the loaded file. */
|
||||
typedef int (*load_func_t)(const floc *flocp);
|
||||
int load_file (const floc *flocp, struct file *file, int noerror);
|
||||
int unload_file (const char *name);
|
||||
void unload_all (void);
|
||||
|
||||
/* Maintainer mode support */
|
||||
#ifdef MAKE_MAINTAINER_MODE
|
||||
# define SPIN(_s) spin (_s)
|
||||
void spin (const char* suffix);
|
||||
# define DBG(_f) dbg _f
|
||||
void dbg (const char *fmt, ...);
|
||||
#else
|
||||
# define SPIN(_s)
|
||||
/* Never put this code into Git or a release. */
|
||||
# define DBG(_f) compile-error
|
||||
#endif
|
||||
|
||||
/* We omit these declarations on non-POSIX systems which define _POSIX_VERSION,
|
||||
because such systems often declare them in header files anyway. */
|
||||
|
||||
#if !defined (__GNU_LIBRARY__) && !defined (POSIX) && !defined (_POSIX_VERSION) && !defined(WINDOWS32)
|
||||
#if !defined (__GNU_LIBRARY__) && !defined (POSIX) && !defined (_POSIX_VERSION) && !MK_OS_W32
|
||||
|
||||
# ifndef VMS
|
||||
# if !MK_OS_VMS
|
||||
long int lseek ();
|
||||
# endif
|
||||
|
||||
# ifdef HAVE_GETCWD
|
||||
# if !defined(VMS) && !defined(__DECC)
|
||||
char *getcwd ();
|
||||
# ifdef HAVE_GETCWD
|
||||
# if !MK_OS_VMS && !defined(__DECC)
|
||||
char *getcwd (void);
|
||||
# endif
|
||||
# else
|
||||
char *getwd ();
|
||||
char *getwd (void);
|
||||
# define getcwd(buf, len) getwd (buf)
|
||||
# endif
|
||||
|
||||
@ -654,9 +705,6 @@ char *getwd ();
|
||||
# define strcasecmp stricmp
|
||||
# elif HAVE_STRCMPI
|
||||
# define strcasecmp strcmpi
|
||||
# else
|
||||
/* Create our own, in misc.c */
|
||||
int strcasecmp (const char *s1, const char *s2);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@ -665,22 +713,9 @@ int strcasecmp (const char *s1, const char *s2);
|
||||
# define strncasecmp strnicmp
|
||||
# elif HAVE_STRNCMPI
|
||||
# define strncasecmp strncmpi
|
||||
# else
|
||||
/* Create our own, in misc.c */
|
||||
int strncasecmp (const char *s1, const char *s2, int n);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !HAVE_MEMPCPY
|
||||
/* Create our own, in misc.c */
|
||||
void *mempcpy (void *dest, const void *src, size_t n);
|
||||
#endif
|
||||
|
||||
#if !HAVE_STPCPY
|
||||
/* Create our own, in misc.c */
|
||||
char *stpcpy (char *dest, const char *src);
|
||||
#endif
|
||||
|
||||
#define OUTPUT_SYNC_NONE 0
|
||||
#define OUTPUT_SYNC_LINE 1
|
||||
#define OUTPUT_SYNC_TARGET 2
|
||||
@ -697,10 +732,10 @@ extern unsigned short stopchar_map[];
|
||||
extern int just_print_flag, run_silent, ignore_errors_flag, keep_going_flag;
|
||||
extern int print_data_base_flag, question_flag, touch_flag, always_make_flag;
|
||||
extern int env_overrides, no_builtin_rules_flag, no_builtin_variables_flag;
|
||||
extern int print_version_flag, print_directory, check_symlink_flag;
|
||||
extern int warn_undefined_variables_flag, posix_pedantic;
|
||||
extern int print_version_flag, check_symlink_flag, posix_pedantic;
|
||||
extern int not_parallel, second_expansion, clock_skew_detected;
|
||||
extern int rebuilding_makefiles, one_shell, output_sync, verify_flag;
|
||||
extern int export_all_variables;
|
||||
extern unsigned long command_count;
|
||||
|
||||
extern const char *default_shell;
|
||||
@ -711,11 +746,27 @@ extern int batch_mode_shell;
|
||||
#define GNUMAKEFLAGS_NAME "GNUMAKEFLAGS"
|
||||
#define MAKEFLAGS_NAME "MAKEFLAGS"
|
||||
|
||||
#define MAKELEVEL_NAME "MAKELEVEL"
|
||||
#define MAKELEVEL_LENGTH (CSTRLEN (MAKELEVEL_NAME))
|
||||
|
||||
/* Resetting the command script introduction prefix character. */
|
||||
#define RECIPEPREFIX_NAME ".RECIPEPREFIX"
|
||||
#define RECIPEPREFIX_DEFAULT '\t'
|
||||
extern char cmd_prefix;
|
||||
|
||||
/* Setting warning actions. */
|
||||
#define WARNINGS_NAME ".WARNINGS"
|
||||
|
||||
extern unsigned int no_intermediates;
|
||||
|
||||
#if HAVE_MKFIFO
|
||||
/* It seems that mkfifo() is not working correctly, or at least not the way
|
||||
GNU make wants it to work, on: GNU/Hurd, Cygwin, OS2; don't use it there. */
|
||||
# if !defined(JOBSERVER_USE_FIFO) && !MK_OS_HURD && !MK_OS_CYGWIN && !MK_OS_OS2
|
||||
# define JOBSERVER_USE_FIFO 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define JOBSERVER_AUTH_OPT "jobserver-auth"
|
||||
|
||||
extern char *jobserver_auth;
|
||||
@ -724,7 +775,7 @@ extern double max_load_average;
|
||||
|
||||
extern const char *program;
|
||||
|
||||
#ifdef VMS
|
||||
#if MK_OS_VMS
|
||||
const char *vms_command (const char *argv0);
|
||||
const char *vms_progname (const char *argv0);
|
||||
|
||||
@ -771,7 +822,7 @@ extern char *version_string, *remote_description, *make_host;
|
||||
|
||||
extern unsigned int commands_started;
|
||||
|
||||
extern int handling_fatal_signal;
|
||||
extern volatile sig_atomic_t handling_fatal_signal;
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(_a,_b) ((_a)<(_b)?(_a):(_b))
|
||||
@ -791,7 +842,7 @@ extern int handling_fatal_signal;
|
||||
#endif
|
||||
|
||||
#ifndef initialize_main
|
||||
# ifdef __EMX__
|
||||
# if MK_OS_OS2
|
||||
# define initialize_main(pargc, pargv) \
|
||||
{ _wildcard(pargc, pargv); _response(pargc, pargv); }
|
||||
# else
|
||||
@ -799,7 +850,7 @@ extern int handling_fatal_signal;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __EMX__
|
||||
#if MK_OS_OS2
|
||||
# if !defined chdir
|
||||
# define chdir _chdir2
|
||||
# endif
|
||||
|
430
src/misc.c
430
src/misc.c
@ -1,5 +1,5 @@
|
||||
/* Miscellaneous generic support functions for GNU Make.
|
||||
Copyright (C) 1988-2022 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988-2024 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
@ -12,7 +12,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "makeint.h"
|
||||
#include "filedef.h"
|
||||
@ -20,15 +20,19 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
#include "os.h"
|
||||
#include "debug.h"
|
||||
|
||||
/* GNU make no longer supports pre-ANSI89 environments. */
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef WINDOWS32
|
||||
#if MK_OS_W32
|
||||
# include <windows.h>
|
||||
# include <io.h>
|
||||
#endif
|
||||
|
||||
#if MK_OS_OS2
|
||||
# define INCL_DOS
|
||||
# include <os2.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FCNTL_H
|
||||
# include <fcntl.h>
|
||||
#else
|
||||
@ -54,6 +58,52 @@ make_toui (const char *str, const char **error)
|
||||
return val;
|
||||
}
|
||||
|
||||
/* Convert val into a string, written to buf. buf must be large enough
|
||||
to hold the largest possible value, plus a nul byte. Returns buf.
|
||||
We can't use standard PRI* here: those are based on intNN_t types. */
|
||||
|
||||
char *
|
||||
make_lltoa (long long val, char *buf)
|
||||
{
|
||||
sprintf (buf, "%" MK_PRI64_PREFIX "d", val);
|
||||
return buf;
|
||||
}
|
||||
|
||||
char *
|
||||
make_ulltoa (unsigned long long val, char *buf)
|
||||
{
|
||||
sprintf (buf, "%" MK_PRI64_PREFIX "u", val);
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* Simple random number generator, for use with shuffle.
|
||||
This doesn't need to be truly random, just pretty random. Use our own
|
||||
implementation rather than relying on the C runtime's rand() so we always
|
||||
get the same results for a given seed, regardless of C runtime. */
|
||||
|
||||
static unsigned int mk_state = 0;
|
||||
|
||||
void
|
||||
make_seed (unsigned int seed)
|
||||
{
|
||||
mk_state = seed;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
make_rand ()
|
||||
{
|
||||
/* mk_state must never be 0. */
|
||||
if (mk_state == 0)
|
||||
mk_state = (unsigned int)(time (NULL) ^ make_pid ()) + 1;
|
||||
|
||||
/* A simple xorshift RNG. */
|
||||
mk_state ^= mk_state << 13;
|
||||
mk_state ^= mk_state >> 17;
|
||||
mk_state ^= mk_state << 5;
|
||||
|
||||
return mk_state;
|
||||
}
|
||||
|
||||
/* Compare strings *S1 and *S2.
|
||||
Return negative if the first is less, positive if it is greater,
|
||||
zero if they are equal. */
|
||||
@ -81,7 +131,7 @@ collapse_continuations (char *line)
|
||||
char *q;
|
||||
|
||||
q = strchr(in, '\n');
|
||||
if (q == 0)
|
||||
if (!q)
|
||||
return;
|
||||
|
||||
do
|
||||
@ -112,17 +162,33 @@ collapse_continuations (char *line)
|
||||
|
||||
if (i & 1)
|
||||
{
|
||||
/* Backslash/newline handling:
|
||||
In traditional GNU make all trailing whitespace, consecutive
|
||||
backslash/newlines, and any leading non-newline whitespace on the
|
||||
next line is reduced to a single space.
|
||||
In POSIX, each backslash/newline and is replaced by a space. */
|
||||
unsigned int dollar;
|
||||
|
||||
/* Backslash/newline handling: out points to the final "\".
|
||||
In POSIX, each backslash/newline is replaced by a space.
|
||||
In GNU Make all trailing whitespace, consecutive backslash +
|
||||
newlines, and any leading non-newline whitespace on the next line
|
||||
is reduced to a single space.
|
||||
As a special case, replace "$\" with the empty string. */
|
||||
while (ISBLANK (*in))
|
||||
++in;
|
||||
if (! posix_pedantic)
|
||||
|
||||
{
|
||||
const char *dp = out;
|
||||
while (dp > line && dp[-1] == '$')
|
||||
--dp;
|
||||
dollar = (out - dp) % 2;
|
||||
}
|
||||
|
||||
if (dollar)
|
||||
--out;
|
||||
|
||||
if (!posix_pedantic)
|
||||
while (out > line && ISBLANK (out[-1]))
|
||||
--out;
|
||||
*out++ = ' ';
|
||||
|
||||
if (!dollar)
|
||||
*out++ = ' ';
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -285,7 +351,7 @@ xstrndup (const char *str, size_t length)
|
||||
#else
|
||||
result = xmalloc (length + 1);
|
||||
if (length > 0)
|
||||
strncpy (result, str, length);
|
||||
memcpy (result, str, length);
|
||||
result[length] = '\0';
|
||||
#endif
|
||||
|
||||
@ -352,6 +418,50 @@ next_token (const char *s)
|
||||
return (char *)s;
|
||||
}
|
||||
|
||||
/* This function returns P if P points to EOS, or P+1 if P is NOT an open
|
||||
paren or brace, or a pointer to the character after the matching close
|
||||
paren or brace, skipping matched internal parens or braces.
|
||||
|
||||
It is typically called when we have seen a '$' in a string and we want to
|
||||
treat it as a variable reference and find the end of it: in that case P
|
||||
should point to the character after the '$'. */
|
||||
|
||||
char *
|
||||
skip_reference (const char *p)
|
||||
{
|
||||
char openparen = *p;
|
||||
char closeparen;
|
||||
int count = 1;
|
||||
|
||||
if (openparen == '\0')
|
||||
return (char*)p;
|
||||
|
||||
if (openparen == '(')
|
||||
closeparen = ')';
|
||||
else if (openparen == '{')
|
||||
closeparen = '}';
|
||||
else
|
||||
return (char*)(p+1);
|
||||
|
||||
while (1)
|
||||
{
|
||||
++p;
|
||||
if (!STOP_SET (*p, MAP_NUL|MAP_VARSEP))
|
||||
continue;
|
||||
if (*p == '\0')
|
||||
break;
|
||||
if (*p == openparen)
|
||||
++count;
|
||||
else if (*p == closeparen && --count == 0)
|
||||
{
|
||||
++p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (char*)p;
|
||||
}
|
||||
|
||||
/* Find the next token in PTR; return the address of it, and store the length
|
||||
of the token into *LENGTHPTR if LENGTHPTR is not nil. Set *PTR to the end
|
||||
of the token, so this function can be called repeatedly in a loop. */
|
||||
@ -371,6 +481,7 @@ find_next_token (const char **ptr, size_t *lengthptr)
|
||||
return (char *)p;
|
||||
}
|
||||
|
||||
|
||||
/* Write a BUFFER of size LEN to file descriptor FD.
|
||||
Retry short writes from EINTR. Return LEN, or -1 on error. */
|
||||
ssize_t
|
||||
@ -384,7 +495,7 @@ writebuf (int fd, const void *buffer, size_t len)
|
||||
|
||||
EINTRLOOP (r, write (fd, msg, l));
|
||||
if (r < 0)
|
||||
return r;
|
||||
return -1;
|
||||
|
||||
l -= r;
|
||||
msg += r;
|
||||
@ -394,8 +505,7 @@ writebuf (int fd, const void *buffer, size_t len)
|
||||
}
|
||||
|
||||
/* Read until we get LEN bytes from file descriptor FD, into BUFFER.
|
||||
Retry short reads on EINTR. If we get an error, return it.
|
||||
Return 0 at EOF. */
|
||||
Retry short reads on EINTR. Return 0 at EOF and -1 on error. */
|
||||
ssize_t
|
||||
readbuf (int fd, void *buffer, size_t len)
|
||||
{
|
||||
@ -406,7 +516,7 @@ readbuf (int fd, void *buffer, size_t len)
|
||||
|
||||
EINTRLOOP (r, read (fd, msg, len));
|
||||
if (r < 0)
|
||||
return r;
|
||||
return -1;
|
||||
if (r == 0)
|
||||
break;
|
||||
|
||||
@ -418,23 +528,38 @@ readbuf (int fd, void *buffer, size_t len)
|
||||
}
|
||||
|
||||
|
||||
/* Copy a 'struct dep'. For 2nd expansion deps, dup the name. */
|
||||
|
||||
struct dep *
|
||||
copy_dep (const struct dep *d)
|
||||
{
|
||||
struct dep *new = NULL;
|
||||
|
||||
if (d)
|
||||
{
|
||||
new = xmalloc (sizeof (struct dep));
|
||||
memcpy (new, d, sizeof (struct dep));
|
||||
|
||||
if (new->need_2nd_expansion)
|
||||
new->name = xstrdup (new->name);
|
||||
new->next = 0;
|
||||
}
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
/* Copy a chain of 'struct dep'. For 2nd expansion deps, dup the name. */
|
||||
|
||||
struct dep *
|
||||
copy_dep_chain (const struct dep *d)
|
||||
{
|
||||
struct dep *firstnew = 0;
|
||||
struct dep *lastnew = 0;
|
||||
struct dep *firstnew = NULL;
|
||||
struct dep *lastnew = NULL;
|
||||
|
||||
while (d != 0)
|
||||
{
|
||||
struct dep *c = xmalloc (sizeof (struct dep));
|
||||
memcpy (c, d, sizeof (struct dep));
|
||||
struct dep *c = copy_dep (d);
|
||||
|
||||
if (c->need_2nd_expansion)
|
||||
c->name = xstrdup (c->name);
|
||||
|
||||
c->next = 0;
|
||||
if (firstnew == 0)
|
||||
firstnew = lastnew = c;
|
||||
else
|
||||
@ -452,7 +577,7 @@ copy_dep_chain (const struct dep *d)
|
||||
void
|
||||
free_ns_chain (struct nameseq *ns)
|
||||
{
|
||||
while (ns != 0)
|
||||
while (ns != NULL)
|
||||
{
|
||||
struct nameseq *t = ns;
|
||||
ns = ns->next;
|
||||
@ -475,7 +600,7 @@ spin (const char* type)
|
||||
{
|
||||
fprintf (stderr, "SPIN on %s\n", filenm);
|
||||
do
|
||||
#ifdef WINDOWS32
|
||||
#if MK_OS_W32
|
||||
Sleep (1000);
|
||||
#else
|
||||
sleep (1);
|
||||
@ -484,6 +609,22 @@ spin (const char* type)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dbg (const char *fmt, ...)
|
||||
{
|
||||
FILE *fp = fopen ("/tmp/gmkdebug.log", "a+");
|
||||
va_list args;
|
||||
char buf[4096];
|
||||
|
||||
va_start (args, fmt);
|
||||
vsprintf (buf, fmt, args);
|
||||
va_end (args);
|
||||
|
||||
fprintf(fp, "%u: %s\n", (unsigned) make_pid (), buf);
|
||||
fflush (fp);
|
||||
fclose (fp);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@ -506,33 +647,49 @@ umask (mode_t mask)
|
||||
}
|
||||
#endif
|
||||
|
||||
#define MAKE_TMPDIR "MAKE_TMPDIR"
|
||||
#ifdef VMS
|
||||
#if MK_OS_VMS
|
||||
# define DEFAULT_TMPFILE "sys$scratch:gnv$make_cmdXXXXXX.com"
|
||||
# define DEFAULT_TMPDIR "/sys$scratch/"
|
||||
#else
|
||||
# define DEFAULT_TMPFILE "GmXXXXXX"
|
||||
# ifdef P_tmpdir
|
||||
# define DEFAULT_TMPDIR P_tmpdir
|
||||
# else
|
||||
# define DEFAULT_TMPDIR "/tmp"
|
||||
# endif
|
||||
# define DEFAULT_TMPFILE "GmXXXXXX"
|
||||
#endif
|
||||
|
||||
static const char *
|
||||
const char *
|
||||
get_tmpdir ()
|
||||
{
|
||||
static const char *tmpdir = NULL;
|
||||
|
||||
if (!tmpdir)
|
||||
{
|
||||
if (((tmpdir = getenv (MAKE_TMPDIR)) == NULL || *tmpdir == '\0')
|
||||
#if defined (__MSDOS__) || defined (WINDOWS32) || defined (__EMX__)
|
||||
&& ((tmpdir = getenv ("TMP")) == NULL || *tmpdir == '\0')
|
||||
&& ((tmpdir = getenv ("TEMP")) == NULL || *tmpdir == '\0')
|
||||
#if MK_OS_DOS || MK_OS_W32 || MK_OS_OS2
|
||||
# define TMP_EXTRAS "TMP", "TEMP",
|
||||
#else
|
||||
# define TMP_EXTRAS
|
||||
#endif
|
||||
&& ((tmpdir = getenv ("TMPDIR")) == NULL || *tmpdir == '\0'))
|
||||
tmpdir = DEFAULT_TMPDIR;
|
||||
const char *tlist[] = { "MAKE_TMPDIR", "TMPDIR", TMP_EXTRAS NULL };
|
||||
const char **tp;
|
||||
unsigned int found = 0;
|
||||
|
||||
for (tp = tlist; *tp; ++tp)
|
||||
if ((tmpdir = getenv (*tp)) != NULL && *tmpdir != '\0')
|
||||
{
|
||||
struct stat st;
|
||||
int r;
|
||||
found = 1;
|
||||
EINTRLOOP(r, stat (tmpdir, &st));
|
||||
if (r < 0)
|
||||
OSSS (error, NILF,
|
||||
_("%s value %s: %s"), *tp, tmpdir, strerror (errno));
|
||||
else if (! S_ISDIR (st.st_mode))
|
||||
OSS (error, NILF,
|
||||
_("%s value %s: not a directory"), *tp, tmpdir);
|
||||
else
|
||||
return tmpdir;
|
||||
}
|
||||
|
||||
tmpdir = DEFAULT_TMPDIR;
|
||||
|
||||
if (found)
|
||||
OS (error, NILF, _("using default temporary directory '%s'"), tmpdir);
|
||||
}
|
||||
|
||||
return tmpdir;
|
||||
@ -543,47 +700,58 @@ get_tmptemplate ()
|
||||
{
|
||||
const char *tmpdir = get_tmpdir ();
|
||||
char *template;
|
||||
size_t len;
|
||||
char *cp;
|
||||
|
||||
len = strlen (tmpdir);
|
||||
template = xmalloc (len + CSTRLEN (DEFAULT_TMPFILE) + 2);
|
||||
strcpy (template, tmpdir);
|
||||
template = xmalloc (strlen (tmpdir) + CSTRLEN (DEFAULT_TMPFILE) + 2);
|
||||
cp = stpcpy (template, tmpdir);
|
||||
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
if (template[len - 1] != '/' && template[len - 1] != '\\')
|
||||
strcat (template, "/");
|
||||
#else
|
||||
# ifndef VMS
|
||||
if (template[len - 1] != '/')
|
||||
strcat (template, "/");
|
||||
# endif /* !VMS */
|
||||
#endif /* !HAVE_DOS_PATHS */
|
||||
#if !MK_OS_VMS
|
||||
/* It's not possible for tmpdir to be empty. */
|
||||
if (! ISDIRSEP (cp[-1]))
|
||||
*(cp++) = '/';
|
||||
#endif
|
||||
|
||||
strcat (template, DEFAULT_TMPFILE);
|
||||
strcpy (cp, DEFAULT_TMPFILE);
|
||||
|
||||
return template;
|
||||
}
|
||||
|
||||
char *
|
||||
#if !HAVE_MKSTEMP || !HAVE_FDOPEN
|
||||
/* Generate a temporary filename. This is not safe as another program could
|
||||
snipe our filename after we've generated it: use this only on systems
|
||||
without more secure alternatives. */
|
||||
|
||||
static char *
|
||||
get_tmppath ()
|
||||
{
|
||||
char *path;
|
||||
|
||||
#ifdef HAVE_MKTEMP
|
||||
path = get_tmptemplate();
|
||||
# ifdef HAVE_MKTEMP
|
||||
path = get_tmptemplate ();
|
||||
if (*mktemp (path) == '\0')
|
||||
pfatal_with_name ("mktemp");
|
||||
#else
|
||||
{
|
||||
OSS (error, NILF,
|
||||
_("cannot generate temp path from %s: %s"), path, strerror (errno));
|
||||
return NULL;
|
||||
}
|
||||
# else
|
||||
path = xmalloc (L_tmpnam + 1);
|
||||
if (tmpnam (path) == NULL)
|
||||
pfatal_with_name ("tmpnam");
|
||||
#endif
|
||||
{
|
||||
OS (error, NILF,
|
||||
_("cannot generate temp name: %s"), strerror (errno));
|
||||
return NULL;
|
||||
}
|
||||
# endif
|
||||
|
||||
return path;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Generate a temporary file and return an fd for it. If name is NULL then
|
||||
the temp file is anonymous and will be deleted when the process exits. */
|
||||
the temp file is anonymous and will be deleted when the process exits. If
|
||||
name is not null then *name will point to an allocated buffer, or set to
|
||||
NULL on failure. */
|
||||
int
|
||||
get_tmpfd (char **name)
|
||||
{
|
||||
@ -591,15 +759,18 @@ get_tmpfd (char **name)
|
||||
char *tmpnm;
|
||||
mode_t mask;
|
||||
|
||||
/* If there's an os-specific way to get an anoymous temp file use it. */
|
||||
if (!name)
|
||||
if (name)
|
||||
*name = NULL;
|
||||
else
|
||||
{
|
||||
/* If there's an os-specific way to get an anonymous temp file use it. */
|
||||
fd = os_anontmp ();
|
||||
if (fd >= 0)
|
||||
return fd;
|
||||
}
|
||||
|
||||
/* Preserve the current umask, and set a restrictive one for temp files. */
|
||||
/* Preserve the current umask, and set a restrictive one for temp files.
|
||||
Only really needed for mkstemp() but won't hurt for the open method. */
|
||||
mask = umask (0077);
|
||||
|
||||
#if defined(HAVE_MKSTEMP)
|
||||
@ -609,55 +780,121 @@ get_tmpfd (char **name)
|
||||
EINTRLOOP (fd, mkstemp (tmpnm));
|
||||
#else
|
||||
tmpnm = get_tmppath ();
|
||||
if (!tmpnm)
|
||||
return -1;
|
||||
|
||||
/* Can't use mkstemp(), but try to guard against a race condition. */
|
||||
EINTRLOOP (fd, open (tmpnm, O_CREAT|O_EXCL|O_RDWR, 0600));
|
||||
#endif
|
||||
|
||||
umask (mask);
|
||||
if (fd < 0)
|
||||
{
|
||||
OSS (error, NILF,
|
||||
_("cannot create temporary file %s: %s"), tmpnm, strerror (errno));
|
||||
free (tmpnm);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (name)
|
||||
*name = tmpnm;
|
||||
else
|
||||
{
|
||||
unlink (tmpnm);
|
||||
int r;
|
||||
EINTRLOOP (r, unlink (tmpnm));
|
||||
if (r < 0)
|
||||
OSS (error, NILF,
|
||||
_("cannot unlink temporary file %s: %s"), tmpnm, strerror (errno));
|
||||
free (tmpnm);
|
||||
}
|
||||
|
||||
umask (mask);
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
/* Return a FILE* for a temporary file, opened in the safest way possible.
|
||||
Set name to point to an allocated buffer containing the name of the file,
|
||||
or NULL on failure. Note, name cannot be NULL! */
|
||||
FILE *
|
||||
get_tmpfile (char **name)
|
||||
{
|
||||
#if defined(HAVE_FDOPEN)
|
||||
int fd = get_tmpfd (name);
|
||||
/* Be consistent with tmpfile, which opens as if by "wb+". */
|
||||
const char *tmpfile_mode = "wb+";
|
||||
FILE *file;
|
||||
|
||||
return fd < 0 ? NULL : fdopen (fd, "w");
|
||||
#if defined(HAVE_FDOPEN)
|
||||
int fd;
|
||||
assert (name);
|
||||
fd = get_tmpfd (name);
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
assert (*name);
|
||||
|
||||
ENULLLOOP (file, fdopen (fd, tmpfile_mode));
|
||||
if (file == NULL)
|
||||
OSS (error, NILF,
|
||||
_("fdopen: temporary file %s: %s"), *name, strerror (errno));
|
||||
#else
|
||||
/* Preserve the current umask, and set a restrictive one for temp files. */
|
||||
mode_t mask = umask (0077);
|
||||
|
||||
char *tmpnm = get_tmppath ();
|
||||
assert (name);
|
||||
*name = get_tmppath ();
|
||||
if (!*name)
|
||||
return NULL;
|
||||
|
||||
/* Not secure, but...? If name is NULL we could use tmpfile()... */
|
||||
FILE *file = fopen (tmpnm, "w");
|
||||
/* Although this fopen is insecure, it is executed only on non-fdopen
|
||||
platforms, which should be a rarity nowadays. */
|
||||
|
||||
umask (mask);
|
||||
|
||||
if (name)
|
||||
*name = tmpnm;
|
||||
else
|
||||
ENULLLOOP (file, fopen (*name, tmpfile_mode));
|
||||
if (file == NULL)
|
||||
{
|
||||
unlink (tmpnm);
|
||||
free (tmpnm);
|
||||
OSS (error, NILF,
|
||||
_("fopen: temporary file %s: %s"), *name, strerror (errno));
|
||||
free (*name);
|
||||
*name = NULL;
|
||||
}
|
||||
|
||||
return file;
|
||||
umask (mask);
|
||||
#endif
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
|
||||
#if HAVE_TTYNAME && MK_OS_OS2
|
||||
/* OS/2 kLIBC has a declaration for ttyname(), so configure finds it.
|
||||
But, it is not implemented! Roll our own. */
|
||||
char *ttyname (int fd)
|
||||
{
|
||||
ULONG type;
|
||||
ULONG attr;
|
||||
ULONG rc;
|
||||
|
||||
rc = DosQueryHType (fd, &type, &attr);
|
||||
if (rc)
|
||||
{
|
||||
errno = EBADF;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (type == HANDTYPE_DEVICE)
|
||||
{
|
||||
if (attr & 3) /* 1 = KBD$, 2 = SCREEN$ */
|
||||
return (char *) "/dev/con";
|
||||
|
||||
if (attr & 4) /* 4 = NUL */
|
||||
return (char *) "/dev/nul";
|
||||
|
||||
if (attr & 8) /* 8 = CLOCK$ */
|
||||
return (char *) "/dev/clock$";
|
||||
}
|
||||
|
||||
errno = ENOTTY;
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if !HAVE_STRCASECMP && !HAVE_STRICMP && !HAVE_STRCMPI
|
||||
/* If we don't have strcasecmp() (from POSIX), or anything that can substitute
|
||||
for it, define our own version. */
|
||||
@ -688,7 +925,7 @@ strcasecmp (const char *s1, const char *s2)
|
||||
substitute for it, define our own version. */
|
||||
|
||||
int
|
||||
strncasecmp (const char *s1, const char *s2, int n)
|
||||
strncasecmp (const char *s1, const char *s2, size_t n)
|
||||
{
|
||||
while (n-- > 0)
|
||||
{
|
||||
@ -711,25 +948,6 @@ strncasecmp (const char *s1, const char *s2, int n)
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef NEED_GET_PATH_MAX
|
||||
unsigned int
|
||||
get_path_max (void)
|
||||
{
|
||||
static unsigned int value;
|
||||
|
||||
if (value == 0)
|
||||
{
|
||||
long int x = pathconf ("/", _PC_PATH_MAX);
|
||||
if (x > 0)
|
||||
value = x;
|
||||
else
|
||||
return MAXPATHLEN;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !HAVE_MEMPCPY
|
||||
void *
|
||||
mempcpy (void *dest, const void *src, size_t n)
|
||||
|
36
src/mkconfig.h.in
Normal file
36
src/mkconfig.h.in
Normal file
@ -0,0 +1,36 @@
|
||||
/* Autoconf values for use on non-POSIX systems.
|
||||
Copyright (C) 2022-2024 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Name of package */
|
||||
#define PACKAGE "@PACKAGE@"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT "@PACKAGE_BUGREPORT@"
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "@PACKAGE_NAME@"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "@PACKAGE_NAME@ @PACKAGE_VERSION@"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "@PACKAGE_TARNAME@"
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#define PACKAGE_URL "@PACKAGE_URL@"
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "@PACKAGE_VERSION@"
|
65
src/mkcustom.h
Normal file
65
src/mkcustom.h
Normal file
@ -0,0 +1,65 @@
|
||||
/* Miscellaneous global declarations and portability cruft for GNU Make.
|
||||
Copyright (C) 2023-2024 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/*
|
||||
This file is included at the end of config.h
|
||||
|
||||
That means it's included _everywhere_ as the first thing,
|
||||
INCLUDING content imported from gnulib. BE AWARE!!
|
||||
*/
|
||||
|
||||
#undef HAVE_CONFIG_H
|
||||
#define HAVE_CONFIG_H 1
|
||||
|
||||
/* Specify we want GNU source code. This must be defined before any
|
||||
system headers are included. */
|
||||
|
||||
#define _GNU_SOURCE 1
|
||||
|
||||
/* AIX requires this to be the first thing in the file. */
|
||||
#if HAVE_ALLOCA_H
|
||||
# include <alloca.h>
|
||||
#else
|
||||
# ifdef _AIX
|
||||
#pragma alloca
|
||||
# else
|
||||
# if !defined(__GNUC__) && !MK_OS_W32
|
||||
# ifndef alloca /* predefined by HP cc +Olibcalls */
|
||||
char *alloca ();
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Declare function prototypes for src/misc.c functions if needed. */
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#if !HAVE_STRCASECMP && !HAVE_STRICMP && !HAVE_STRCMPI
|
||||
int strcasecmp (const char *s1, const char *s2);
|
||||
#endif
|
||||
|
||||
#if !HAVE_STRNCASECMP && !HAVE_STRNICMP && !HAVE_STRNCMPI
|
||||
int strncasecmp (const char *s1, const char *s2, size_t n);
|
||||
#endif
|
||||
|
||||
#if !HAVE_MEMPCPY
|
||||
void *mempcpy (void *dest, const void *src, size_t n);
|
||||
#endif
|
||||
|
||||
#if !HAVE_STPCPY
|
||||
char *stpcpy (char *dest, const char *src);
|
||||
#endif
|
81
src/os.h
81
src/os.h
@ -1,5 +1,5 @@
|
||||
/* Declarations for operating system interfaces for GNU Make.
|
||||
Copyright (C) 2016-2022 Free Software Foundation, Inc.
|
||||
Copyright (C) 2016-2024 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
@ -12,8 +12,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#define IO_UNKNOWN 0x0001
|
||||
#define IO_COMBINED_OUTERR 0x0002
|
||||
@ -21,29 +20,31 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
#define IO_STDOUT_OK 0x0008
|
||||
#define IO_STDERR_OK 0x0010
|
||||
|
||||
#if defined(VMS) || defined(_AMIGA) || defined(__MSDOS__)
|
||||
# define check_io_state() (IO_STDIN_OK|IO_STDOUT_OK|IO_STDERR_OK)
|
||||
# define fd_inherit(_i) (0)
|
||||
# define fd_noinherit(_i) (0)
|
||||
# define fd_set_append(_i) (void)(0)
|
||||
#if MK_OS_VMS || MK_OS_DOS
|
||||
# define check_io_state() (IO_STDIN_OK|IO_STDOUT_OK|IO_STDERR_OK)
|
||||
# define fd_inherit(_i) (0)
|
||||
# define fd_noinherit(_i) (0)
|
||||
# define fd_set_append(_i) (-1)
|
||||
# define fd_reset_append(_i,_f) (void)(0)
|
||||
# define os_anontmp() (-1)
|
||||
#else
|
||||
|
||||
/* Determine the state of stdin/stdout/stderr. */
|
||||
unsigned int check_io_state ();
|
||||
unsigned int check_io_state (void);
|
||||
|
||||
/* Set a file descriptor to close/not close in a subprocess. */
|
||||
void fd_inherit (int);
|
||||
void fd_noinherit (int);
|
||||
void fd_inherit (int fd);
|
||||
void fd_noinherit (int fd);
|
||||
|
||||
/* If the file descriptor is for a file put it into append mode. */
|
||||
void fd_set_append (int);
|
||||
#endif
|
||||
/* If the file descriptor is for a file put it into append mode.
|
||||
Return the original flags for the file descriptor, or -1 if not found. */
|
||||
int fd_set_append (int fd);
|
||||
|
||||
/* Reset the append mode to the flags returned by fd_set_append(). */
|
||||
void fd_reset_append (int fd, int flags);
|
||||
|
||||
/* Return a file descriptor for a new anonymous temp file, or -1. */
|
||||
#if defined(WINDOWS32)
|
||||
int os_anontmp ();
|
||||
#else
|
||||
# define os_anontmp() (-1)
|
||||
int os_anontmp (void);
|
||||
#endif
|
||||
|
||||
/* This section provides OS-specific functions to support the jobserver. */
|
||||
@ -51,7 +52,7 @@ int os_anontmp ();
|
||||
#ifdef MAKE_JOBSERVER
|
||||
|
||||
/* Returns 1 if the jobserver is enabled, else 0. */
|
||||
unsigned int jobserver_enabled ();
|
||||
unsigned int jobserver_enabled (void);
|
||||
|
||||
/* Called in the parent make to set up the jobserver initially. */
|
||||
unsigned int jobserver_setup (int job_slots, const char *style);
|
||||
@ -61,23 +62,25 @@ unsigned int jobserver_setup (int job_slots, const char *style);
|
||||
unsigned int jobserver_parse_auth (const char* auth);
|
||||
|
||||
/* Returns an allocated buffer used to pass to child instances. */
|
||||
char *jobserver_get_auth ();
|
||||
char *jobserver_get_auth (void);
|
||||
|
||||
/* Returns a pointer to a static string used to indicate that the child
|
||||
cannot access the jobserver, or NULL if it always can. */
|
||||
const char *jobserver_get_invalid_auth ();
|
||||
const char *jobserver_get_invalid_auth (void);
|
||||
|
||||
/* Clear this instance's jobserver configuration. */
|
||||
void jobserver_clear ();
|
||||
/* Clear this instance's jobserver configuration.
|
||||
This method might be invoked from a signal handler. */
|
||||
void jobserver_clear (void);
|
||||
|
||||
/* Recover all the jobserver tokens and return the number we got. */
|
||||
unsigned int jobserver_acquire_all ();
|
||||
/* Recover all the jobserver tokens and return the number we got.
|
||||
Will also run jobserver_clear() as a side-effect. */
|
||||
unsigned int jobserver_acquire_all (void);
|
||||
|
||||
/* Release a jobserver token. If it fails and is_fatal is 1, fatal. */
|
||||
void jobserver_release (int is_fatal);
|
||||
|
||||
/* Notify the jobserver that a child exited. */
|
||||
void jobserver_signal ();
|
||||
void jobserver_signal (void);
|
||||
|
||||
/* Get ready to start a non-recursive child. */
|
||||
void jobserver_pre_child (int);
|
||||
@ -86,7 +89,7 @@ void jobserver_pre_child (int);
|
||||
void jobserver_post_child (int);
|
||||
|
||||
/* Set up to acquire a new token. */
|
||||
void jobserver_pre_acquire ();
|
||||
void jobserver_pre_acquire (void);
|
||||
|
||||
/* Wait until we can acquire a jobserver token.
|
||||
TIMEOUT is 1 if we have other jobs waiting for the load to go down;
|
||||
@ -116,28 +119,29 @@ unsigned int jobserver_acquire (int timeout);
|
||||
#ifndef NO_OUTPUT_SYNC
|
||||
|
||||
/* Returns 1 if output sync is enabled, else 0. */
|
||||
unsigned int osync_enabled ();
|
||||
unsigned int osync_enabled (void);
|
||||
|
||||
/* Called in the parent make to set up output sync initially. */
|
||||
void osync_setup ();
|
||||
void osync_setup (void);
|
||||
|
||||
/* Returns an allocated buffer containing output sync info to pass to child
|
||||
instances, or NULL if not needed. */
|
||||
char *osync_get_mutex ();
|
||||
char *osync_get_mutex (void);
|
||||
|
||||
/* Called in a child instance to obtain info on the output sync mutex.
|
||||
Return 1 if we got a valid mutex, else 0. */
|
||||
unsigned int osync_parse_mutex (const char *mutex);
|
||||
|
||||
/* Clean up this instance's output sync facilities. */
|
||||
void osync_clear ();
|
||||
/* Clean up this instance's output sync facilities.
|
||||
This method might be invoked from a signal handler. */
|
||||
void osync_clear (void);
|
||||
|
||||
/* Acquire the output sync lock. This will wait until available.
|
||||
Returns 0 if there was an error getting the semaphore. */
|
||||
unsigned int osync_acquire ();
|
||||
unsigned int osync_acquire (void);
|
||||
|
||||
/* Release the output sync lock. */
|
||||
void osync_release ();
|
||||
void osync_release (void);
|
||||
|
||||
#else
|
||||
|
||||
@ -152,8 +156,13 @@ void osync_release ();
|
||||
#endif /* NO_OUTPUT_SYNC */
|
||||
|
||||
/* Create a "bad" file descriptor for stdin when parallel jobs are run. */
|
||||
#if defined(VMS) || defined(WINDOWS32) || defined(_AMIGA) || defined(__MSDOS__)
|
||||
#if MK_OS_VMS || MK_OS_W32 || MK_OS_DOS
|
||||
# define get_bad_stdin() (-1)
|
||||
#else
|
||||
int get_bad_stdin ();
|
||||
int get_bad_stdin (void);
|
||||
#endif
|
||||
|
||||
#if MK_OS_W32
|
||||
#include <windows.h> /* Needed for HANDLE */
|
||||
HANDLE get_handle_for_fd (int);
|
||||
#endif
|
||||
|
155
src/output.c
155
src/output.c
@ -1,5 +1,5 @@
|
||||
/* Output to stdout / stderr for GNU make
|
||||
Copyright (C) 2013-2022 Free Software Foundation, Inc.
|
||||
/* Output to stdout / stderr for GNU Make
|
||||
Copyright (C) 2013-2024 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
@ -12,13 +12,13 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "makeint.h"
|
||||
#include "os.h"
|
||||
#include "output.h"
|
||||
|
||||
/* GNU make no longer supports pre-ANSI89 environments. */
|
||||
/* GNU Make no longer supports pre-ANSI89 environments. */
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
@ -34,11 +34,11 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
# include <sys/file.h>
|
||||
#endif
|
||||
|
||||
#ifdef WINDOWS32
|
||||
#if MK_OS_W32
|
||||
# include <windows.h>
|
||||
# include <io.h>
|
||||
# include "sub_proc.h"
|
||||
#endif /* WINDOWS32 */
|
||||
#endif
|
||||
|
||||
struct output *output_context = NULL;
|
||||
unsigned int stdio_traced = 0;
|
||||
@ -51,20 +51,24 @@ unsigned int stdio_traced = 0;
|
||||
static void
|
||||
_outputs (struct output *out, int is_err, const char *msg)
|
||||
{
|
||||
if (! out || ! out->syncout)
|
||||
{
|
||||
FILE *f = is_err ? stderr : stdout;
|
||||
fputs (msg, f);
|
||||
fflush (f);
|
||||
}
|
||||
else
|
||||
FILE *f;
|
||||
|
||||
if (out && out->syncout)
|
||||
{
|
||||
int fd = is_err ? out->err : out->out;
|
||||
size_t len = strlen (msg);
|
||||
int r;
|
||||
EINTRLOOP (r, lseek (fd, 0, SEEK_END));
|
||||
writebuf (fd, msg, len);
|
||||
if (fd != OUTPUT_NONE)
|
||||
{
|
||||
size_t len = strlen (msg);
|
||||
int r;
|
||||
EINTRLOOP (r, lseek (fd, 0, SEEK_END));
|
||||
writebuf (fd, msg, len);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
f = is_err ? stderr : stdout;
|
||||
fputs (msg, f);
|
||||
fflush (f);
|
||||
}
|
||||
|
||||
/* Write a message indicating that we've just entered or
|
||||
@ -147,7 +151,7 @@ pump_from_tmp (int from, FILE *to)
|
||||
{
|
||||
static char buffer[8192];
|
||||
|
||||
#ifdef WINDOWS32
|
||||
#if MK_OS_W32
|
||||
int prev_mode;
|
||||
|
||||
/* "from" is opened by open_tmpfd, which does it in binary mode, so
|
||||
@ -174,7 +178,7 @@ pump_from_tmp (int from, FILE *to)
|
||||
fflush (to);
|
||||
}
|
||||
|
||||
#ifdef WINDOWS32
|
||||
#if MK_OS_W32
|
||||
/* Switch "to" back to its original mode, so that log messages by
|
||||
Make have the same EOL format as without --output-sync. */
|
||||
_setmode (fileno (to), prev_mode);
|
||||
@ -198,7 +202,16 @@ output_tmpfd (void)
|
||||
static void
|
||||
setup_tmpfile (struct output *out)
|
||||
{
|
||||
unsigned int io_state = check_io_state ();
|
||||
static unsigned int in_setup = 0;
|
||||
unsigned int io_state;
|
||||
|
||||
/* If something fails during setup we might recurse back into this function
|
||||
while writing errors. Make sure we don't do so infinitely. */
|
||||
if (in_setup)
|
||||
return;
|
||||
in_setup = 1;
|
||||
|
||||
io_state = check_io_state ();
|
||||
|
||||
if (NONE_SET (io_state, IO_STDOUT_OK|IO_STDERR_OK))
|
||||
{
|
||||
@ -230,13 +243,18 @@ setup_tmpfile (struct output *out)
|
||||
}
|
||||
}
|
||||
|
||||
in_setup = 0;
|
||||
return;
|
||||
|
||||
/* If we failed to create a temp file, disable output sync going forward. */
|
||||
error:
|
||||
O (error, NILF,
|
||||
_("cannot open output-sync lock file: suppressing output-sync"));
|
||||
|
||||
output_close (out);
|
||||
output_sync = OUTPUT_SYNC_NONE;
|
||||
osync_clear ();
|
||||
in_setup = 0;
|
||||
}
|
||||
|
||||
/* Synchronize the output of jobs in -j mode to keep the results of
|
||||
@ -262,12 +280,13 @@ output_dump (struct output *out)
|
||||
if (!osync_acquire ())
|
||||
{
|
||||
O (error, NILF,
|
||||
_("warning: Cannot acquire output lock, disabling output sync."));
|
||||
_("warning: cannot acquire output lock: disabling output sync"));
|
||||
osync_clear ();
|
||||
}
|
||||
|
||||
/* Log the working directory for this dump. */
|
||||
if (print_directory && output_sync != OUTPUT_SYNC_RECURSE)
|
||||
|
||||
if (output_sync != OUTPUT_SYNC_RECURSE && should_print_dir ())
|
||||
traced = log_working_directory (1);
|
||||
|
||||
if (outfd_not_empty)
|
||||
@ -299,6 +318,9 @@ output_dump (struct output *out)
|
||||
#endif /* NO_OUTPUT_SYNC */
|
||||
|
||||
|
||||
static int stdout_flags = -1;
|
||||
static int stderr_flags = -1;
|
||||
|
||||
void
|
||||
output_init (struct output *out)
|
||||
{
|
||||
@ -311,8 +333,8 @@ output_init (struct output *out)
|
||||
|
||||
/* Force stdout/stderr into append mode (if they are files) to ensure
|
||||
parallel jobs won't lose output due to overlapping writes. */
|
||||
fd_set_append (fileno (stdout));
|
||||
fd_set_append (fileno (stderr));
|
||||
stdout_flags = fd_set_append (fileno (stdout));
|
||||
stderr_flags = fd_set_append (fileno (stderr));
|
||||
}
|
||||
|
||||
void
|
||||
@ -322,6 +344,8 @@ output_close (struct output *out)
|
||||
{
|
||||
if (stdio_traced)
|
||||
log_working_directory (0);
|
||||
fd_reset_append(fileno (stdout), stdout_flags);
|
||||
fd_reset_append(fileno (stderr), stderr_flags);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -351,7 +375,7 @@ output_start (void)
|
||||
/* If we're not syncing this output per-line or per-target, make sure we emit
|
||||
the "Entering..." message where appropriate. */
|
||||
if (output_sync == OUTPUT_SYNC_NONE || output_sync == OUTPUT_SYNC_RECURSE)
|
||||
if (! stdio_traced && print_directory)
|
||||
if (! stdio_traced && should_print_dir ())
|
||||
stdio_traced = log_working_directory (1);
|
||||
}
|
||||
|
||||
@ -394,19 +418,16 @@ void
|
||||
message (int prefix, size_t len, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char *start;
|
||||
char *p;
|
||||
|
||||
len += strlen (fmt) + strlen (program) + INTSTR_LENGTH + 4 + 1 + 1;
|
||||
p = get_buffer (len);
|
||||
start = p = get_buffer (len);
|
||||
|
||||
if (prefix)
|
||||
{
|
||||
if (makelevel == 0)
|
||||
sprintf (p, "%s: ", program);
|
||||
else
|
||||
sprintf (p, "%s[%u]: ", program, makelevel);
|
||||
p += strlen (p);
|
||||
}
|
||||
p += (makelevel == 0
|
||||
? sprintf (p, "%s: ", program)
|
||||
: sprintf (p, "%s[%u]: ", program, makelevel));
|
||||
|
||||
va_start (args, fmt);
|
||||
vsprintf (p, fmt, args);
|
||||
@ -414,8 +435,8 @@ message (int prefix, size_t len, const char *fmt, ...)
|
||||
|
||||
strcat (p, "\n");
|
||||
|
||||
assert (fmtbuf.buffer[len-1] == '\0');
|
||||
outputs (0, fmtbuf.buffer);
|
||||
assert (start[len-1] == '\0');
|
||||
outputs (0, start);
|
||||
}
|
||||
|
||||
/* Print an error message. */
|
||||
@ -424,20 +445,19 @@ void
|
||||
error (const floc *flocp, size_t len, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char *start;
|
||||
char *p;
|
||||
|
||||
len += (strlen (fmt) + strlen (program)
|
||||
+ (flocp && flocp->filenm ? strlen (flocp->filenm) : 0)
|
||||
+ INTSTR_LENGTH + 4 + 1 + 1);
|
||||
p = get_buffer (len);
|
||||
start = p = get_buffer (len);
|
||||
|
||||
if (flocp && flocp->filenm)
|
||||
sprintf (p, "%s:%lu: ", flocp->filenm, flocp->lineno + flocp->offset);
|
||||
else if (makelevel == 0)
|
||||
sprintf (p, "%s: ", program);
|
||||
else
|
||||
sprintf (p, "%s[%u]: ", program, makelevel);
|
||||
p += strlen (p);
|
||||
p += (flocp && flocp->filenm
|
||||
? sprintf (p, "%s:%lu: ", flocp->filenm, flocp->lineno + flocp->offset)
|
||||
: makelevel == 0
|
||||
? sprintf (p, "%s: ", program)
|
||||
: sprintf (p, "%s[%u]: ", program, makelevel));
|
||||
|
||||
va_start (args, fmt);
|
||||
vsprintf (p, fmt, args);
|
||||
@ -445,8 +465,8 @@ error (const floc *flocp, size_t len, const char *fmt, ...)
|
||||
|
||||
strcat (p, "\n");
|
||||
|
||||
assert (fmtbuf.buffer[len-1] == '\0');
|
||||
outputs (1, fmtbuf.buffer);
|
||||
assert (start[len-1] == '\0');
|
||||
outputs (1, start);
|
||||
}
|
||||
|
||||
/* Print an error message and exit. */
|
||||
@ -454,22 +474,22 @@ error (const floc *flocp, size_t len, const char *fmt, ...)
|
||||
void
|
||||
fatal (const floc *flocp, size_t len, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
const char *stop = _(". Stop.\n");
|
||||
va_list args;
|
||||
char *start;
|
||||
char *p;
|
||||
|
||||
len += (strlen (fmt) + strlen (program)
|
||||
+ (flocp && flocp->filenm ? strlen (flocp->filenm) : 0)
|
||||
+ INTSTR_LENGTH + 8 + strlen (stop) + 1);
|
||||
p = get_buffer (len);
|
||||
start = p = get_buffer (len);
|
||||
|
||||
if (flocp && flocp->filenm)
|
||||
sprintf (p, "%s:%lu: *** ", flocp->filenm, flocp->lineno + flocp->offset);
|
||||
else if (makelevel == 0)
|
||||
sprintf (p, "%s: *** ", program);
|
||||
else
|
||||
sprintf (p, "%s[%u]: *** ", program, makelevel);
|
||||
p += strlen (p);
|
||||
p += (flocp && flocp->filenm
|
||||
? sprintf (p, "%s:%lu: *** ", flocp->filenm,
|
||||
flocp->lineno + flocp->offset)
|
||||
: makelevel == 0
|
||||
? sprintf (p, "%s: *** ", program)
|
||||
: sprintf (p, "%s[%u]: *** ", program, makelevel));
|
||||
|
||||
va_start (args, fmt);
|
||||
vsprintf (p, fmt, args);
|
||||
@ -477,12 +497,35 @@ fatal (const floc *flocp, size_t len, const char *fmt, ...)
|
||||
|
||||
strcat (p, stop);
|
||||
|
||||
assert (fmtbuf.buffer[len-1] == '\0');
|
||||
outputs (1, fmtbuf.buffer);
|
||||
assert (start[len-1] == '\0');
|
||||
outputs (1, start);
|
||||
|
||||
die (MAKE_FAILURE);
|
||||
}
|
||||
|
||||
/* Format a message and return a pointer to an internal buffer. */
|
||||
|
||||
char *
|
||||
format (const char *prefix, size_t len, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
size_t plen = prefix ? strlen (prefix) : 0;
|
||||
char *start;
|
||||
char *p;
|
||||
|
||||
len += strlen (fmt) + plen + 1;
|
||||
start = p = get_buffer (len);
|
||||
|
||||
if (plen)
|
||||
p = mempcpy (p, prefix, plen);
|
||||
|
||||
va_start (args, fmt);
|
||||
vsprintf (p, fmt, args);
|
||||
va_end (args);
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
/* Print an error message from errno. */
|
||||
|
||||
void
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Output to stdout / stderr for GNU make
|
||||
Copyright (C) 2013-2022 Free Software Foundation, Inc.
|
||||
/* Output to stdout / stderr for GNU Make
|
||||
Copyright (C) 2013-2024 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
@ -12,7 +12,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
struct output
|
||||
{
|
||||
|
206
src/posixos.c
206
src/posixos.c
@ -1,5 +1,5 @@
|
||||
/* POSIX-based operating system interface for GNU Make.
|
||||
Copyright (C) 2016-2022 Free Software Foundation, Inc.
|
||||
Copyright (C) 2016-2024 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
@ -12,7 +12,7 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "makeint.h"
|
||||
|
||||
@ -24,6 +24,10 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
#elif defined(HAVE_SYS_FILE_H)
|
||||
# include <sys/file.h>
|
||||
#endif
|
||||
#if MK_OS_ZOS
|
||||
/* FIXME: HAVE_PSELECT path hangs on z/OS */
|
||||
#undef HAVE_PSELECT
|
||||
#endif
|
||||
|
||||
#if !defined(FD_OK)
|
||||
# define FD_OK(_f) 1
|
||||
@ -75,6 +79,9 @@ check_io_state ()
|
||||
|
||||
/* This section provides OS-specific functions to support the jobserver. */
|
||||
|
||||
/* True if this is the root make instance. */
|
||||
static unsigned char job_root = 0;
|
||||
|
||||
/* These track the state of the jobserver pipe. Passed to child instances. */
|
||||
static int job_fds[2] = { -1, -1 };
|
||||
|
||||
@ -115,10 +122,8 @@ make_job_rfd ()
|
||||
}
|
||||
|
||||
static void
|
||||
set_blocking (int fd, int blocking)
|
||||
force_blocking (int fd, int blocking)
|
||||
{
|
||||
/* If we're not using pselect() don't change the blocking. */
|
||||
#ifdef HAVE_PSELECT
|
||||
int flags;
|
||||
EINTRLOOP (flags, fcntl (fd, F_GETFL));
|
||||
if (flags >= 0)
|
||||
@ -129,18 +134,42 @@ set_blocking (int fd, int blocking)
|
||||
if (r < 0)
|
||||
pfatal_with_name ("fcntl(O_NONBLOCK)");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_blocking (int fd, int blocking)
|
||||
{
|
||||
/* If we're not using pselect() don't change the blocking. */
|
||||
#ifdef HAVE_PSELECT
|
||||
force_blocking (fd, blocking);
|
||||
#else
|
||||
(void) fd;
|
||||
(void) blocking;
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned int
|
||||
jobserver_setup (int slots, const char *style)
|
||||
{
|
||||
int r;
|
||||
int r, k;
|
||||
|
||||
#if HAVE_MKFIFO
|
||||
if (style == NULL || strcmp (style, "fifo") == 0)
|
||||
/* This function sets up the root jobserver. */
|
||||
job_root = 1;
|
||||
|
||||
#if JOBSERVER_USE_FIFO
|
||||
if (!style || strcmp (style, "fifo") == 0)
|
||||
{
|
||||
fifo_name = get_tmppath ();
|
||||
/* Unfortunately glibc warns about uses of mktemp even though we aren't
|
||||
using it in dangerous way here. So avoid this by generating our own
|
||||
temporary file name. The template in misc.c uses 6 X's so be sure this
|
||||
name cannot conflict with that. */
|
||||
# define FNAME_PREFIX "GmFIFO"
|
||||
const char *tmpdir = get_tmpdir ();
|
||||
|
||||
fifo_name = xmalloc (strlen (tmpdir) + CSTRLEN (FNAME_PREFIX)
|
||||
+ INTSTR_LENGTH + 2);
|
||||
sprintf (fifo_name, "%s/" FNAME_PREFIX "%03" MK_PRI64_PREFIX "d",
|
||||
tmpdir, (long long)make_pid ());
|
||||
|
||||
EINTRLOOP (r, mkfifo (fifo_name, 0600));
|
||||
if (r < 0)
|
||||
@ -155,16 +184,14 @@ jobserver_setup (int slots, const char *style)
|
||||
hang until the write side is open. */
|
||||
EINTRLOOP (job_fds[0], open (fifo_name, O_RDONLY|O_NONBLOCK));
|
||||
if (job_fds[0] < 0)
|
||||
OSS (fatal, NILF, _("Cannot open jobserver %s: %s"),
|
||||
OSS (fatal, NILF, _("cannot open jobserver %s: %s"),
|
||||
fifo_name, strerror (errno));
|
||||
|
||||
EINTRLOOP (job_fds[1], open (fifo_name, O_WRONLY));
|
||||
if (job_fds[0] < 0)
|
||||
OSS (fatal, NILF, _("Cannot open jobserver %s: %s"),
|
||||
OSS (fatal, NILF, _("cannot open jobserver %s: %s"),
|
||||
fifo_name, strerror (errno));
|
||||
|
||||
DB (DB_JOBS, (_("Jobserver setup (fifo %s)\n"), fifo_name));
|
||||
|
||||
js_type = js_fifo;
|
||||
}
|
||||
}
|
||||
@ -173,15 +200,12 @@ jobserver_setup (int slots, const char *style)
|
||||
if (js_type == js_none)
|
||||
{
|
||||
if (style && strcmp (style, "pipe") != 0)
|
||||
OS (fatal, NILF, _("Unknown jobserver auth style '%s'"), style);
|
||||
OS (fatal, NILF, _("unknown jobserver auth style '%s'"), style);
|
||||
|
||||
EINTRLOOP (r, pipe (job_fds));
|
||||
if (r < 0)
|
||||
pfatal_with_name (_("creating jobs pipe"));
|
||||
|
||||
DB (DB_JOBS, (_("Jobserver setup (fds %d,%d)\n"),
|
||||
job_fds[0], job_fds[1]));
|
||||
|
||||
js_type = js_pipe;
|
||||
}
|
||||
|
||||
@ -193,12 +217,21 @@ jobserver_setup (int slots, const char *style)
|
||||
if (make_job_rfd () < 0)
|
||||
pfatal_with_name (_("duping jobs pipe"));
|
||||
|
||||
while (slots--)
|
||||
/* Set the write side of the pipe to non blocking in case the number of
|
||||
slots specified by the user exceeds pipe capacity. */
|
||||
force_blocking (job_fds[1], 0);
|
||||
for (k = 0; k < slots; ++k)
|
||||
{
|
||||
EINTRLOOP (r, write (job_fds[1], &token, 1));
|
||||
if (r != 1)
|
||||
pfatal_with_name (_("init jobserver pipe"));
|
||||
{
|
||||
if (errno != EAGAIN)
|
||||
pfatal_with_name (_("init jobserver pipe"));
|
||||
|
||||
ONN (fatal, NILF, _("requested job count (%d) is larger than system limit (%d)"), slots+1, k);
|
||||
}
|
||||
}
|
||||
force_blocking (job_fds[1], 1);
|
||||
|
||||
/* When using pselect() we want the read to be non-blocking. */
|
||||
set_blocking (job_fds[0], 0);
|
||||
@ -220,21 +253,24 @@ jobserver_parse_auth (const char *auth)
|
||||
|
||||
EINTRLOOP (job_fds[0], open (fifo_name, O_RDONLY));
|
||||
if (job_fds[0] < 0)
|
||||
OSS (fatal, NILF,
|
||||
_("Cannot open jobserver %s: %s"), fifo_name, strerror (errno));
|
||||
{
|
||||
OSS (error, NILF,
|
||||
_("cannot open jobserver %s: %s"), fifo_name, strerror (errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
EINTRLOOP (job_fds[1], open (fifo_name, O_WRONLY));
|
||||
if (job_fds[0] < 0)
|
||||
OSS (fatal, NILF,
|
||||
_("Cannot open jobserver %s: %s"), fifo_name, strerror (errno));
|
||||
|
||||
if (job_fds[1] < 0)
|
||||
{
|
||||
OSS (error, NILF,
|
||||
_("cannot open jobserver %s: %s"), fifo_name, strerror (errno));
|
||||
return 0;
|
||||
}
|
||||
js_type = js_fifo;
|
||||
}
|
||||
/* If not, it must be a simple pipe. */
|
||||
else if (sscanf (auth, "%d,%d", &rfd, &wfd) == 2)
|
||||
{
|
||||
DB (DB_JOBS, (_("Jobserver client (fds %d,%d)\n"), rfd, wfd));
|
||||
|
||||
/* The parent overrode our FDs because we aren't a recursive make. */
|
||||
if (rfd == -2 || wfd == -2)
|
||||
return 0;
|
||||
@ -327,8 +363,20 @@ jobserver_clear ()
|
||||
|
||||
job_fds[0] = job_fds[1] = job_rfd = -1;
|
||||
|
||||
free (fifo_name);
|
||||
fifo_name = NULL;
|
||||
if (fifo_name)
|
||||
{
|
||||
if (job_root)
|
||||
{
|
||||
int r;
|
||||
EINTRLOOP (r, unlink (fifo_name));
|
||||
}
|
||||
|
||||
if (!handling_fatal_signal)
|
||||
{
|
||||
free (fifo_name);
|
||||
fifo_name = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
js_type = js_none;
|
||||
}
|
||||
@ -368,11 +416,10 @@ jobserver_acquire_all ()
|
||||
++tokens;
|
||||
}
|
||||
|
||||
if (fifo_name)
|
||||
EINTRLOOP (r, unlink (fifo_name));
|
||||
|
||||
DB (DB_JOBS, ("Acquired all %u jobserver tokens.\n", tokens));
|
||||
|
||||
jobserver_clear ();
|
||||
|
||||
return tokens;
|
||||
}
|
||||
|
||||
@ -462,7 +509,7 @@ jobserver_acquire (int timeout)
|
||||
case EBADF:
|
||||
/* Someone closed the jobs pipe.
|
||||
That shouldn't happen but if it does we're done. */
|
||||
O (fatal, NILF, _("job server shut down"));
|
||||
O (fatal, NILF, _("job server shut down"));
|
||||
|
||||
default:
|
||||
pfatal_with_name (_("pselect jobs pipe"));
|
||||
@ -527,7 +574,7 @@ set_child_handler_action_flags (int set_handler, int set_alarm)
|
||||
{
|
||||
struct sigaction sa;
|
||||
|
||||
#ifdef __EMX__
|
||||
#if MK_OS_OS2
|
||||
/* The child handler must be turned off here. */
|
||||
signal (SIGCHLD, SIG_DFL);
|
||||
#endif
|
||||
@ -594,7 +641,7 @@ jobserver_acquire (int timeout)
|
||||
go back and reap_children(), and try again. */
|
||||
errno = saved_errno;
|
||||
|
||||
if (errno != EINTR && errno != EBADF)
|
||||
if (errno != EINTR && errno != EBADF && errno != EAGAIN)
|
||||
pfatal_with_name (_("read jobs pipe"));
|
||||
|
||||
if (errno == EBADF)
|
||||
@ -615,7 +662,7 @@ static int osync_handle = -1;
|
||||
|
||||
static char *osync_tmpfile = NULL;
|
||||
|
||||
static unsigned int sync_parent = 0;
|
||||
static unsigned int sync_root = 0;
|
||||
|
||||
unsigned int
|
||||
osync_enabled ()
|
||||
@ -627,8 +674,8 @@ void
|
||||
osync_setup ()
|
||||
{
|
||||
osync_handle = get_tmpfd (&osync_tmpfile);
|
||||
if (osync_handle >= 0)
|
||||
sync_parent = 1;
|
||||
fd_noinherit (osync_handle);
|
||||
sync_root = 1;
|
||||
}
|
||||
|
||||
char *
|
||||
@ -655,6 +702,7 @@ osync_parse_mutex (const char *mutex)
|
||||
return 0;
|
||||
}
|
||||
|
||||
free (osync_tmpfile);
|
||||
osync_tmpfile = xstrdup (mutex + CSTRLEN (MUTEX_PREFIX));
|
||||
|
||||
EINTRLOOP (osync_handle, open (osync_tmpfile, O_WRONLY));
|
||||
@ -662,21 +710,26 @@ osync_parse_mutex (const char *mutex)
|
||||
OSS (fatal, NILF, _("cannot open output sync mutex %s: %s"),
|
||||
osync_tmpfile, strerror (errno));
|
||||
|
||||
fd_noinherit (osync_handle);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
osync_clear ()
|
||||
{
|
||||
if (osync_handle)
|
||||
if (osync_handle >= 0)
|
||||
{
|
||||
close (osync_handle);
|
||||
osync_handle = -1;
|
||||
}
|
||||
|
||||
if (sync_parent && osync_tmpfile)
|
||||
if (sync_root && osync_tmpfile)
|
||||
{
|
||||
unlink (osync_tmpfile);
|
||||
int r;
|
||||
|
||||
EINTRLOOP (r, unlink (osync_tmpfile));
|
||||
free (osync_tmpfile);
|
||||
osync_tmpfile = NULL;
|
||||
}
|
||||
}
|
||||
@ -692,6 +745,7 @@ osync_acquire ()
|
||||
fl.l_whence = SEEK_SET;
|
||||
fl.l_start = 0;
|
||||
fl.l_len = 1;
|
||||
/* We don't want to keep waiting on EINTR. */
|
||||
if (fcntl (osync_handle, F_SETLKW, &fl) == -1)
|
||||
{
|
||||
perror ("fcntl()");
|
||||
@ -713,6 +767,7 @@ osync_release ()
|
||||
fl.l_whence = SEEK_SET;
|
||||
fl.l_start = 0;
|
||||
fl.l_len = 1;
|
||||
/* We don't want to keep waiting on EINTR. */
|
||||
if (fcntl (osync_handle, F_SETLKW, &fl) == -1)
|
||||
perror ("fcntl()");
|
||||
}
|
||||
@ -736,7 +791,7 @@ get_bad_stdin ()
|
||||
if (pipe (pd) == 0)
|
||||
{
|
||||
/* Close the write side. */
|
||||
(void) close (pd[1]);
|
||||
close (pd[1]);
|
||||
/* Save the read side. */
|
||||
bad_stdin = pd[0];
|
||||
|
||||
@ -792,12 +847,12 @@ fd_noinherit (int fd)
|
||||
/* Set a file descriptor referring to a regular file to be in O_APPEND mode.
|
||||
If it fails, just ignore it. */
|
||||
|
||||
void
|
||||
int
|
||||
fd_set_append (int fd)
|
||||
{
|
||||
int flags = -1;
|
||||
#if defined(F_GETFL) && defined(F_SETFL) && defined(O_APPEND)
|
||||
struct stat stbuf;
|
||||
int flags;
|
||||
if (fstat (fd, &stbuf) == 0 && S_ISREG (stbuf.st_mode))
|
||||
{
|
||||
flags = fcntl (fd, F_GETFL, 0);
|
||||
@ -808,4 +863,67 @@ fd_set_append (int fd)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return flags;
|
||||
}
|
||||
|
||||
/* Reset a file descriptor referring to a regular file to be in O_APPEND mode.
|
||||
If it fails, just ignore it. */
|
||||
|
||||
void
|
||||
fd_reset_append (int fd, int flags)
|
||||
{
|
||||
#if defined(F_GETFL) && defined(F_SETFL) && defined(O_APPEND)
|
||||
if (flags >= 0)
|
||||
{
|
||||
int r;
|
||||
EINTRLOOP(r, fcntl (fd, F_SETFL, flags));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Return a file descriptor for a new anonymous temp file, or -1. */
|
||||
int
|
||||
os_anontmp ()
|
||||
{
|
||||
const char *tdir = get_tmpdir ();
|
||||
int fd = -1;
|
||||
|
||||
#ifdef O_TMPFILE
|
||||
static unsigned int tmpfile_works = 1;
|
||||
|
||||
if (tmpfile_works)
|
||||
{
|
||||
EINTRLOOP (fd, open (tdir, O_RDWR | O_TMPFILE | O_EXCL, 0600));
|
||||
if (fd >= 0)
|
||||
return fd;
|
||||
|
||||
DB (DB_BASIC, (_("Cannot open '%s' with O_TMPFILE: %s.\n"),
|
||||
tdir, strerror (errno)));
|
||||
tmpfile_works = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAVE_DUP
|
||||
/* If we can dup and we are creating temp files in the default location then
|
||||
try tmpfile() + dup() + fclose() to avoid ever having a named file. */
|
||||
if (streq (tdir, DEFAULT_TMPDIR))
|
||||
{
|
||||
mode_t mask = umask (0077);
|
||||
FILE *tfile;
|
||||
ENULLLOOP (tfile, tmpfile ());
|
||||
if (!tfile)
|
||||
{
|
||||
OS (error, NILF, "tmpfile: %s", strerror (errno));
|
||||
return -1;
|
||||
}
|
||||
umask (mask);
|
||||
|
||||
EINTRLOOP (fd, dup (fileno (tfile)));
|
||||
if (fd < 0)
|
||||
OS (error, NILF, "dup: %s", strerror (errno));
|
||||
fclose (tfile);
|
||||
}
|
||||
#endif
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
483
src/read.c
483
src/read.c
@ -1,5 +1,5 @@
|
||||
/* Reading and parsing of makefiles for GNU Make.
|
||||
Copyright (C) 1988-2022 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988-2024 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify it under the
|
||||
@ -12,12 +12,21 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "makeint.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#if MK_OS_W32
|
||||
# include <windows.h>
|
||||
# include "sub_proc.h"
|
||||
#elif MK_OS_VMS
|
||||
struct passwd *getpwnam (char *name);
|
||||
#else
|
||||
# include <pwd.h>
|
||||
#endif
|
||||
|
||||
#include "filedef.h"
|
||||
#include "dep.h"
|
||||
#include "job.h"
|
||||
@ -27,20 +36,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
#include "rule.h"
|
||||
#include "debug.h"
|
||||
#include "hash.h"
|
||||
|
||||
|
||||
#ifdef WINDOWS32
|
||||
#include <windows.h>
|
||||
#include "sub_proc.h"
|
||||
#else /* !WINDOWS32 */
|
||||
#ifndef _AMIGA
|
||||
#ifndef VMS
|
||||
#include <pwd.h>
|
||||
#else
|
||||
struct passwd *getpwnam (char *name);
|
||||
#endif
|
||||
#endif
|
||||
#endif /* !WINDOWS32 */
|
||||
#include "warning.h"
|
||||
|
||||
/* A 'struct ebuffer' controls the origin of the makefile we are currently
|
||||
eval'ing.
|
||||
@ -72,7 +68,7 @@ struct vmodifiers
|
||||
enum make_word_type
|
||||
{
|
||||
w_bogus, w_eol, w_static, w_variable, w_colon, w_dcolon, w_semicolon,
|
||||
w_varassign, w_ampcolon, w_ampdcolon
|
||||
w_ampcolon, w_ampdcolon
|
||||
};
|
||||
|
||||
|
||||
@ -100,9 +96,9 @@ static struct conditionals *conditionals = &toplevel_conditionals;
|
||||
|
||||
/* Default directories to search for include files in */
|
||||
|
||||
static const char *default_include_directories[] =
|
||||
static const char *const default_include_directories[] =
|
||||
{
|
||||
#if defined(WINDOWS32) && !defined(INCLUDEDIR)
|
||||
#if MK_OS_W32 && !defined(INCLUDEDIR)
|
||||
/* This completely up to the user when they install MSVC or other packages.
|
||||
This is defined as a placeholder. */
|
||||
# define INCLUDEDIR "."
|
||||
@ -110,12 +106,10 @@ static const char *default_include_directories[] =
|
||||
#if defined(INCLUDEDIR)
|
||||
INCLUDEDIR,
|
||||
#endif
|
||||
#ifndef _AMIGA
|
||||
"/usr/gnu/include",
|
||||
"/usr/local/include",
|
||||
"/usr/include",
|
||||
#endif
|
||||
0
|
||||
NULL
|
||||
};
|
||||
|
||||
/* List of directories to search for include files in */
|
||||
@ -192,15 +186,7 @@ read_all_makefiles (const char **makefiles)
|
||||
char *name, *p;
|
||||
size_t length;
|
||||
|
||||
{
|
||||
/* Turn off --warn-undefined-variables while we expand MAKEFILES. */
|
||||
int save = warn_undefined_variables_flag;
|
||||
warn_undefined_variables_flag = 0;
|
||||
|
||||
value = allocated_variable_expand ("$(MAKEFILES)");
|
||||
|
||||
warn_undefined_variables_flag = save;
|
||||
}
|
||||
value = allocated_expand_variable (STRING_SIZE_TUPLE ("MAKEFILES"));
|
||||
|
||||
/* Set NAME to the start of next token and LENGTH to its length.
|
||||
MAKEFILES is updated for finding remaining tokens. */
|
||||
@ -236,23 +222,19 @@ read_all_makefiles (const char **makefiles)
|
||||
|
||||
if (num_makefiles == 0)
|
||||
{
|
||||
static const char *default_makefiles[] =
|
||||
#ifdef VMS
|
||||
static const char *const default_makefiles[] =
|
||||
#if MK_OS_VMS
|
||||
/* all lower case since readdir() (the vms version) 'lowercasifies' */
|
||||
/* TODO: Above is not always true, this needs more work */
|
||||
{ "makefile.vms", "gnumakefile", "makefile", 0 };
|
||||
#else
|
||||
#ifdef _AMIGA
|
||||
{ "GNUmakefile", "Makefile", "SMakefile", 0 };
|
||||
#else /* !Amiga && !VMS */
|
||||
#ifdef WINDOWS32
|
||||
#if MK_OS_W32
|
||||
{ "GNUmakefile", "makefile", "Makefile", "makefile.mak", 0 };
|
||||
#else /* !Amiga && !VMS && !WINDOWS32 */
|
||||
#else /* !MK_OS_VMS && !MK_OS_W32 */
|
||||
{ "GNUmakefile", "makefile", "Makefile", 0 };
|
||||
#endif /* !Amiga && !VMS && !WINDOWS32 */
|
||||
#endif /* AMIGA */
|
||||
#endif /* VMS */
|
||||
const char **p = default_makefiles;
|
||||
#endif /* !MK_OS_VMS && !MK_OS_W32 */
|
||||
#endif /* MK_OS_VMS */
|
||||
const char *const *p = default_makefiles;
|
||||
while (*p != 0 && !file_exists_p (*p))
|
||||
++p;
|
||||
|
||||
@ -373,25 +355,29 @@ eval_makefile (const char *filename, unsigned short flags)
|
||||
/* If the makefile wasn't found and it's either a makefile from the
|
||||
'MAKEFILES' variable or an included makefile, search the included
|
||||
makefile search path for this makefile. */
|
||||
if (ebuf.fp == NULL && deps->error == ENOENT && (flags & RM_INCLUDED)
|
||||
&& *filename != '/' && include_directories)
|
||||
for (const char **dir = include_directories; *dir != NULL; ++dir)
|
||||
{
|
||||
const char *included = concat (3, *dir, "/", filename);
|
||||
if (ebuf.fp == NULL && deps->error == ENOENT && include_directories
|
||||
&& ANY_SET (flags, RM_INCLUDED)
|
||||
&& !HAS_DRIVESPEC (filename) && !ISDIRSEP (*filename))
|
||||
{
|
||||
const char **dir;
|
||||
for (dir = include_directories; *dir != NULL; ++dir)
|
||||
{
|
||||
const char *included = concat (3, *dir, "/", filename);
|
||||
|
||||
ENULLLOOP(ebuf.fp, fopen (included, "r"));
|
||||
if (ebuf.fp)
|
||||
{
|
||||
filename = included;
|
||||
break;
|
||||
}
|
||||
if (errno != ENOENT)
|
||||
{
|
||||
filename = included;
|
||||
deps->error = errno;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ENULLLOOP(ebuf.fp, fopen (included, "r"));
|
||||
if (ebuf.fp)
|
||||
{
|
||||
filename = included;
|
||||
break;
|
||||
}
|
||||
if (errno != ENOENT)
|
||||
{
|
||||
filename = included;
|
||||
deps->error = errno;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Enter the final name for this makefile as a goaldep. */
|
||||
filename = strcache_add (filename);
|
||||
@ -400,6 +386,7 @@ eval_makefile (const char *filename, unsigned short flags)
|
||||
deps->file = enter_file (filename);
|
||||
filename = deps->file->name;
|
||||
deps->flags = flags;
|
||||
deps->file->is_explicit = 1;
|
||||
|
||||
free (expanded);
|
||||
|
||||
@ -426,7 +413,7 @@ eval_makefile (const char *filename, unsigned short flags)
|
||||
|
||||
/* Add this makefile to the list. */
|
||||
do_variable_definition (&ebuf.floc, "MAKEFILE_LIST", filename, o_file,
|
||||
f_append_value, 0);
|
||||
f_append_value, 0, s_global);
|
||||
|
||||
/* Evaluate the makefile */
|
||||
|
||||
@ -634,6 +621,7 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
size_t wlen;
|
||||
char *p;
|
||||
char *p2;
|
||||
unsigned int is_rule;
|
||||
struct vmodifiers vmod;
|
||||
|
||||
/* At the top of this loop, we are starting a brand new line. */
|
||||
@ -678,16 +666,16 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
/* Ignore the commands in a rule with no targets. */
|
||||
continue;
|
||||
|
||||
if (ignoring)
|
||||
/* Yep, this is a shell command, and we don't care. */
|
||||
continue;
|
||||
|
||||
/* If there is no preceding rule line, don't treat this line
|
||||
as a command, even though it begins with a recipe prefix.
|
||||
SunOS 4 make appears to behave this way. */
|
||||
|
||||
if (filenames != 0)
|
||||
{
|
||||
if (ignoring)
|
||||
/* Yep, this is a shell command, and we don't care. */
|
||||
continue;
|
||||
|
||||
if (commands_idx == 0)
|
||||
cmds_started = ebuf->floc.lineno;
|
||||
|
||||
@ -745,14 +733,14 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
record_waiting_files ();
|
||||
|
||||
if (vmod.undefine_v)
|
||||
{
|
||||
do_undefine (p, origin, ebuf);
|
||||
continue;
|
||||
}
|
||||
else if (vmod.define_v)
|
||||
{
|
||||
do_undefine (p, origin, ebuf);
|
||||
continue;
|
||||
}
|
||||
if (vmod.define_v)
|
||||
v = do_define (p, origin, ebuf);
|
||||
else
|
||||
v = try_variable_definition (fstart, p, origin, 0);
|
||||
v = try_variable_definition (fstart, p, origin, s_global);
|
||||
|
||||
assert (v != NULL);
|
||||
|
||||
@ -773,6 +761,8 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
wlen = p2 - p;
|
||||
NEXT_TOKEN (p2);
|
||||
|
||||
is_rule = *p2 == ':' || ((*p2 == '&' || *p2 == '|') && p2[1] == ':');
|
||||
|
||||
/* If we're in an ignored define, skip this line (but maybe get out). */
|
||||
if (in_ignored_define)
|
||||
{
|
||||
@ -820,7 +810,7 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
|
||||
/* Expand the line so we can use indirect and constructed
|
||||
variable names in an (un)export command. */
|
||||
cp = ap = allocated_variable_expand (p2);
|
||||
cp = ap = allocated_expand_string (p2);
|
||||
|
||||
for (p = find_next_token (&cp, &l); p != 0;
|
||||
p = find_next_token (&cp, &l))
|
||||
@ -846,7 +836,7 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
/* vpath ends the previous rule. */
|
||||
record_waiting_files ();
|
||||
|
||||
cp = variable_expand (p2);
|
||||
cp = expand_string (p2);
|
||||
p = find_next_token (&cp, &l);
|
||||
if (p != 0)
|
||||
{
|
||||
@ -879,7 +869,7 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
/* Include ends the previous rule. */
|
||||
record_waiting_files ();
|
||||
|
||||
p = allocated_variable_expand (p2);
|
||||
p = allocated_expand_string (p2);
|
||||
|
||||
/* If no filenames, it's a no-op. */
|
||||
if (*p == '\0')
|
||||
@ -923,8 +913,8 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Handle the load operations. */
|
||||
if (word1eq ("load") || word1eq ("-load"))
|
||||
/* Handle the load operations. Allow targets named "load". */
|
||||
if ((word1eq ("load") || word1eq ("-load")) && !is_rule)
|
||||
{
|
||||
/* A 'load' line specifies a dynamic object to load. */
|
||||
struct nameseq *files;
|
||||
@ -933,7 +923,7 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
/* Load ends the previous rule. */
|
||||
record_waiting_files ();
|
||||
|
||||
p = allocated_variable_expand (p2);
|
||||
p = allocated_expand_string (p2);
|
||||
|
||||
/* If no filenames, it's a no-op. */
|
||||
if (*p == '\0')
|
||||
@ -984,6 +974,7 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
/* Otherwise add it to the list to be rebuilt. */
|
||||
deps = alloc_goaldep ();
|
||||
deps->next = read_files;
|
||||
deps->floc = ebuf->floc;
|
||||
read_files = deps;
|
||||
deps->file = f;
|
||||
}
|
||||
@ -1064,7 +1055,7 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
break;
|
||||
}
|
||||
|
||||
p2 = variable_expand_string (NULL, lb_next, wlen);
|
||||
p2 = expand_string_buf (NULL, lb_next, wlen);
|
||||
|
||||
while (1)
|
||||
{
|
||||
@ -1092,7 +1083,7 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
entirely consistent, since we do an unconditional
|
||||
expand below once we know we don't have a
|
||||
target-specific variable. */
|
||||
variable_expand_string (pend, lb_next, SIZE_MAX);
|
||||
expand_string_buf (pend, lb_next, SIZE_MAX);
|
||||
lb_next += strlen (lb_next);
|
||||
p2 = variable_buffer + p2_off;
|
||||
cmdleft = variable_buffer + cmd_off + 1;
|
||||
@ -1107,7 +1098,7 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
Note that the only separators of targets in this context are
|
||||
whitespace and a left paren. If others are possible, add them
|
||||
to the string in the call to strchr. */
|
||||
while (colonp && (colonp[1] == '/' || colonp[1] == '\\') &&
|
||||
while (colonp && ISDIRSEP (colonp[1]) &&
|
||||
isalpha ((unsigned char) colonp[-1]) &&
|
||||
(colonp == p2 + 1 || strchr (" \t(", colonp[-2]) != 0))
|
||||
colonp = find_char_unquote (colonp + 1, ':');
|
||||
@ -1128,7 +1119,7 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
|
||||
p2 += strlen (p2);
|
||||
*(p2++) = ' ';
|
||||
p2 = variable_expand_string (p2, lb_next, wlen);
|
||||
p2 = expand_string_buf (p2, lb_next, wlen);
|
||||
/* We don't need to worry about cmdleft here, because if it was
|
||||
found in the variable_buffer the entire buffer has already
|
||||
been expanded... we'll never get here. */
|
||||
@ -1136,20 +1127,29 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
|
||||
p2 = next_token (variable_buffer);
|
||||
|
||||
/* If the word we're looking at is EOL, see if there's _anything_
|
||||
on the line. If not, a variable expanded to nothing, so ignore
|
||||
it. If so, we can't parse this line so punt. */
|
||||
/* If we're at EOL we didn't find a separator so we don't know what
|
||||
kind of line this is. */
|
||||
if (wtype == w_eol)
|
||||
{
|
||||
/* Ignore an empty line. */
|
||||
if (*p2 == '\0')
|
||||
continue;
|
||||
|
||||
/* There's no need to be ivory-tower about this: check for
|
||||
one of the most common bugs found in makefiles... */
|
||||
/* Check for spaces instead of TAB. */
|
||||
if (cmd_prefix == '\t' && strneq (line, " ", 8))
|
||||
O (fatal, fstart, _("missing separator (did you mean TAB instead of 8 spaces?)"));
|
||||
else
|
||||
O (fatal, fstart, _("missing separator"));
|
||||
|
||||
/* Check for conditionals without whitespace afterward.
|
||||
We don't check ifdef/ifndef because there's no real way to miss
|
||||
whitespace there. */
|
||||
p2 = next_token (line);
|
||||
if (strneq (p2, "if", 2) &&
|
||||
((strneq (&p2[2], "neq", 3) && !STOP_SET (p2[5], MAP_BLANK))
|
||||
|| (strneq (&p2[2], "eq", 2) && !STOP_SET (p2[4], MAP_BLANK))))
|
||||
O (fatal, fstart, _("missing separator (ifeq/ifneq must be followed by whitespace)"));
|
||||
|
||||
/* No idea... */
|
||||
O (fatal, fstart, _("missing separator"));
|
||||
}
|
||||
|
||||
{
|
||||
@ -1231,7 +1231,7 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
if (*lb_next != '\0')
|
||||
{
|
||||
size_t l = p2 - variable_buffer;
|
||||
variable_expand_string (p2 + plen, lb_next, SIZE_MAX);
|
||||
expand_string_buf (p2 + plen, lb_next, SIZE_MAX);
|
||||
p2 = variable_buffer + l;
|
||||
|
||||
/* Look for a semicolon in the expanded line. */
|
||||
@ -1256,30 +1256,13 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
else
|
||||
break;
|
||||
}
|
||||
#ifdef _AMIGA
|
||||
/* Here, the situation is quite complicated. Let's have a look
|
||||
at a couple of targets:
|
||||
|
||||
install: dev:make
|
||||
|
||||
dev:make: make
|
||||
|
||||
dev:make:: xyz
|
||||
|
||||
The rule is that it's only a target, if there are TWO :'s
|
||||
OR a space around the :.
|
||||
*/
|
||||
if (p && !(ISSPACE (p[1]) || !p[1] || ISSPACE (p[-1])))
|
||||
p = 0;
|
||||
#endif
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
{
|
||||
int check_again;
|
||||
do {
|
||||
check_again = 0;
|
||||
/* For DOS-style paths, skip a "C:\..." or a "C:/..." */
|
||||
if (p != 0 && (p[1] == '\\' || p[1] == '/') &&
|
||||
isalpha ((unsigned char)p[-1]) &&
|
||||
if (p != 0 && ISDIRSEP (p[1]) && isalpha ((unsigned char)p[-1]) &&
|
||||
(p == p2 + 1 || strchr (" \t:(", p[-2]) != 0)) {
|
||||
p = strchr (p + 1, ':');
|
||||
check_again = 1;
|
||||
@ -1379,7 +1362,7 @@ do_undefine (char *name, enum variable_origin origin, struct ebuffer *ebuf)
|
||||
char *p, *var;
|
||||
|
||||
/* Expand the variable name and find the beginning (NAME) and end. */
|
||||
var = allocated_variable_expand (name);
|
||||
var = allocated_expand_string (name);
|
||||
name = next_token (var);
|
||||
if (*name == '\0')
|
||||
O (fatal, &ebuf->floc, _("empty variable name"));
|
||||
@ -1388,7 +1371,7 @@ do_undefine (char *name, enum variable_origin origin, struct ebuffer *ebuf)
|
||||
--p;
|
||||
p[1] = '\0';
|
||||
|
||||
undefine_variable_global (name, p - name + 1, origin);
|
||||
undefine_variable_global (&ebuf->floc, name, p - name + 1, origin);
|
||||
free (var);
|
||||
}
|
||||
|
||||
@ -1412,8 +1395,11 @@ do_define (char *name, enum variable_origin origin, struct ebuffer *ebuf)
|
||||
|
||||
p = parse_variable_definition (name, &var);
|
||||
if (p == NULL)
|
||||
/* No assignment token, so assume recursive. */
|
||||
var.flavor = f_recursive;
|
||||
{
|
||||
/* No assignment token, so assume recursive. */
|
||||
var.flavor = f_recursive;
|
||||
var.conditional = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (var.value[0] != '\0')
|
||||
@ -1424,7 +1410,7 @@ do_define (char *name, enum variable_origin origin, struct ebuffer *ebuf)
|
||||
}
|
||||
|
||||
/* Expand the variable name and find the beginning (NAME) and end. */
|
||||
n = allocated_variable_expand (name);
|
||||
n = allocated_expand_string (name);
|
||||
name = next_token (n);
|
||||
if (name[0] == '\0')
|
||||
O (fatal, &defstart, _("empty variable name"));
|
||||
@ -1497,8 +1483,8 @@ do_define (char *name, enum variable_origin origin, struct ebuffer *ebuf)
|
||||
else
|
||||
definition[idx - 1] = '\0';
|
||||
|
||||
v = do_variable_definition (&defstart, name,
|
||||
definition, origin, var.flavor, 0);
|
||||
v = do_variable_definition (&defstart, name, definition, origin, var.flavor,
|
||||
var.conditional, s_global);
|
||||
free (definition);
|
||||
free (n);
|
||||
return (v);
|
||||
@ -1657,7 +1643,7 @@ conditional_line (char *line, size_t len, const floc *flocp)
|
||||
|
||||
/* Expand the thing we're looking up, so we can use indirect and
|
||||
constructed variable names. */
|
||||
var = allocated_variable_expand (line);
|
||||
var = allocated_expand_string (line);
|
||||
|
||||
/* Make sure there's only one variable name to test. */
|
||||
p = end_of_token (var);
|
||||
@ -1686,19 +1672,10 @@ conditional_line (char *line, size_t len, const floc *flocp)
|
||||
|
||||
s1 = ++line;
|
||||
/* Find the end of the first string. */
|
||||
if (termin == ',')
|
||||
{
|
||||
int count = 0;
|
||||
for (; *line != '\0'; ++line)
|
||||
if (*line == '(')
|
||||
++count;
|
||||
else if (*line == ')')
|
||||
--count;
|
||||
else if (*line == ',' && count <= 0)
|
||||
break;
|
||||
}
|
||||
else
|
||||
while (*line != '\0' && *line != termin)
|
||||
while (*line != '\0' && *line != termin)
|
||||
if (*line == '$')
|
||||
line = skip_reference (line+1);
|
||||
else
|
||||
++line;
|
||||
|
||||
if (*line == '\0')
|
||||
@ -1706,7 +1683,7 @@ conditional_line (char *line, size_t len, const floc *flocp)
|
||||
|
||||
if (termin == ',')
|
||||
{
|
||||
/* Strip blanks after the first string. */
|
||||
/* Strip blanks before the comma. */
|
||||
char *p = line++;
|
||||
while (ISBLANK (p[-1]))
|
||||
--p;
|
||||
@ -1715,9 +1692,9 @@ conditional_line (char *line, size_t len, const floc *flocp)
|
||||
else
|
||||
*line++ = '\0';
|
||||
|
||||
s2 = variable_expand (s1);
|
||||
s2 = expand_string (s1);
|
||||
/* We must allocate a new copy of the expanded string because
|
||||
variable_expand re-uses the same buffer. */
|
||||
expand_string re-uses the same buffer. */
|
||||
l = strlen (s2);
|
||||
s1 = alloca (l + 1);
|
||||
memcpy (s1, s2, l + 1);
|
||||
@ -1764,7 +1741,7 @@ conditional_line (char *line, size_t len, const floc *flocp)
|
||||
if (*line != '\0')
|
||||
EXTRATEXT ();
|
||||
|
||||
s2 = variable_expand (s2);
|
||||
s2 = expand_string (s2);
|
||||
conditionals->ignoring[o] = (streq (s1, s2) == (cmdtype == c_ifneq));
|
||||
}
|
||||
|
||||
@ -1824,7 +1801,7 @@ record_target_var (struct nameseq *filenames, char *defn,
|
||||
|
||||
v->origin = origin;
|
||||
if (v->flavor == f_simple)
|
||||
v->value = allocated_variable_expand (v->value);
|
||||
v->value = allocated_expand_string (v->value);
|
||||
else
|
||||
v->value = xstrdup (v->value);
|
||||
}
|
||||
@ -1845,9 +1822,9 @@ record_target_var (struct nameseq *filenames, char *defn,
|
||||
initialize_file_variables (f, 1);
|
||||
|
||||
current_variable_set_list = f->variables;
|
||||
v = try_variable_definition (flocp, defn, origin, 1);
|
||||
v = try_variable_definition (flocp, defn, origin, s_target);
|
||||
if (!v)
|
||||
O (fatal, flocp, _("Malformed target-specific variable definition"));
|
||||
O (fatal, flocp, _("malformed target-specific variable definition"));
|
||||
current_variable_set_list = global;
|
||||
}
|
||||
|
||||
@ -1915,7 +1892,7 @@ check_specials (struct nameseq *files, int set_default)
|
||||
continue;
|
||||
}
|
||||
|
||||
#if !defined (__MSDOS__) && !defined (__EMX__)
|
||||
#if !MK_OS_DOS && !MK_OS_OS2
|
||||
if (!one_shell && streq (nm, ".ONESHELL"))
|
||||
{
|
||||
one_shell = 1;
|
||||
@ -2133,7 +2110,6 @@ record_files (struct nameseq *filenames, int are_also_makes,
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Walk through each target and create it in the database.
|
||||
We already set up the first target, above. */
|
||||
while (1)
|
||||
@ -2200,11 +2176,6 @@ record_files (struct nameseq *filenames, int are_also_makes,
|
||||
free_dep_chain (f->deps);
|
||||
f->deps = 0;
|
||||
}
|
||||
/* This file is explicitly mentioned as a target. There is no need
|
||||
to set is_explicit in the case of double colon below, because an
|
||||
implicit double colon rule only applies when the prerequisite
|
||||
exists. A prerequisite which exists is not intermediate anyway. */
|
||||
f->is_explicit = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2229,6 +2200,8 @@ record_files (struct nameseq *filenames, int are_also_makes,
|
||||
|
||||
f->cmds = cmds;
|
||||
}
|
||||
/* This file is explicitly mentioned as a target. */
|
||||
f->is_explicit = 1;
|
||||
|
||||
if (are_also_makes)
|
||||
{
|
||||
@ -2306,15 +2279,14 @@ record_files (struct nameseq *filenames, int are_also_makes,
|
||||
}
|
||||
|
||||
/* If there are also-makes, then populate a copy of the also-make list into
|
||||
each one. For the last file, we take our original also_make list instead
|
||||
wastefully copying it one more time and freeing it. */
|
||||
each one. Omit the file from its also-make list. */
|
||||
{
|
||||
struct dep *i;
|
||||
|
||||
for (i = also_make; i != NULL; i = i->next)
|
||||
{
|
||||
struct file *f = i->file;
|
||||
struct dep *cpy = i->next ? copy_dep_chain (also_make) : also_make;
|
||||
struct dep *dp;
|
||||
|
||||
if (f->also_make)
|
||||
{
|
||||
@ -2322,11 +2294,20 @@ record_files (struct nameseq *filenames, int are_also_makes,
|
||||
_("warning: overriding group membership for target '%s'"),
|
||||
f->name);
|
||||
free_dep_chain (f->also_make);
|
||||
f->also_make = NULL;
|
||||
}
|
||||
|
||||
f->also_make = cpy;
|
||||
for (dp = also_make; dp != NULL; dp = dp->next)
|
||||
if (dp->file != f)
|
||||
{
|
||||
struct dep *cpy = copy_dep (dp);
|
||||
cpy->next = f->also_make;
|
||||
f->also_make = cpy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free_dep_chain (also_make);
|
||||
}
|
||||
}
|
||||
|
||||
/* Search STRING for an unquoted STOPMAP.
|
||||
@ -2358,35 +2339,7 @@ find_map_unquote (char *string, int stopmap)
|
||||
/* If we stopped due to a variable reference, skip over its contents. */
|
||||
if (*p == '$')
|
||||
{
|
||||
char openparen = p[1];
|
||||
|
||||
/* Check if '$' is the last character in the string. */
|
||||
if (openparen == '\0')
|
||||
break;
|
||||
|
||||
p += 2;
|
||||
|
||||
/* Skip the contents of a non-quoted, multi-char variable ref. */
|
||||
if (openparen == '(' || openparen == '{')
|
||||
{
|
||||
unsigned int pcount = 1;
|
||||
char closeparen = (openparen == '(' ? ')' : '}');
|
||||
|
||||
while (*p)
|
||||
{
|
||||
if (*p == openparen)
|
||||
++pcount;
|
||||
else if (*p == closeparen)
|
||||
if (--pcount == 0)
|
||||
{
|
||||
++p;
|
||||
break;
|
||||
}
|
||||
++p;
|
||||
}
|
||||
}
|
||||
|
||||
/* Skipped the variable reference: look for STOPCHARS again. */
|
||||
p = skip_reference (p+1);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -2693,7 +2646,7 @@ readline (struct ebuffer *ebuf)
|
||||
/* We got a newline, so add one to the count of lines. */
|
||||
++nlines;
|
||||
|
||||
#if !defined(WINDOWS32) && !defined(__MSDOS__) && !defined(__EMX__)
|
||||
#if !MK_OS_W32 && !MK_OS_DOS && !MK_OS_OS2
|
||||
/* Check to see if the line was really ended with CRLF; if so ignore
|
||||
the CR. */
|
||||
if ((p - start) > 1 && p[-2] == '\r')
|
||||
@ -2747,7 +2700,8 @@ readline (struct ebuffer *ebuf)
|
||||
}
|
||||
|
||||
/* Parse the next "makefile word" from the input buffer, and return info
|
||||
about it.
|
||||
about it. This function won't be called in any context where we might need
|
||||
to parse a variable assignment so we don't need to check that.
|
||||
|
||||
A "makefile word" is one of:
|
||||
|
||||
@ -2760,11 +2714,10 @@ readline (struct ebuffer *ebuf)
|
||||
w_ampcolon An ampersand-colon (&:) token
|
||||
w_ampdcolon An ampersand-double-colon (&::) token
|
||||
w_semicolon A semicolon
|
||||
w_varassign A variable assignment operator (=, :=, ::=, +=, ?=, or !=)
|
||||
|
||||
Note that this function is only used when reading certain parts of the
|
||||
makefile. Don't use it where special rules hold sway (RHS of a variable,
|
||||
in a command list, etc.) */
|
||||
in a recipe, etc.) */
|
||||
|
||||
static enum make_word_type
|
||||
get_next_mword (char *buffer, char **startp, size_t *length)
|
||||
@ -2791,29 +2744,13 @@ get_next_mword (char *buffer, char **startp, size_t *length)
|
||||
wtype = w_semicolon;
|
||||
goto done;
|
||||
|
||||
case '=':
|
||||
wtype = w_varassign;
|
||||
goto done;
|
||||
|
||||
case ':':
|
||||
if (*p == '=')
|
||||
wtype = w_colon;
|
||||
if (*p == ':')
|
||||
{
|
||||
++p;
|
||||
wtype = w_varassign; /* := */
|
||||
wtype = w_dcolon;
|
||||
}
|
||||
else if (*p == ':')
|
||||
{
|
||||
++p;
|
||||
if (p[1] == '=')
|
||||
{
|
||||
++p;
|
||||
wtype = w_varassign; /* ::= */
|
||||
}
|
||||
else
|
||||
wtype = w_dcolon;
|
||||
}
|
||||
else
|
||||
wtype = w_colon;
|
||||
goto done;
|
||||
|
||||
case '&':
|
||||
@ -2831,43 +2768,26 @@ get_next_mword (char *buffer, char **startp, size_t *length)
|
||||
}
|
||||
break;
|
||||
|
||||
case '+':
|
||||
case '?':
|
||||
case '!':
|
||||
if (*p == '=')
|
||||
{
|
||||
++p;
|
||||
wtype = w_varassign; /* += or ?= or != */
|
||||
goto done;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* This is some non-operator word. A word consists of the longest
|
||||
string of characters that doesn't contain whitespace, one of [:=#],
|
||||
or [?+!]=, or &:. */
|
||||
/* This is some non-operator word. A word consists of the longest string of
|
||||
characters that doesn't contain whitespace, one of [:#], or &:. */
|
||||
|
||||
/* We start out assuming a static word; if we see a variable we'll
|
||||
adjust our assumptions then. */
|
||||
wtype = w_static;
|
||||
|
||||
/* We already found the first value of "c", above. */
|
||||
while (1)
|
||||
{
|
||||
char closeparen;
|
||||
int count;
|
||||
|
||||
/* Each time through the loop, "c" has the current character
|
||||
and "p" points to the next character. */
|
||||
if (END_OF_TOKEN (c))
|
||||
goto done_word;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '=':
|
||||
goto done_word;
|
||||
|
||||
case ':':
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
/* A word CAN include a colon in its drive spec. The drive
|
||||
@ -2886,34 +2806,9 @@ get_next_mword (char *buffer, char **startp, size_t *length)
|
||||
if (c == '\0')
|
||||
goto done_word;
|
||||
|
||||
/* This is a variable reference, so note that it's expandable.
|
||||
Then read it to the matching close paren. */
|
||||
/* This is a variable reference: note that then skip it. */
|
||||
wtype = w_variable;
|
||||
|
||||
if (c == '(')
|
||||
closeparen = ')';
|
||||
else if (c == '{')
|
||||
closeparen = '}';
|
||||
else
|
||||
/* This is a single-letter variable reference. */
|
||||
break;
|
||||
|
||||
for (count=0; *p != '\0'; ++p)
|
||||
{
|
||||
if (*p == c)
|
||||
++count;
|
||||
else if (*p == closeparen && --count < 0)
|
||||
{
|
||||
++p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case '?':
|
||||
case '+':
|
||||
if (*p == '=')
|
||||
goto done_word;
|
||||
p = skip_reference (p-1);
|
||||
break;
|
||||
|
||||
case '\\':
|
||||
@ -2947,6 +2842,7 @@ get_next_mword (char *buffer, char **startp, size_t *length)
|
||||
*startp = beg;
|
||||
if (length)
|
||||
*length = p - beg;
|
||||
|
||||
return wtype;
|
||||
}
|
||||
|
||||
@ -2967,12 +2863,12 @@ construct_include_path (const char **arg_dirs)
|
||||
int disable = 0;
|
||||
|
||||
/* Compute the number of pointers we need in the table. */
|
||||
idx = sizeof (default_include_directories) / sizeof (const char *);
|
||||
idx = ARRAYLEN (default_include_directories);
|
||||
if (arg_dirs)
|
||||
for (cpp = arg_dirs; *cpp != 0; ++cpp)
|
||||
++idx;
|
||||
|
||||
#ifdef __MSDOS__
|
||||
#if MK_OS_DOS
|
||||
/* Add one for $DJDIR. */
|
||||
++idx;
|
||||
#endif
|
||||
@ -3026,7 +2922,8 @@ construct_include_path (const char **arg_dirs)
|
||||
/* Now add the standard default dirs at the end. */
|
||||
if (!disable)
|
||||
{
|
||||
#ifdef __MSDOS__
|
||||
const char *const *ccpp;
|
||||
#if MK_OS_DOS
|
||||
/* The environment variable $DJDIR holds the root of the DJGPP directory
|
||||
tree; add ${DJDIR}/include. */
|
||||
struct variable *djdir = lookup_variable ("DJDIR", 5);
|
||||
@ -3043,20 +2940,20 @@ construct_include_path (const char **arg_dirs)
|
||||
max_incl_len = len;
|
||||
}
|
||||
#endif
|
||||
for (cpp = default_include_directories; *cpp != 0; ++cpp)
|
||||
for (ccpp = default_include_directories; *ccpp != 0; ++ccpp)
|
||||
{
|
||||
int e;
|
||||
|
||||
EINTRLOOP (e, stat (*cpp, &stbuf));
|
||||
EINTRLOOP (e, stat (*ccpp, &stbuf));
|
||||
if (e == 0 && S_ISDIR (stbuf.st_mode))
|
||||
{
|
||||
size_t len = strlen (*cpp);
|
||||
size_t len = strlen (*ccpp);
|
||||
/* If dir name is written with trailing slashes, discard them. */
|
||||
while (len > 1 && (*cpp)[len - 1] == '/')
|
||||
while (len > 1 && (*ccpp)[len - 1] == '/')
|
||||
--len;
|
||||
if (len > max_incl_len)
|
||||
max_incl_len = len;
|
||||
dirs[idx++] = strcache_add_len (*cpp, len);
|
||||
dirs[idx++] = strcache_add_len (*ccpp, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3065,12 +2962,13 @@ construct_include_path (const char **arg_dirs)
|
||||
|
||||
/* Now add each dir to the .INCLUDE_DIRS variable. */
|
||||
|
||||
do_variable_definition (NILF, ".INCLUDE_DIRS", "", o_default, f_simple, 0);
|
||||
do_variable_definition (NILF, ".INCLUDE_DIRS", "", o_default, f_simple, 0,
|
||||
s_global);
|
||||
for (cpp = dirs; *cpp != 0; ++cpp)
|
||||
do_variable_definition (NILF, ".INCLUDE_DIRS", *cpp,
|
||||
o_default, f_append, 0);
|
||||
do_variable_definition (NILF, ".INCLUDE_DIRS", *cpp, o_default, f_append,
|
||||
0, s_global);
|
||||
|
||||
free (include_directories);
|
||||
free ((void *) include_directories);
|
||||
include_directories = dirs;
|
||||
}
|
||||
|
||||
@ -3080,20 +2978,20 @@ construct_include_path (const char **arg_dirs)
|
||||
char *
|
||||
tilde_expand (const char *name)
|
||||
{
|
||||
#if !defined(VMS)
|
||||
#if !MK_OS_VMS
|
||||
if (name[1] == '/' || name[1] == '\0')
|
||||
{
|
||||
char *home_dir;
|
||||
int is_variable;
|
||||
|
||||
{
|
||||
/* Turn off --warn-undefined-variables while we expand HOME. */
|
||||
int save = warn_undefined_variables_flag;
|
||||
warn_undefined_variables_flag = 0;
|
||||
/* Turn off undefined variables warning while we expand HOME. */
|
||||
enum warning_action save = warn_get (wt_undefined_var);
|
||||
warn_set (wt_undefined_var, w_ignore);
|
||||
|
||||
home_dir = allocated_variable_expand ("$(HOME)");
|
||||
home_dir = allocated_expand_variable (STRING_SIZE_TUPLE ("HOME"));
|
||||
|
||||
warn_undefined_variables_flag = save;
|
||||
warn_set (wt_undefined_var, save);
|
||||
}
|
||||
|
||||
is_variable = home_dir[0] != '\0';
|
||||
@ -3102,7 +3000,7 @@ tilde_expand (const char *name)
|
||||
free (home_dir);
|
||||
home_dir = getenv ("HOME");
|
||||
}
|
||||
# if !defined(_AMIGA) && !defined(WINDOWS32)
|
||||
# if !MK_OS_W32
|
||||
if (home_dir == 0 || home_dir[0] == '\0')
|
||||
{
|
||||
char *logname = getlogin ();
|
||||
@ -3114,7 +3012,7 @@ tilde_expand (const char *name)
|
||||
home_dir = p->pw_dir;
|
||||
}
|
||||
}
|
||||
# endif /* !AMIGA && !WINDOWS32 */
|
||||
# endif /* !MK_OS_W32 */
|
||||
if (home_dir != 0)
|
||||
{
|
||||
char *new = xstrdup (concat (2, home_dir, name + 1));
|
||||
@ -3123,7 +3021,7 @@ tilde_expand (const char *name)
|
||||
return new;
|
||||
}
|
||||
}
|
||||
# if !defined(_AMIGA) && !defined(WINDOWS32)
|
||||
# if !MK_OS_W32
|
||||
else
|
||||
{
|
||||
struct passwd *pwent;
|
||||
@ -3142,8 +3040,8 @@ tilde_expand (const char *name)
|
||||
else if (userend != 0)
|
||||
*userend = '/';
|
||||
}
|
||||
# endif /* !AMIGA && !WINDOWS32 */
|
||||
#endif /* !VMS */
|
||||
# endif /* !MK_OS_W32 */
|
||||
#endif /* !MK_OS_VMS */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -3254,22 +3152,17 @@ parse_file_seq (char **stringp, size_t size, int stopmap,
|
||||
s = p;
|
||||
p = find_map_unquote (p, findmap);
|
||||
|
||||
#ifdef VMS
|
||||
#if MK_OS_VMS
|
||||
/* convert comma separated list to space separated */
|
||||
if (p && *p == ',')
|
||||
*p =' ';
|
||||
#endif
|
||||
#ifdef _AMIGA
|
||||
/* If we stopped due to a device name, skip it. */
|
||||
if (p && p != s+1 && p[0] == ':')
|
||||
p = find_map_unquote (p+1, findmap);
|
||||
#endif
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
/* If we stopped due to a drive specifier, skip it.
|
||||
Tokens separated by spaces are treated as separate paths since make
|
||||
doesn't allow path names with spaces. */
|
||||
if (p && p == s+1 && p[0] == ':'
|
||||
&& isalpha ((unsigned char)s[0]) && STOP_SET (p[1], MAP_DIRSEP))
|
||||
&& isalpha ((unsigned char)s[0]) && ISDIRSEP (p[1]))
|
||||
p = find_map_unquote (p+1, findmap);
|
||||
#endif
|
||||
|
||||
@ -3286,22 +3179,24 @@ parse_file_seq (char **stringp, size_t size, int stopmap,
|
||||
|
||||
/* Strip leading "this directory" references. */
|
||||
if (NONE_SET (flags, PARSEFS_NOSTRIP))
|
||||
#ifdef VMS
|
||||
/* Skip leading '[]'s. should only be one set or bug somewhere else */
|
||||
if (p - s > 2 && s[0] == '[' && s[1] == ']')
|
||||
{
|
||||
#if MK_OS_VMS
|
||||
/* Skip leading '[]'s. should only be one set or bug somewhere else */
|
||||
if (p - s > 2 && s[0] == '[' && s[1] == ']')
|
||||
s += 2;
|
||||
/* Skip leading '<>'s. should only be one set or bug somewhere else */
|
||||
if (p - s > 2 && s[0] == '<' && s[1] == '>')
|
||||
/* Skip leading '<>'s. should only be one set or bug somewhere else */
|
||||
if (p - s > 2 && s[0] == '<' && s[1] == '>')
|
||||
s += 2;
|
||||
#endif
|
||||
/* Skip leading './'s. */
|
||||
while (p - s > 2 && s[0] == '.' && s[1] == '/')
|
||||
{
|
||||
/* Skip "./" and all following slashes. */
|
||||
s += 2;
|
||||
while (*s == '/')
|
||||
++s;
|
||||
}
|
||||
/* Skip leading './'s. */
|
||||
while (p - s > 2 && s[0] == '.' && s[1] == '/')
|
||||
{
|
||||
/* Skip "./" and all following slashes. */
|
||||
s += 2;
|
||||
while (*s == '/')
|
||||
++s;
|
||||
}
|
||||
}
|
||||
|
||||
/* Extract the filename just found, and skip it.
|
||||
Set NAME to the string, and NLEN to its length. */
|
||||
@ -3309,20 +3204,14 @@ parse_file_seq (char **stringp, size_t size, int stopmap,
|
||||
if (s == p)
|
||||
{
|
||||
/* The name was stripped to empty ("./"). */
|
||||
#if defined(_AMIGA)
|
||||
/* PDS-- This cannot be right!! */
|
||||
tp[0] = '\0';
|
||||
nlen = 0;
|
||||
#else
|
||||
tp[0] = '.';
|
||||
tp[1] = '/';
|
||||
tp[2] = '\0';
|
||||
nlen = 2;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef VMS
|
||||
#if MK_OS_VMS
|
||||
/* VMS filenames can have a ':' in them but they have to be '\'ed but we need
|
||||
* to remove this '\' before we can use the filename.
|
||||
* xstrdup called because S may be read-only string constant.
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user