mirror of
https://github.com/mirror/make.git
synced 2026-08-20 00:43:29 +08:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ed493f6c91 | ||
|
|
7c3260bbdd | ||
|
|
38b19976f5 | ||
|
|
1dd52ab472 | ||
|
|
92789aa2e7 | ||
|
|
4e18732a1d | ||
|
|
11f9da227e | ||
|
|
b92340a1ea | ||
|
|
8064aee4f9 | ||
|
|
cf78e65fda | ||
|
|
04f0d8427f | ||
|
|
f8401ad28b |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -61,7 +61,7 @@ GccDebug/
|
||||
GccRel/
|
||||
|
||||
# Test artifacts
|
||||
makeerror-*.tar.gz
|
||||
makeerror-*
|
||||
test-suite.log
|
||||
|
||||
# Distribution artifacts
|
||||
|
||||
14
Makefile.am
14
Makefile.am
@@ -166,13 +166,18 @@ GMK_OUTDIR = ..
|
||||
|
||||
testlog = test-suite.log
|
||||
testresult = tests/.test-result
|
||||
errorfile = makeerror-$(host_triplet).tar.gz
|
||||
errorpre = makeerror-$(PACKAGE_VERSION)-$(host_triplet)
|
||||
|
||||
testfiles = $(testlog) $(testresult) $(errorfile)
|
||||
MOSTLYCLEANFILES = $(testfiles)
|
||||
|
||||
errordetails = config.status config.log src/config.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
|
||||
@rm -f $(testfiles)
|
||||
@if test -f '$(top_srcdir)/tests/run_make_tests'; then \
|
||||
@@ -189,8 +194,11 @@ check-regression: tests/config-flags.pm
|
||||
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 $$? >.test-result) 2>&1 | tee $(testlog); \
|
||||
er=$$(cat $(testresult)); if test "$$er" -ne 0; then \
|
||||
$(AMTAR) chf - $(errordetails) | eval GZIP= gzip $(GZIP_ENV) -c >$(errorfile); \
|
||||
echo '*** Testing failed! Details saved in: $(errorfile)'; \
|
||||
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; \
|
||||
|
||||
4
NEWS
4
NEWS
@@ -1,6 +1,6 @@
|
||||
GNU Make NEWS -*-indented-text-*-
|
||||
History of user-visible changes.
|
||||
24 October 2022
|
||||
31 October 2022
|
||||
|
||||
See the end of this file for copyrights and conditions.
|
||||
|
||||
@@ -9,7 +9,7 @@ which is contained in this distribution as the file doc/make.texi.
|
||||
See the README file and the GNU Make manual for instructions for
|
||||
reporting bugs.
|
||||
|
||||
Version 4.3.92 (24 Oct 2022)
|
||||
Version 4.4 (31 Oct 2022)
|
||||
|
||||
A complete list of bugs fixed in this version is available here:
|
||||
|
||||
|
||||
179
README.git
179
README.git
@@ -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:
|
||||
|
||||
@@ -178,6 +178,9 @@ 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
|
||||
---------------------
|
||||
@@ -203,7 +206,7 @@ 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)
|
||||
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.
|
||||
@@ -250,34 +253,118 @@ consistent (that's why we don't finalize the Git tag, etc. until the end).
|
||||
"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
|
||||
|
||||
If you don't want to create a new repository then run "git clean -fdx".
|
||||
Then:
|
||||
|
||||
./bootstrap.sh
|
||||
./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 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:
|
||||
|
||||
* 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.
|
||||
|
||||
* 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:
|
||||
|
||||
* Update configure.ac and add a ".90" to the release number.
|
||||
@@ -285,66 +372,6 @@ 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, platform-testers@gnu.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
|
||||
--------------------------
|
||||
|
||||
@@ -360,6 +387,6 @@ For a debugging version:
|
||||
|
||||
./bootstrap && ./configure CFLAGS=-g && make check
|
||||
|
||||
For a release version
|
||||
For an optimized version
|
||||
|
||||
./bootstrap && ./configure && make check
|
||||
|
||||
43
build.sh
43
build.sh
@@ -20,6 +20,11 @@
|
||||
# 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"
|
||||
|
||||
@@ -55,6 +60,7 @@ get_mk_var ()
|
||||
# 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 +71,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 +144,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.
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
AC_INIT([GNU Make],[4.3.92],[bug-make@gnu.org])
|
||||
AC_INIT([GNU Make],[4.4],[bug-make@gnu.org])
|
||||
|
||||
AC_PREREQ([2.69])
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
@setfilename make.info
|
||||
|
||||
@include version.texi
|
||||
@set EDITION 0.75
|
||||
@set EDITION 0.76
|
||||
|
||||
@settitle GNU @code{make}
|
||||
@setchapternewpage odd
|
||||
|
||||
@@ -259,7 +259,8 @@ 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 =
|
||||
|
||||
@@ -277,6 +278,7 @@ checkcfg.no-sync: CFGCHECK_CONFIGFLAGS = CPPFLAGS=-DNO_OUTPUT_SYNC
|
||||
checkcfg.no-archives: CFGCHECK_CONFIGFLAGS = CPPFLAGS=-DNO_ARCHIVES
|
||||
|
||||
CONFIG_CHECKS := \
|
||||
checkcfg.strict-c90 \
|
||||
checkcfg.no-jobserver \
|
||||
checkcfg.no-load \
|
||||
checkcfg.no-guile \
|
||||
@@ -295,7 +297,7 @@ 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
|
||||
|
||||
|
||||
5
src/ar.c
5
src/ar.c
@@ -36,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;
|
||||
@@ -61,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;
|
||||
|
||||
@@ -601,7 +601,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)
|
||||
|
||||
@@ -2811,7 +2811,8 @@ 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
|
||||
|
||||
37
src/job.c
37
src/job.c
@@ -205,11 +205,10 @@ int getgid ();
|
||||
#endif
|
||||
|
||||
#if HAVE_SYS_LOADAVG_H
|
||||
# include <sys/time.h>
|
||||
# include <sys/loadavg.h>
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_DECL_GETLOADAVG
|
||||
#if HAVE_DECL_GETLOADAVG == 0
|
||||
int getloadavg (double loadavg[], int nelem);
|
||||
#endif
|
||||
|
||||
@@ -2272,7 +2271,7 @@ child_execute_job (struct childbase *child, int good_stdin, char **argv)
|
||||
const int fdin = good_stdin ? FD_STDIN : get_bad_stdin ();
|
||||
int fdout = FD_STDOUT;
|
||||
int fderr = FD_STDERR;
|
||||
pid_t pid;
|
||||
pid_t pid = -1;
|
||||
int r;
|
||||
#if defined(USE_POSIX_SPAWN)
|
||||
char *cmd;
|
||||
@@ -3365,30 +3364,44 @@ construct_command_argv_internal (char *line, char **restp, const char *shell,
|
||||
#endif /* WINDOWS32 */
|
||||
/* Create an argv list for the shell command line. */
|
||||
{
|
||||
int n = 0;
|
||||
int n = 1;
|
||||
char *nextp;
|
||||
|
||||
new_argv = xmalloc ((4 + sflags_len/2) * sizeof (char *));
|
||||
new_argv[n++] = xstrdup (shell);
|
||||
|
||||
nextp = new_argv[0] = xmalloc (shell_len + sflags_len + line_len + 3);
|
||||
nextp = mempcpy (nextp, shell, shell_len + 1);
|
||||
|
||||
/* Chop up the shellflags (if any) and assign them. */
|
||||
if (! shellflags)
|
||||
new_argv[n++] = xstrdup ("");
|
||||
{
|
||||
new_argv[n++] = nextp;
|
||||
*(nextp++) = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Parse shellflags using construct_command_argv_internal to
|
||||
handle quotes. */
|
||||
char **argv;
|
||||
char *f;
|
||||
f = alloca (sflags_len + 1); // +1 for null terminator.
|
||||
char *f = alloca (sflags_len + 1);
|
||||
memcpy (f, shellflags, sflags_len + 1);
|
||||
argv = construct_command_argv_internal (f, 0, 0, 0, 0, flags, 0);
|
||||
for (char **a = argv; a && *a; ++a)
|
||||
new_argv[n++] = *a;
|
||||
free (argv);
|
||||
if (argv)
|
||||
{
|
||||
char **a;
|
||||
for (a = argv; *a; ++a)
|
||||
{
|
||||
new_argv[n++] = nextp;
|
||||
nextp = stpcpy (nextp, *a) + 1;
|
||||
}
|
||||
free (argv[0]);
|
||||
free (argv);
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the command to invoke. */
|
||||
new_argv[n++] = line;
|
||||
new_argv[n++] = nextp;
|
||||
memcpy(nextp, line, line_len + 1);
|
||||
new_argv[n++] = NULL;
|
||||
}
|
||||
return new_argv;
|
||||
|
||||
@@ -668,6 +668,7 @@ get_tmpfd (char **name)
|
||||
{
|
||||
int fd = -1;
|
||||
char *tmpnm;
|
||||
mode_t mask;
|
||||
|
||||
/* If there's an os-specific way to get an anoymous temp file use it. */
|
||||
if (!name)
|
||||
@@ -677,6 +678,10 @@ get_tmpfd (char **name)
|
||||
return fd;
|
||||
}
|
||||
|
||||
/* 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)
|
||||
tmpnm = get_tmptemplate ();
|
||||
|
||||
@@ -704,6 +709,8 @@ get_tmpfd (char **name)
|
||||
free (tmpnm);
|
||||
}
|
||||
|
||||
umask (mask);
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
@@ -673,6 +673,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));
|
||||
@@ -843,12 +844,18 @@ os_anontmp ()
|
||||
int fd = -1;
|
||||
|
||||
#ifdef O_TMPFILE
|
||||
EINTRLOOP (fd, open (tdir, O_RDWR | O_TMPFILE | O_EXCL, 0600));
|
||||
if (fd >= 0)
|
||||
return fd;
|
||||
static unsigned int tmpfile_works = 1;
|
||||
|
||||
DB (DB_BASIC, (_("Cannot open '%s' with O_TMPFILE: %s.\n"),
|
||||
tdir, strerror (errno)));
|
||||
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
|
||||
|
||||
35
src/read.c
35
src/read.c
@@ -375,23 +375,26 @@ eval_makefile (const char *filename, unsigned short flags)
|
||||
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);
|
||||
{
|
||||
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);
|
||||
|
||||
54
tests/README
54
tests/README
@@ -23,10 +23,9 @@ distributed under the following terms:
|
||||
this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
The test suite requires Perl. These days, you should have at least Perl
|
||||
5.004 (available from ftp.gnu.org, and portable to many machines). It
|
||||
used to work with Perl 4.036 but official support for Perl 4.x was
|
||||
abandoned a long time ago, due to lack of testbeds, as well as interest.
|
||||
The test suite requires Perl. These days, you should have at least Perl 5.6.
|
||||
Newer versions may be required: I don't test regularly with older versions
|
||||
than what is installed by default on my development systems.
|
||||
|
||||
The test suite assumes that the first "diff" it finds on your PATH is
|
||||
GNU diff, but that only matters if a test fails.
|
||||
@@ -54,14 +53,6 @@ with your network or file server, not GNU make (I believe). This
|
||||
shouldn't happen very often anymore: I've done a lot of work on the
|
||||
tests to reduce the impacts of this situation.
|
||||
|
||||
The options/dash-l test will not really test anything if the copy of
|
||||
make you are using can't obtain the system load. Some systems require
|
||||
make to be setgid sys or kmem for this; if you don't want to install
|
||||
make just to test it, make it setgid to kmem or whatever group /dev/kmem
|
||||
is (i.e., "chgrp kmem make;chmod g+s make" as root). In any case, the
|
||||
options/dash-l test should no longer *fail* because make can't read
|
||||
/dev/kmem.
|
||||
|
||||
A directory named "work" will be created when the tests are run which
|
||||
will contain any makefiles and "diff" files of tests that fail so that
|
||||
you may look at them afterward to see the output of make and the
|
||||
@@ -74,28 +65,35 @@ other possible options for the test suite.
|
||||
Open Issues
|
||||
-----------
|
||||
|
||||
The test suite has a number of problems which should be addressed. One
|
||||
VERY serious one is that there is no real documentation. You just have
|
||||
to see the existing tests. Use the newer tests: many of the tests
|
||||
haven't been updated to use the latest/greatest test methods. See the
|
||||
ChangeLog in the tests directory for pointers.
|
||||
The test suite has a number of problems which should be addressed. One VERY
|
||||
serious one is that there is no real documentation. You just have to see the
|
||||
existing tests. Use the newer tests: many of the tests haven't been updated
|
||||
to use the latest/greatest test methods. See the ChangeLogs for pointers.
|
||||
|
||||
The second serious problem is that it's not parallelizable: it scribbles
|
||||
all over its installation directory and so can only test one make at a
|
||||
time. The third serious problem is that it's not relocatable: the only
|
||||
way it works when you build out of the source tree is to create
|
||||
symlinks, which doesn't work on every system and is bogus to boot. The
|
||||
fourth serious problem is that it doesn't create its own sandbox when
|
||||
running tests, so that if a test forgets to clean up after itself that
|
||||
can impact future tests.
|
||||
The second serious problem is that it's not relocatable: when you build out of
|
||||
the source tree it creates symlinks, which doesn't work on every system and is
|
||||
just bogus to boot.
|
||||
|
||||
The third serious problem is that it's not parallelizable: it scribbles all
|
||||
over its installation directory and so can only test one make at a time.
|
||||
|
||||
The fourth serious problem is that since the tests scribble all over the same
|
||||
directory (a) they can interfere with each other and (b) we cannot preserve
|
||||
the full environment for every test, if it involves creating temporary files
|
||||
etc. as they must be deleted before the next test.
|
||||
|
||||
To solve these the suite should create a separate directory for EVERY test,
|
||||
local to the build directory, and all temporary files should exist in that
|
||||
directory. The directory can be preserved on error, or removed if the test
|
||||
succeeds (unless --keep is given).
|
||||
|
||||
|
||||
Bugs
|
||||
----
|
||||
|
||||
Any complaints/suggestions/bugs/etc. for the test suite itself (as
|
||||
opposed to problems in make that the suite finds) should be handled the
|
||||
same way as normal GNU make bugs/problems (see the README for GNU make).
|
||||
Any complaints/suggestions/bugs/etc. for the test suite itself should be
|
||||
handled the same way as normal GNU make bugs/problems (see the README for GNU
|
||||
make).
|
||||
|
||||
|
||||
Paul D. Smith
|
||||
|
||||
@@ -110,78 +110,6 @@ $ERR_nonexe_file = undef;
|
||||
$ERR_exe_dir = undef;
|
||||
$ERR_command_not_found = undef;
|
||||
|
||||
{
|
||||
use locale;
|
||||
|
||||
my $loc = undef;
|
||||
if ($has_POSIX) {
|
||||
POSIX->import(qw(locale_h));
|
||||
# Windows has POSIX locale, but only LC_ALL not LC_MESSAGES
|
||||
$loc = POSIX::setlocale(&POSIX::LC_ALL);
|
||||
POSIX::setlocale(&POSIX::LC_ALL, 'C');
|
||||
|
||||
# See set_defaults() as this doesn't work right on Windows :(
|
||||
$! = &POSIX::ERANGE;
|
||||
}
|
||||
|
||||
if (open(my $F, '<', 'file.none')) {
|
||||
print "Opened non-existent file! Skipping related tests.\n";
|
||||
} else {
|
||||
$ERR_no_such_file = "$!";
|
||||
}
|
||||
|
||||
unlink('file.out');
|
||||
touch('file.out');
|
||||
|
||||
chmod(0444, 'file.out');
|
||||
if (open(my $F, '>', 'file.out')) {
|
||||
print "Opened read-only file! Skipping related tests.\n";
|
||||
close($F);
|
||||
} else {
|
||||
$ERR_read_only_file = "$!";
|
||||
}
|
||||
|
||||
$_ = `./file.out 2>&1`;
|
||||
if ($? == 0) {
|
||||
print "Executed non-executable file! Skipping related tests.\n";
|
||||
} else {
|
||||
$ERR_nonexe_file = "$!";
|
||||
}
|
||||
|
||||
if ($^O =~ /cygwin/i) {
|
||||
# For some reason the execute here gives a different answer than make's
|
||||
print "Skipping directory execution on $^O\n";
|
||||
} else {
|
||||
$_ = `./. 2>&1`;
|
||||
if ($? == 0) {
|
||||
print "Executed directory! Skipping related tests.\n";
|
||||
} else {
|
||||
$ERR_exe_dir = "$!";
|
||||
}
|
||||
}
|
||||
|
||||
chmod(0000, 'file.out');
|
||||
if (open(my $F, '<', 'file.out')) {
|
||||
print "Opened unreadable file! Skipping related tests.\n";
|
||||
close($F);
|
||||
} else {
|
||||
$ERR_unreadable_file = "$!";
|
||||
}
|
||||
|
||||
unlink('file.out') or die "Failed to delete file.out: $!\n";
|
||||
|
||||
$_ = `/bin/sh -c 'bad-command 2>&1'`;
|
||||
if ($? == 0) {
|
||||
print "Invoked invalid file! Skipping related tests.\n";
|
||||
} else {
|
||||
chomp($_);
|
||||
s/bad-command/#CMDNAME#/g;
|
||||
$ERR_command_not_found = $_;
|
||||
}
|
||||
|
||||
$loc and POSIX::setlocale(&POSIX::LC_ALL, $loc);
|
||||
}
|
||||
|
||||
#$SIG{INT} = sub { print STDERR "Caught a signal!\n"; die @_; };
|
||||
|
||||
sub valid_option
|
||||
@@ -477,6 +405,81 @@ sub set_defaults
|
||||
} else {
|
||||
$scriptsuffix = '.bat';
|
||||
}
|
||||
|
||||
$ENV{LC_ALL} = $makeENV{LC_ALL};
|
||||
$ENV{LANG} = $makeENV{LANG};
|
||||
$ENV{LANGUAGE} = $makeENV{LANGUAGE};
|
||||
|
||||
use locale;
|
||||
|
||||
my $loc = undef;
|
||||
if ($has_POSIX) {
|
||||
POSIX->import(qw(locale_h));
|
||||
# Windows has POSIX locale, but only LC_ALL not LC_MESSAGES
|
||||
$loc = POSIX::setlocale(&POSIX::LC_ALL);
|
||||
POSIX::setlocale(&POSIX::LC_ALL, 'C');
|
||||
}
|
||||
|
||||
if (open(my $F, '<', 'file.none')) {
|
||||
print "Opened non-existent file! Skipping related tests.\n";
|
||||
} else {
|
||||
$ERR_no_such_file = "$!";
|
||||
}
|
||||
|
||||
unlink('file.out');
|
||||
touch('file.out');
|
||||
|
||||
chmod(0444, 'file.out');
|
||||
if (open(my $F, '>', 'file.out')) {
|
||||
print "Opened read-only file! Skipping related tests.\n";
|
||||
close($F);
|
||||
} else {
|
||||
$ERR_read_only_file = "$!";
|
||||
}
|
||||
|
||||
$_ = `./file.out 2>&1`;
|
||||
if ($? == 0) {
|
||||
print "Executed non-executable file! Skipping related tests.\n";
|
||||
} else {
|
||||
$ERR_nonexe_file = "$!";
|
||||
}
|
||||
|
||||
if ($^O =~ /cygwin/i) {
|
||||
# For some reason the execute here gives a different answer than make's
|
||||
print "Skipping directory execution on $^O\n";
|
||||
} else {
|
||||
$_ = `./. 2>&1`;
|
||||
if ($? == 0) {
|
||||
print "Executed directory! Skipping related tests.\n";
|
||||
} else {
|
||||
$ERR_exe_dir = "$!";
|
||||
}
|
||||
}
|
||||
|
||||
chmod(0000, 'file.out');
|
||||
if (open(my $F, '<', 'file.out')) {
|
||||
print "Opened unreadable file! Skipping related tests.\n";
|
||||
close($F);
|
||||
} else {
|
||||
$ERR_unreadable_file = "$!";
|
||||
}
|
||||
|
||||
unlink('file.out') or die "Failed to delete file.out: $!\n";
|
||||
|
||||
$_ = `/bin/sh -c 'bad-command 2>&1'`;
|
||||
if ($? == 0) {
|
||||
print "Invoked invalid file! Skipping related tests.\n";
|
||||
} else {
|
||||
chomp($_);
|
||||
s/bad-command/#CMDNAME#/g;
|
||||
$ERR_command_not_found = $_;
|
||||
}
|
||||
|
||||
$loc and POSIX::setlocale(&POSIX::LC_ALL, $loc);
|
||||
|
||||
$ENV{LC_ALL} = $origENV{LC_ALL};
|
||||
$ENV{LANG} = $origENV{LANG};
|
||||
$ENV{LANGUAGE} = $origENV{LANGUAGE};
|
||||
}
|
||||
|
||||
# This is no longer used: we import config-flags.pm instead
|
||||
|
||||
@@ -15,11 +15,19 @@ my $details = "The various shells that this test uses are the default"
|
||||
$port_type eq 'UNIX' or return -1;
|
||||
$^O =~ /cygwin/ and return -1;
|
||||
|
||||
my $usersh = $origENV{SHELL};
|
||||
my $answer = 'hello, world';
|
||||
my @shbangs = ('', '#!/bin/sh', "#!$perl_name");
|
||||
my @shells = ('', 'SHELL=/bin/sh');
|
||||
|
||||
my @shbangs = ('', '#!/bin/sh', "#!$usersh", "#!$perl_name");
|
||||
my @shells = ('', 'SHELL=/bin/sh', "SHELL=$usersh");
|
||||
# Try whatever shell the user has, as long as it's not a C shell.
|
||||
# The C shell is not usable with make, due to not correctly handling
|
||||
# file descriptors and possibly other issues.
|
||||
my $usersh = $origENV{SHELL};
|
||||
if ($usersh !~ /csh/) {
|
||||
push @shbangs, ("#!$usersh");
|
||||
push @shells, ("SHELL=$usersh");
|
||||
}
|
||||
|
||||
my $answer = 'hello, world';
|
||||
|
||||
# tests [0-11]
|
||||
# Have a makefile with various SHELL= exec a shell program with varios
|
||||
|
||||
@@ -75,7 +75,6 @@ rmfiles(qw(ONE.inc TWO.inc THREE.inc ONE TWO THREE 1.inc 2.inc));
|
||||
# function in an exported recursive variable. I added some code to check
|
||||
# for this situation and print a message if it occurred. This test used
|
||||
# to trigger this code when I added it but no longer does after the fix.
|
||||
# We have to increase the timeout from the default (5s) on this test.
|
||||
|
||||
run_make_test(q!
|
||||
export HI = $(shell $($@.CMD))
|
||||
@@ -86,7 +85,7 @@ second.CMD = #HELPER# sleep 4
|
||||
all: first second
|
||||
|
||||
first second: ; @#HELPER# out $@ sleep 1 out $@!,
|
||||
'-j2', "first\nsleep 1\nfirst\nsecond\nsleep 1\nsecond", 0, 7);
|
||||
'-j2', "first\nsleep 1\nfirst\nsecond\nsleep 1\nsecond", 0);
|
||||
|
||||
# Michael Matz <matz@suse.de> reported a bug where if make is running in
|
||||
# parallel without -k and two jobs die in a row, but not too close to each
|
||||
|
||||
@@ -196,7 +196,7 @@ all: foo.x foo-mt.x
|
||||
'', "one\ntwo");
|
||||
|
||||
# Test pattern rules building the same targets
|
||||
# See SV 54233. Rely on our standard test timeout to break the loop
|
||||
# See SV 54233.
|
||||
|
||||
touch('a.c');
|
||||
|
||||
|
||||
@@ -84,7 +84,9 @@ unlink($fout);
|
||||
use File::Spec;
|
||||
use File::Copy;
|
||||
|
||||
my $makecopy = File::Spec->catfile($TEMPDIR, "make");
|
||||
my $tmakedir = File::Spec->catfile($cwdpath, 'tmakedir');
|
||||
mkdir($tmakedir, 0770);
|
||||
my $makecopy = File::Spec->catfile($tmakedir, 'make');
|
||||
copy("$mkpath", $makecopy);
|
||||
# Set file mode bits, because perl copy won't.
|
||||
chmod 0700, $makecopy;
|
||||
@@ -106,6 +108,7 @@ force:
|
||||
|
||||
@make_command = @make_orig;
|
||||
unlink($makecopy);
|
||||
rmdir($tmakedir);
|
||||
}
|
||||
|
||||
close(STDIN);
|
||||
|
||||
@@ -9,8 +9,7 @@ variable2 := Hello
|
||||
y = $(subst 1,2,$(x))
|
||||
z = y
|
||||
a := $($($(z)))
|
||||
all:
|
||||
@echo $(a)
|
||||
all: ; @echo $(a)
|
||||
',
|
||||
'', "Hello\n");
|
||||
|
||||
@@ -21,15 +20,8 @@ all:
|
||||
|
||||
run_make_test('
|
||||
VARIABLE = $(eval VARIABLE := echo hi)$(VARIABLE)
|
||||
wololo:
|
||||
@$(VARIABLE)
|
||||
wololo: ; @$(VARIABLE)
|
||||
',
|
||||
'', "hi\n");
|
||||
|
||||
1;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -39,11 +39,12 @@ all:;@echo 'a=,$a,' 'b=,$b,' 'x=,$x,' 'y=,$y,' 'z=,$z,'
|
||||
# We still expand the list and body.
|
||||
run_make_test('
|
||||
null =
|
||||
v = $(let ,$(info blankvar),abc)
|
||||
x = $(let $(null),$(info side-effect),abc)
|
||||
y = $(let y,,$ydef)
|
||||
|
||||
all: ; @echo $x$y',
|
||||
'', "side-effect\nabcdef\n");
|
||||
all: ; @echo $v/$x/$y',
|
||||
'', "blankvar\nside-effect\nabc/abc/def\n");
|
||||
|
||||
# The example macro from the manual.
|
||||
run_make_test('
|
||||
|
||||
@@ -10,7 +10,7 @@ if ($port_type ne 'W32') {
|
||||
# Some shells (*shakes fist at Solaris*) cannot handle multiple flags in
|
||||
# separate arguments.
|
||||
my $t = `$sh_name -e -c true 2>/dev/null`;
|
||||
my $multi_ok = $? == 0;
|
||||
$multi_ok = $? == 0;
|
||||
}
|
||||
|
||||
# Simple
|
||||
|
||||
@@ -57,15 +57,11 @@ $pathsep = undef;
|
||||
$test_passed = 1;
|
||||
|
||||
# Timeout in seconds. If the test takes longer than this we'll fail it.
|
||||
$test_timeout = 5;
|
||||
$test_timeout = 10 if $^O eq 'VMS';
|
||||
# This is to prevent hung tests.
|
||||
$test_timeout = 60;
|
||||
|
||||
$diff_name = undef;
|
||||
|
||||
# Create a temporary directory that tests can use, outside the temp
|
||||
# directory that make is using.
|
||||
$TEMPDIR = File::Temp->newdir();
|
||||
|
||||
# Path to Perl
|
||||
$perl_name = $^X;
|
||||
if ($^O ne 'VMS') {
|
||||
@@ -201,7 +197,7 @@ sub toplevel
|
||||
'TZ', 'TMPDIR', 'HOME', 'USER', 'LOGNAME', 'PATH',
|
||||
'LD_LIBRARY_PATH',
|
||||
# *SAN things
|
||||
'ASAN_OPTIONS', 'UBSAN_OPTIONS',
|
||||
'ASAN_OPTIONS', 'UBSAN_OPTIONS', 'LSAN_OPTIONS',
|
||||
# Purify things
|
||||
'PURIFYOPTIONS',
|
||||
# Windows-specific things
|
||||
@@ -859,7 +855,8 @@ sub compare_output
|
||||
$slurp_mod =~ s,\r\n,\n,gs;
|
||||
|
||||
$answer_matched = ($slurp_mod eq $answer_mod);
|
||||
if ($^O eq 'VMS') {
|
||||
|
||||
if (!$answer_matched && $^O eq 'VMS') {
|
||||
|
||||
# VMS has extra blank lines in output sometimes.
|
||||
# Ticket #41760
|
||||
|
||||
Reference in New Issue
Block a user