Compare commits

...

39 Commits

Author SHA1 Message Date
Paul Smith
00e590fdef * NEWS: Update date and clarify -l change. 2019-09-16 08:25:34 -04:00
Paul Smith
4c64a5f986 * tests/run_make_tests.pl: Create $scriptsuffix for Windows/VMS.
* tests/scripts/features/targetvars: Add a suffix to scripts.
* tests/scripts/misc/general4: Ditto.
2019-09-16 08:25:33 -04:00
Paul Smith
414af96a50 Refresh the test suite framework implementation.
Go through both run_make_tests.pl and test_driver.pl and slightly
modernize the Perl and clean up indentation etc.  Fix a number of
warnings in the test scripts detected by running with -w.

* tests/test_driver.pl: Move make error string detection out of the
base test driver.
(run_all_tests): Ensure that we always look for tests in the cwd.
* tests/run_make_tests.pl: Use File::Spec for path manipulations.
Correctly use setlocale() when detecting error strings.
Get configuration from the config-flags.pm file not config.status.
* tests/scripts/features/archives: Use new $cwddir variable.
* tests/scripts/features/reinvoke: Add missing semicolon.
* tests/scripts/features/vpath2: Avoid non-existent variable.
* tests/scripts/functions/foreach: Escape variables.
* tests/scripts/misc/bs-nl: Remove non-existing \v escape sequence.
* tests/scripts/misc/general4: Use handy create_file().
* tests/scripts/options/dash-C: Use Cwd/$cwddir.
* tests/scripts/options/dash-I: Use subst_make_string() and #PWD#.
* tests/scripts/options/symlinks: Use File::Spec.
* tests/scripts/targets/DEFAULT: Use create_file and run_make_test.
* tests/scripts/variables/CURDIR: Use run_make_test.
* tests/scripts/variables/automatic: Remove extraneous "\".
* tests/scripts/vms/library: Remove extra "my" and extraneous "\".
2019-09-16 08:25:33 -04:00
Paul Smith
1b976397e5 * tests/config-flags.pm.in: Add USE_SYSTEM_GLOB.
* tests/config_flags_pm.com [VMS]: Ditto.
2019-09-16 08:25:33 -04:00
Paul Smith
9bc5491712 * README.git: [SV 56895] Provide more info about "maintainer mode".
* src/read.c (get_next_mword) [HAVE_DOS_PATHS]: Don't fall through to
parsing variable references if we find a drivespec in a word!
2019-09-16 08:25:33 -04:00
Paul Smith
57b13c8020 * tests/test_driver.pl: Remember error for "running" a directory.
* tests/scripts/features/errors: Check errors "running" a directory.
2019-09-16 08:25:33 -04:00
Paul Smith
02a4c2913a * src/job.c (child_execute_job): Use errno from find_in_given_path().
* tests/test_driver.pl: Determine non-executable error message.
* tests/scripts/features/errors: Use the local non-executable error.
2019-09-16 08:25:33 -04:00
Paul Smith
8acb89c8c4 * src/job.c (child_execute_job): Use newer gnulib findprog version. 2019-09-16 08:25:33 -04:00
Eli Zaretskii
271e572ba2 Revert "[SV 56449] (Windows) Use slow path if '%' appears in the command"
This reverts commit 38e96eadea.
Per discussion on Savannah, the modified behavior matches
the way % is handled in batch files, but not in cmd command
lines.  And since Make mostly tries to emulate the command
line, the new behavior is unexpected and backward-incompatible.
2019-09-10 19:09:39 +03:00
Paul Smith
bde990bfea Rework the creation of build.sh so it's not a template.
* build.sh: Rename from build.template.  Get the list of objects
from the Makefile.  Move configure-replaced variables ...
* build.cfg.in: to this new .in file.
* configure.ac: Remove special handling of build.sh.in and add
build.cfg as a generated file.
* Makefile.am (EXTRA_DIST): Remove build.sh.in and add build.sh
and build.cfg.in for build.sh.in.
* maintMakefile: Remove handling for build.template.  Treat
build.sh as a source file, not a generated file.
* .gitignore: Ignore generated build.cfg file.
2019-09-09 18:38:31 -04:00
Paul Smith
60e54608bd * gl/modules/make-glob: Move local glob configure.ac to here
* configure.ac: from here.
2019-09-08 15:17:06 -04:00
Paul Smith
60905a8afb [SV 56834] Support local PATH search with posix_spawnp
When using exec we install the child's environment before invoking
execlp(), so commands are found on the child's PATH.  posix_spawnp
searches on the parent's PATH, which we don't want.

Import gnulib's findprog-in module and use it to search the child's
PATH, then use posix_spawn() to run it.

Also, posix_spawn() does not fall back to trying sh on ENOEXEC, as
execlp() does, so implement that as well.

* bootstrap.conf: Add the findprog-in gnulib module
* src/job.c: Include findprog.h if we're using posix_spawn.
(start_job_command): Remove the handling of child->cmd_name,
(child_execute_job): and add it here.  Look up the command to be
run in the child's path and invoke it if found.  If it fails with
ENOEXEC then retry it as an argument to the default shell.
* tests/scripts/misc/general4: Test makefile PATH assignments.
* tests/scripts/features/targetvars: Ditto, for target variables.
2019-09-08 15:12:40 -04:00
Paul Smith
ebe1d37104 * doc/make.texi (Recipe Execution): Correct example to use $(<[DF]) 2019-09-07 20:12:44 -04:00
Paul Smith
c0cb9c8b3d * configure.ac: Check whether struct dirent has a d_type field
* src/dir.c (dir_contents_file_exists_p): Use the autoconf macro
HAVE_STRUCT_DIRENT_D_TYPE rather than relying on the GNU libc-
specific _DIRENT_HAVE_D_TYPE.
* lib/glob.c: Set HAVE_D_TYPE if HAVE_STRUCT_DIRENT_D_TYPE.
2019-09-07 20:12:44 -04:00
Paul Smith
34ee9adaed * src/config.h.W32.template [W32]: Add support for dirent.d_type
* src/w32/include/dirent.h: Add DT_* values for dirent.d_type
(struct dirent): Add d_type
* src/w32/compat/durent.c (readdir): Set dirent.d_type based on
Windows file attributes.
2019-09-07 20:12:44 -04:00
Paul Smith
64f5375fe0 * src/makeint.h: Add typedef for mode_t if !HAVE_UMASK 2019-09-07 20:12:44 -04:00
Paul Smith
da81e0815f * build.template: Rewrite to allow gnulib support. 2019-09-07 20:12:44 -04:00
Paul Smith
9be3c0e2b2 * doc/make.texi: Clarify that the jobserver pipe is "blocking" 2019-09-07 18:27:26 -04:00
Paul Smith
9da708772c Align child_execute_job among different ports
Create a struct childbase which is the basics of struct child needed
to invoke child_execute_job(), and can be cast back and forth to a
struct child.  Ensure all implementations of child_execute_job() take
the same arguments.

* src/job.h (CHILDBASE): Create a macro to hold the base parts.
(struct childbase): A structure containing CHILDBASE.
(struct child): Use CHILDBASE as the initial part of child.
[VMS]: Remove declaration of VMS version of child_execute_job.
* src/job.c (start_job_command): Use new child_execute_job() call.
(child_execute_job) [__EMX__]: Implement new calling signature.
(child_execute_job): Implement new calling signature.
* src/main.c (main) [__EMX__]: Use new child_execute_job() call.
* src/function.c (func_shell_base): Use new child_execute_job() call.
* src/vmsjobs.c (vmsHandleChildTerm): Accept struct childbase.
* src/vmsjobs.c (child_execute_job): Implement new calling signature.
Modify the return value to be pid_t, not a boolean, and return the
PID rather than setting it in the child.  This is OK because our only
caller immediately reset PID to -1 anyway if we return 0.
2019-09-07 18:27:26 -04:00
Paul Smith
0967624050 * doc/make.tex (Substitution Refs): Clarify patsubst relationship. 2019-09-07 18:27:26 -04:00
Paul Smith
ba950a796a * src/job.c (start_job_command) [VMS]: Correct VMS comment. 2019-09-07 18:27:26 -04:00
Paul Smith
005a251689 Show useful errors when posix_spawn() doesn't do so
The posix_spawn() function may not detect that the command to run is
invalid when it's invoked.  Instead, it will run then exit with
error code 127.  If that happens do our best to present the user
with a useful error message.

* src/job.h (struct child): Add cmd_name to hold the command we ran.
* src/job.c (start_job_command): On success, remember the cmd_name.
(reap_children): On exit 127, stat cmd_name and show a useful error.
(free_child): Free cmd_name.
2019-09-07 18:27:26 -04:00
Paul Smith
76b6e668a6 * README.git: Describe GCC and GNU make requirements
* maintMakefile: Put custom C flags into a separate variable
so they can be overridden more easily on the command line.
2019-09-07 18:27:26 -04:00
Paul Smith
5ff6ae6177 * tests/scripts/features/archives: Fix expected long ar name output. 2019-09-07 18:27:26 -04:00
Paul Smith
7c202b50fa * tetss/run_make_test.pl: Avoid 'sh -c' for Windows portability. 2019-09-07 18:27:26 -04:00
Paul Smith
f0182df865 Update to GNU make release candidate 4.2.91 2019-09-07 18:27:26 -04:00
Paul Smith
0a6c38eff8 * tests/scripts/functions/wildcard: Skip dangling symlink test.
The built-in glob implementation does not correctly handle dangling
symlinks.  This needs to be fixed by switching to the latest glob
implementation from gnulib but that's a big job: for now avoid the
test if we know it will fail.
2019-09-07 18:27:26 -04:00
Paul Smith
4b45e2828d * maintMakefile: Use check-local when testing build.sh.
Running 'make check' will rebuild 'make' so we're not testing the
build.sh-generated make binary.
2019-09-07 18:27:26 -04:00
Paul Smith
4f3a41c60a Don't reset stack size when using posix_spawn()
There's no way to run setrlimit() from posix_spawn() so we can't reset
the stack limit in children; thus, don't change it in the parent.

* src/makeint.h (SET_STACK_SIZE): Don't set this when HAVE_POSIX_SPAWN.
* src/job.c (child_execute_job): Remove useless comment.
2019-09-07 18:27:26 -04:00
Paul Smith
757a9d06e3 * configure.ac: Remove redundant getloadavg gnulib support 2019-09-07 18:27:26 -04:00
Paul Smith
31394f7f53 * src/dir.c (dir_setup_glob): Initialize unused gl_offs.
* tests/scripts/functions/wildcard: Add trailing slash tests.
Initial changes by Dmitry Goncharov <dgoncharov@users.sf.net>
2019-09-07 18:27:26 -04:00
Paul Eggert
b6884c73b7 Pacify Oracle Studio c99
* src/dep.h (DEP):
* src/function.c (struct function_table_entry):
Use unsigned int, not unsigned short.  Without this patch, c99
complains ‘warning: nonportable bit-field type’.
2019-09-02 11:11:26 -04:00
Paul Eggert
8bffc8d53c Port grouped_targets test to Solaris 10
* tests/scripts/features/grouped_targets: Use ‘printf ''’
instead of ‘echo -n’, as POSIX says the latter is not portable.
2019-09-02 11:11:26 -04:00
Paul Eggert
a9609084f4 Remove useless code in eval
* src/read.c (eval): Remove useless code.  Without this patch,
Oracle Studio 12.6 complains ‘"src/read.c", line 1405: warning:
loop not entered at top’.
2019-09-02 11:11:26 -04:00
Paul Eggert
8d820d57f6 Pacify Oracle Studio 12.6 in init_switches
* src/main.c (init_switches): Use a cast to convert char const *
to char *.  Without this patch, the compiler complains
‘"src/main.c", line 2643: warning: assignment type mismatch:
pointer to char "=" pointer to const char’.
2019-09-02 11:11:26 -04:00
Paul Eggert
73e11a5024 Pacify Oracle Studio 12.6
* src/arscan.c [VMS]: Use ‘#if !defined LBR$_HDRTRUNC’ instead
of ‘#ifndef LBR$_HDRTRUNC’ to pacify Oracle Studio 12.6, which
looks inside unused #if branches for preprocessor syntax errors.
Without this patch it complains ‘"src/arscan.c", line 43: warning:
tokens ignored at end of directive line’.
2019-09-02 11:11:26 -04:00
Paul Smith
85cdc9e9ae * NEWS: Fix incorrect notes. 2019-09-02 11:11:26 -04:00
Paul Smith
7e60ffe83e * src/read.c (parse_file_seq): [SV 52076] Don't reverse glob() results. 2019-09-02 11:11:26 -04:00
Eli Zaretskii
715c787dc6 Fix MS-Windows MinGW build
* src/w32/subproc/sub_proc.c (process_wait_for_multiple_objects):
Fix format specifier for GetLastError's value.

* src/job.c (reap_children): Define the 'remote_status_lose' label
only for Posix platforms, to avoid compiler warning.

* build_w32.bat (LNKOUT): New variable, using forward slashes.
Use forward slashes in calls to :Compile, so that linking with GNU
ld works.

* src/makeint.h [!HAVE_UMASK]: Prototype for 'umask'.
(UMASK, MODE_T): Don't define.

* src/misc.c (get_tmpfile): Don't call UMASK, call umask, to
avoid compilation warning on !HAVE_UMASK platforms.
* src/output.c (output_tmpfd): Likewise.

* src/misc.c (umask) [!HAVE_UMASK]: New no-op function.

* src/config.h.W32.template (__USE_MINGW_ANSI_STDIO)
[__MINGW32__]: Define to 1, to force Make use ANSI-compatible
stdio functions, which also support the non-standard 'Id' and 'Ix'
specifiers.
(HAVE_UMASK) [__MINGW32__]: Define to 1.

* src/arscan.c (ar_member_touch): Type-cast argument of strlen to
avoid compiler warnings.
2019-08-28 17:45:49 +03:00
51 changed files with 1703 additions and 1393 deletions

3
.gitignore vendored
View File

@@ -60,8 +60,7 @@ README
README.DOS README.DOS
README.OS2 README.OS2
README.W32 README.W32
build.sh build.cfg
build.sh.in
config.ami config.ami
config.h-vms config.h-vms
config.h.W32 config.h.W32

View File

@@ -97,7 +97,7 @@ test_FILES = tests/run_make_tests tests/run_make_tests.bat \
tests/mkshadow tests/jhelp.pl tests/guile.supp tests/README tests/mkshadow tests/jhelp.pl tests/guile.supp tests/README
# test/scripts are added via dist-hook below. # test/scripts are added via dist-hook below.
EXTRA_DIST = ChangeLog README build.sh.in $(man_MANS) \ EXTRA_DIST = ChangeLog README build.sh build.cfg.in $(man_MANS) \
README.customs README.OS2 \ README.customs README.OS2 \
README.Amiga SCOPTIONS src/config.ami \ README.Amiga SCOPTIONS src/config.ami \
README.DOS builddos.bat src/configh.dos \ README.DOS builddos.bat src/configh.dos \
@@ -107,11 +107,6 @@ EXTRA_DIST = ChangeLog README build.sh.in $(man_MANS) \
src/gmk-default.scm src/gmk-default.h \ src/gmk-default.scm src/gmk-default.h \
$(mk_FILES) $(m4_FILES) $(test_FILES) $(mk_FILES) $(m4_FILES) $(test_FILES)
# This is built during configure, but behind configure's back
DISTCLEANFILES = build.sh
# --------------- Generate the Guile default module content # --------------- Generate the Guile default module content
src/guile.$(OBJEXT): src/gmk-default.h src/guile.$(OBJEXT): src/gmk-default.h

21
NEWS
View File

@@ -1,6 +1,6 @@
GNU make NEWS -*-indented-text-*- GNU make NEWS -*-indented-text-*-
History of user-visible changes. History of user-visible changes.
26 August 2019 16 September 2019
See the end of this file for copyrights and conditions. 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 See the README file and the GNU make manual for instructions for
reporting bugs. reporting bugs.
Version 4.2.90 (26 Aug 2019) Version 4.2.91 (16 Sep 2019)
A complete list of bugs fixed in this version is available here: A complete list of bugs fixed in this version is available here:
@@ -37,10 +37,10 @@ http://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=108&set
* WARNING: Backward-incompatibility! * WARNING: Backward-incompatibility!
On Linux, and any other systems that provide a /proc/loadavg with similar On Linux, and any other systems that provide a /proc/loadavg with similar
syntax, the -l/--load-average option will use the contents of that file to syntax, the -l/--load-average option will consult that file to determine how
determine how many jobs are running at any given instant, and compare that many CPUs are busy at that moment and compare that value to the load value
value to the load value requested. This allows usage such as "-j -lN" for requested. This allows usage such as "-j -lN" for N-processor systems
N-processor systems without fear of overload. without fear of overload during initial startup.
Patch provided by Sven C. Dack <sven.c.dack@sky.com> Patch provided by Sven C. Dack <sven.c.dack@sky.com>
* WARNING: Backward-incompatibility! * WARNING: Backward-incompatibility!
@@ -59,11 +59,10 @@ http://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=108&set
* Makefiles can now specify the '-j' option in their MAKEFLAGS variable and * Makefiles can now specify the '-j' option in their MAKEFLAGS variable and
this will cause make to enable that parallelism mode. this will cause make to enable that parallelism mode.
* GNU make will now use pthread_spawn() on systems where it is available. * GNU make will now use posix_spawn() on systems where it is available.
It will select POSIX_SPAWN_USEVFORK where that is available. If you prefer If you prefer to use fork/exec even on systems where posix_spawn() is
to use fork/exec even on systems where pthread_spawn() is present, you can present, you can use the --disable-posix-spawn option to configure. Aron
use the --disable-pthread-spawn option to configure. Barath <baratharon@caesar.elte.hu> provided the basic implementation.
Aron Barath <baratharon@caesar.elte.hu> provided the basic implementation.
* Error messages printed when invoking non-existent commands have been cleaned * Error messages printed when invoking non-existent commands have been cleaned
up and made consistent. up and made consistent.

View File

@@ -85,6 +85,8 @@ need to install the following extra software:
* autopoint * autopoint
* pkg-config * pkg-config
* texinfo (for makeinfo) * texinfo (for makeinfo)
* GCC (Clang's GCC emulation is not sufficient)
* GNU make (POSIX make is not sufficient)
And any tools that those utilities require (GNU m4, Perl, etc.) And any tools that those utilities require (GNU m4, Perl, etc.)
@@ -93,10 +95,13 @@ a local installation of gnulib you can set GNULIB_SRCDIR to point to it.
Otherwise, ./bootstrap will obtain a clone for you. Otherwise, ./bootstrap will obtain a clone for you.
Unfortunately due to issues with gnulib's getloadavg, you must have automake Unfortunately due to issues with gnulib's getloadavg, you must have automake
1.16.1 or above. This version is not yet widely available in GNU/Linux 1.16.1 or above. This version may not yet be available through GNU/Linux
package managers. If you need to install from source be sure to set package managers. If you need to install from source be sure to set
ACLOCAL_PATH to point to the pkg-config location (e.g., /usr/share/aclocal). ACLOCAL_PATH to point to the pkg-config location (e.g., /usr/share/aclocal).
If you want to build from Git with a non-GCC compiler, add "MAKE_CFLAGS=" to
your make command line (or at least remove any flags your compiler does not
support).
When building from Git you must build in the source directory: "VPATH When building from Git you must build in the source directory: "VPATH
builds" from remote directories are not supported. Once you've created builds" from remote directories are not supported. Once you've created
@@ -114,9 +119,24 @@ That is, you can just run:
$ ./configure $ ./configure
$ make check $ make check
$ make install
to build and install 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
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.
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.
For example:
$ ./configure
$ make check MAKE_MAINTAINER_MODE= MAKE_CFLAGS=
$ make install
Building From Git for Windows Building From Git for Windows
@@ -155,9 +175,10 @@ Even better, you should run this:
Which will build both .gz and .bz2 package files, then unpack them into Which will build both .gz and .bz2 package files, then unpack them into
a temporary location, try to build them, and repack them, verifying that a temporary location, try to build them, and repack them, verifying that
everything works, you get the same results, _and_ no extraneous files everything works, you get the same results, _and_ no extraneous files
are left over after the "distclean" rule--whew!! Now, _that_ is why are left over after the "distclean" rule.
converting to Automake is worth the trouble! A big "huzzah!" to Tom
T. and the AutoToolers! This package can be unpacked and built to give a "normal" (non-maintainer
mode) result.
Steps to Release Steps to Release

View File

@@ -46,6 +46,7 @@ gnulib_files=doc/make-stds.texi
gnulib_modules="\ gnulib_modules="\
alloca alloca
fdl fdl
findprog-in
getloadavg getloadavg
host-cpu-c-abi host-cpu-c-abi
strerror strerror

38
build.cfg.in Normal file
View File

@@ -0,0 +1,38 @@
# Configuration for building GNU Make in the absence of any 'make' program.
# @configure_input@
# Copyright (C) 1993-2019 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/>.
# See Makefile.in for comments describing these variables.
top_srcdir='@top_srcdir@'
prefix='@prefix@'
exec_prefix=`eval echo @exec_prefix@`
CC='@CC@'
AR='@AR@'
CFLAGS='@CFLAGS@ @GUILE_CFLAGS@'
CPPFLAGS='@CPPFLAGS@'
DEFS='@DEFS@'
ARFLAGS='@ARFLAGS@'
LDFLAGS='@AM_LDFLAGS@ @LDFLAGS@'
ALLOCA='@ALLOCA@'
LOADLIBES='@LIBS@ @GUILE_LIBS@ @LIBINTL@'
REMOTE='@REMOTE@'
OBJEXT='@OBJEXT@'
EXEEXT='@EXEEXT@'

149
build.sh Executable file
View File

@@ -0,0 +1,149 @@
#!/bin/sh
# Shell script to build GNU Make in the absence of any 'make' program.
# Copyright (C) 1993-2019 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/>.
# Get configure-generated values
. ./build.cfg
: ${OUTDIR:=.}
OUTLIB="$OUTDIR/lib"
# Directory to find libraries in for '-lXXX'.
libdir=$exec_prefix/lib
# Directory to search by default for included makefiles.
includedir=$prefix/include
localedir=$prefix/share/locale
defines="-DLOCALEDIR=\"$localedir\" -DLIBDIR=\"$libdir\" -DINCLUDEDIR=\"$includedir\""
# Look up a make variable value.
# It can handle simple recursion where variables are separate words.
# 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")
for w in $v; do
case $w in
(\$[\(\{]*[\)\}]) w=${w#\$[\(\{]}; w=$(get_mk_var "$file" "${w%[\)\}]}") ;;
esac
val="${val:+$val }$w"
done
printf '%s\n' "$val"
}
# Compile source files. Object files are put into $objs.
compile ()
{
objs=
for ofile in "$@"; do
file="${ofile%.$OBJEXT}.c"
echo "compiling $file..."
of="$OUTDIR/$ofile"
mkdir -p "${of%/*}"
$CC $cflags $CPPFLAGS $CFLAGS -c -o "$of" "$top_srcdir/$file"
objs="${objs:+$objs }$of"
done
}
# Use config.status to convert a .in file. Output file is put into $out.
# $out will be empty if no conversion was needed.
convert ()
{
out=
base=$1
var="GENERATE_$(echo $base | tr 'a-z./+' A-Z__X)"
# Is this file disabled?
grep "${var}_FALSE\"]=\"\"" config.status >/dev/null && return
# Not disabled, so create it
in="$top_srcdir/lib/$(echo ${base%.*}.in.${base##*.} | tr / _)"
out="$OUTLIB/$base"
mkdir -p "${out%/*}"
# First perform the normal replacements, using config.status
sed -e 's|@GUARD_PREFIX@|GL|g' \
-e 's/@GNULIB_UNISTD_H_GETOPT@/0/g' \
"$in" > "${out}_"
./config.status --file "${out}__:${out}_"
int="${out}__"
# Then see if there any files we need to include. Unfortunately there's no
# algorithmic conversion so we just have to hard-code it.
incls=$(sed -n 's/.*definitions* of \(_[^ $]*\).*/\1/p' "$in")
for inc in $incls; do
case $inc in
(_GL_FUNCDECL_RPL) fn=$(get_mk_var lib/Makefile CXXDEFS_H) ;;
(_GL_ARG_NONNULL) fn=$(get_mk_var lib/Makefile ARG_NONNULL_H) ;;
(_GL_WARN_ON_USE) fn=$(get_mk_var lib/Makefile WARN_ON_USE_H) ;;
(_Noreturn) fn=$(get_mk_var lib/Makefile _NORETURN_H) ;;
(*) echo "Unknown file replacement: $inc"; exit 1 ;;
esac
fn="$top_srcdir/lib/${fn##*/}"
[ -f "$fn" ] || { echo "Missing file: $fn"; exit 1; }
sed "/definitions* of $inc/r $fn" "$int" > "${int}_"
int=${int}_
done
# Done!
mv "$int" "$out"
}
# Get source files provided from gnulib and convert to object files
LIBOBJS=
for lo in $( (get_mk_var lib/Makefile libgnu_a_OBJECTS; get_mk_var lib/Makefile libgnu_a_LIBADD) | sed "s=\$[\(\{]OBJEXT[\)\}]=$OBJEXT=g"); do
LIBOBJS="${LIBOBJS:+$LIBOBJS }lib/$lo"
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
# Generate gnulib header files that would normally be created by make
for b in $(get_mk_var lib/Makefile BUILT_SOURCES); do
convert $b
done
# Build the gnulib library
cflags="$DEFS -I$OUTLIB -Ilib -I$top_srcdir/lib -I$OUTDIR/src -Isrc -I$top_srcdir/src"
compile $LIBOBJS
echo "creating libgnu.a..."
$AR $ARFLAGS "$OUTLIB"/libgnu.a $objs
# 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
# 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"
echo done.

View File

@@ -1,89 +0,0 @@
#!/bin/sh
# Shell script to build GNU Make in the absence of any 'make' program.
# @configure_input@
# Copyright (C) 1993-2019 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/>.
# See Makefile.in for comments describing these variables.
LIBOBJDIR=lib/
U=
top_srcdir="@top_srcdir@"
CC="@CC@"
CFLAGS="@CFLAGS@ @GUILE_CFLAGS@"
CPPFLAGS="@CPPFLAGS@"
LDFLAGS="@AM_LDFLAGS@ @LDFLAGS@"
ALLOCA="@ALLOCA@"
LOADLIBES="@LIBS@ @GUILE_LIBS@ @LIBINTL@"
LIBOBJS="@LIBOBJS@"
REMOTE="@REMOTE@"
OBJEXT="@OBJEXT@"
EXEEXT="@EXEEXT@"
# Use our old-style glob implementation
test x"@USE_SYSTEM_GLOB@" = xno && LIBOBJS="${LIBOBJS} ${LIBOBJDIR}fnmatch.$OBJEXT ${LIBOBJDIR}glob.$OBJEXT"
# Common prefix for machine-independent installed files.
prefix="@prefix@"
# Common prefix for machine-dependent installed files.
exec_prefix=`eval echo @exec_prefix@`
# Directory to find libraries in for '-lXXX'.
libdir=${exec_prefix}/lib
# Directory to search by default for included makefiles.
includedir=${prefix}/include
localedir=${prefix}/share/locale
defines="-DLOCALEDIR=\"${localedir}\" -DLIBDIR=\"${libdir}\" -DINCLUDEDIR=\"${includedir}\" @DEFS@"
# Exit as soon as any command fails.
set -e
# These are all the objects we need to link together.
objs="%objs% src/remote-${REMOTE}.${OBJEXT} ${LIBOBJS}"
case $LIBOBJS in
(*alloca*) cp "$top_srcdir"/lib/alloca.in.h lib/alloca.h ;;
esac
case $LIBOBJS in
(*fnmatch*) cp "$top_srcdir"/lib/fnmatch.in.h lib/fnmatch.h ;;
esac
case $LIBOBJS in
(*glob*) cp "$top_srcdir"/lib/glob.in.h lib/glob.h ;;
esac
# Compile the source files into those objects.
for file in `echo ${objs} | sed 's/\.'${OBJEXT}'/.c/g'`; do
echo compiling ${file}...
$CC $defines $CPPFLAGS $CFLAGS \
-c -Isrc -I"$top_srcdir"/src -Ilib -I"$top_srcdir"/lib "$top_srcdir"/$file
done
# The object files were actually all put in the current directory.
# Remove the source directory names from the list.
srcobjs="$objs"
objs=
for obj in $srcobjs; do
objs="$objs `basename $obj`"
done
# Link all the objects together.
echo linking make...
$CC $CFLAGS $LDFLAGS $objs $LOADLIBES -o makenew${EXEEXT}
echo done
mv -f makenew${EXEEXT} make${EXEEXT}

View File

@@ -154,9 +154,11 @@ exit 1
:FoundMSVC :FoundMSVC
set OUTDIR=.\WinRel set OUTDIR=.\WinRel
set LNKOUT=./WinRel
set "OPTS=/O2 /D NDEBUG" set "OPTS=/O2 /D NDEBUG"
set LINKOPTS= set LINKOPTS=
if "%DEBUG%" == "Y" set OUTDIR=.\WinDebug if "%DEBUG%" == "Y" set OUTDIR=.\WinDebug
if "%DEBUG%" == "Y" set LNKOUT=./WinDebug
if "%DEBUG%" == "Y" set "OPTS=/Zi /Od /D _DEBUG" if "%DEBUG%" == "Y" set "OPTS=/Zi /Od /D _DEBUG"
if "%DEBUG%" == "Y" set LINKOPTS=/DEBUG if "%DEBUG%" == "Y" set LINKOPTS=/DEBUG
if "%MAINT%" == "Y" set "OPTS=%OPTS% /D MAKE_MAINTAINER_MODE" if "%MAINT%" == "Y" set "OPTS=%OPTS% /D MAKE_MAINTAINER_MODE"
@@ -168,9 +170,11 @@ goto Build
:FindGcc :FindGcc
set OUTDIR=.\GccRel set OUTDIR=.\GccRel
set LNKOUT=./GccRel
set OPTS=-O2 set OPTS=-O2
if "%DEBUG%" == "Y" set OPTS=-O0 if "%DEBUG%" == "Y" set OPTS=-O0
if "%DEBUG%" == "Y" set OUTDIR=.\GccDebug if "%DEBUG%" == "Y" set OUTDIR=.\GccDebug
if "%DEBUG%" == "Y" set LNKOUT=./GccDebug
if "%MAINT%" == "Y" set "OPTS=%OPTS% -DMAKE_MAINTAINER_MODE" if "%MAINT%" == "Y" set "OPTS=%OPTS% -DMAKE_MAINTAINER_MODE"
:: Show the compiler version that we found :: Show the compiler version that we found
echo. echo.
@@ -204,43 +208,43 @@ copy lib\fnmatch.in.h %OUTDIR%\lib\fnmatch.h
if exist %OUTDIR%\link.sc del %OUTDIR%\link.sc if exist %OUTDIR%\link.sc del %OUTDIR%\link.sc
call :Compile src\ar call :Compile src/ar
call :Compile src\arscan call :Compile src/arscan
call :Compile src\commands call :Compile src/commands
call :Compile src\default call :Compile src/default
call :Compile src\dir call :Compile src/dir
call :Compile src\expand call :Compile src/expand
call :Compile src\file call :Compile src/file
call :Compile src\function call :Compile src/function
call :Compile src\getopt call :Compile src/getopt
call :Compile src\getopt1 call :Compile src/getopt1
call :Compile src\guile GUILE call :Compile src/guile GUILE
call :Compile src\hash call :Compile src/hash
call :Compile src\implicit call :Compile src/implicit
call :Compile src\job call :Compile src/job
call :Compile src\load call :Compile src/load
call :Compile src\loadapi call :Compile src/loadapi
call :Compile src\main GUILE call :Compile src/main GUILE
call :Compile src\misc call :Compile src/misc
call :Compile src\output call :Compile src/output
call :Compile src\read call :Compile src/read
call :Compile src\remake call :Compile src/remake
call :Compile src\remote-stub call :Compile src/remote-stub
call :Compile src\rule call :Compile src/rule
call :Compile src\signame call :Compile src/signame
call :Compile src\strcache call :Compile src/strcache
call :Compile src\variable call :Compile src/variable
call :Compile src\version call :Compile src/version
call :Compile src\vpath call :Compile src/vpath
call :Compile src\w32\pathstuff call :Compile src/w32/pathstuff
call :Compile src\w32\w32os call :Compile src/w32/w32os
call :Compile src\w32\compat\posixfcn call :Compile src/w32/compat/posixfcn
call :Compile src\w32\subproc\misc call :Compile src/w32/subproc/misc
call :Compile src\w32\subproc\sub_proc call :Compile src/w32/subproc/sub_proc
call :Compile src\w32\subproc\w32err call :Compile src/w32/subproc/w32err
call :Compile lib\fnmatch call :Compile lib/fnmatch
call :Compile lib\glob call :Compile lib/glob
call :Compile lib\getloadavg call :Compile lib/getloadavg
if not "%COMPILER%" == "gcc" call :Compile src\w32\compat\dirent if not "%COMPILER%" == "gcc" call :Compile src\w32\compat\dirent
@@ -262,7 +266,7 @@ goto :EOF
:: ::
:Compile :Compile
echo %OUTDIR%\%1.%O% >>%OUTDIR%\link.sc echo %LNKOUT%/%1.%O% >>%OUTDIR%\link.sc
set EXTRAS= set EXTRAS=
if "%2" == "GUILE" set "EXTRAS=%GUILECFLAGS%" if "%2" == "GUILE" set "EXTRAS=%GUILECFLAGS%"
if exist "%OUTDIR%\%1.%O%" del "%OUTDIR%\%1.%O%" if exist "%OUTDIR%\%1.%O%" del "%OUTDIR%\%1.%O%"
@@ -277,7 +281,7 @@ goto CompileDone
:GccCompile :GccCompile
:: GCC Compile :: GCC Compile
echo on echo on
%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 %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
@echo off @echo off
:CompileDone :CompileDone
@@ -285,13 +289,14 @@ if not exist "%OUTDIR%\%1.%O%" exit 1
goto :EOF goto :EOF
:Link :Link
echo Linking %OUTDIR%/%MAKE%.exe echo.
echo Linking %LNKOUT%/%MAKE%.exe
if "%COMPILER%" == "gcc" goto GccLink if "%COMPILER%" == "gcc" goto GccLink
:: MSVC Link :: MSVC Link
echo %GUILELIBS% kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib >>%OUTDIR%\link.sc echo %GUILELIBS% kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib >>%OUTDIR%\link.sc
echo on echo on
link.exe /NOLOGO /SUBSYSTEM:console /PDB:%OUTDIR%\%MAKE%.pdb %LINKOPTS% /OUT:%OUTDIR%\%MAKE%.exe @%OUTDIR%\link.sc link.exe /NOLOGO /SUBSYSTEM:console /PDB:%LNKOUT%\%MAKE%.pdb %LINKOPTS% /OUT:%LNKOUT%\%MAKE%.exe @%LNKOUT%\link.sc
@echo off @echo off
goto :EOF goto :EOF
@@ -299,7 +304,7 @@ goto :EOF
:: GCC Link :: GCC Link
echo on echo on
echo %GUILELIBS% -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -luuid -lodbc32 -lodbccp32 >>%OUTDIR%\link.sc echo %GUILELIBS% -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -luuid -lodbc32 -lodbccp32 >>%OUTDIR%\link.sc
%COMPILER% -mthreads -gdwarf-2 -g3 %OPTS% -o %OUTDIR%\%MAKE%.exe @%OUTDIR%\link.sc -Wl,--out-implib=%OUTDIR%\libgnumake-1.dll.a %COMPILER% -mthreads -gdwarf-2 -g3 %OPTS% -o %LNKOUT%/%MAKE%.exe @%LNKOUT%/link.sc -Wl,--out-implib=%LNKOUT%/libgnumake-1.dll.a
@echo off @echo off
goto :EOF goto :EOF
@@ -390,6 +395,7 @@ set NOGUILE=
set O= set O=
set OPTS= set OPTS=
set OUTDIR= set OUTDIR=
set LNKOUT=
set PKGMSC= set PKGMSC=
set VSVARS= set VSVARS=
goto :EOF goto :EOF

View File

@@ -16,7 +16,7 @@
# You should have received a copy of the GNU General Public License along with # 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 <http://www.gnu.org/licenses/>.
AC_INIT([GNU make],[4.2.90],[bug-make@gnu.org]) AC_INIT([GNU make],[4.2.91],[bug-make@gnu.org])
AC_PREREQ([2.69]) AC_PREREQ([2.69])
@@ -164,6 +164,9 @@ AC_CHECK_FUNCS([strcasecmp strncasecmp strcmpi strncmpi stricmp strnicmp])
AC_FUNC_STRCOLL AC_FUNC_STRCOLL
AC_FUNC_CLOSEDIR_VOID AC_FUNC_CLOSEDIR_VOID
# dir.c and our glob.c use dirent.d_type if available
AC_STRUCT_DIRENT_D_TYPE
# See if the user wants to add (or not) GNU Guile support # See if the user wants to add (or not) GNU Guile support
AC_ARG_WITH([guile], [AS_HELP_STRING([--with-guile], AC_ARG_WITH([guile], [AS_HELP_STRING([--with-guile],
[Support GNU Guile for embedded scripting])]) [Support GNU Guile for embedded scripting])])
@@ -400,38 +403,6 @@ AS_IF([(/usr/sccs/admin -n s.conftest || admin -n s.conftest) >/dev/null 2>&1 &&
]) ])
rm -f s.conftest conftoast rm -f s.conftest conftoast
# 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])])
# Tell automake about this, so it can build the right .c files.
AM_CONDITIONAL([USE_SYSTEM_GLOB], [test "$make_cv_sys_gnu_glob" = yes])
# Tell build.sh which to use
USE_SYSTEM_GLOB="$make_cv_sys_gnu_glob"
AC_SUBST([USE_SYSTEM_GLOB])
# See if we need a replacement for getloadavg()
gl_GETLOADAVG
if test $HAVE_GETLOADAVG = 0; then
AC_LIBOBJ([getloadavg])
gl_PREREQ_GETLOADAVG
fi
gl_STDLIB_MODULE_INDICATOR([getloadavg])
# Let the makefile know what our build host is # Let the makefile know what our build host is
AC_DEFINE_UNQUOTED([MAKE_HOST],["$host"],[Build host information.]) AC_DEFINE_UNQUOTED([MAKE_HOST],["$host"],[Build host information.])
@@ -521,7 +492,7 @@ AS_IF([test "x$make_cv_posix_spawn" = xno && test "x$user_posix_spawn" = xyes],
]) ])
# Specify what files are to be created. # Specify what files are to be created.
AC_CONFIG_FILES([Makefile lib/Makefile po/Makefile.in doc/Makefile \ AC_CONFIG_FILES([Makefile build.cfg lib/Makefile po/Makefile.in doc/Makefile \
tests/config-flags.pm]) tests/config-flags.pm])
# We don't need this: the standard automake output suffices for POSIX systems. # We don't need this: the standard automake output suffices for POSIX systems.
#mk/Posix.mk #mk/Posix.mk
@@ -530,13 +501,6 @@ AC_CONFIG_FILES([Makefile lib/Makefile po/Makefile.in doc/Makefile \
AC_OUTPUT AC_OUTPUT
# We only generate the build.sh if we have a build.sh.in; we won't have
# one before we've created a distribution.
AS_IF([test -f "$srcdir/build.sh.in"],
[ ./config.status --file build.sh
chmod +x build.sh
])
dnl Local Variables: dnl Local Variables:
dnl comment-start: "dnl " dnl comment-start: "dnl "
dnl comment-end: "" dnl comment-end: ""

View File

@@ -3980,7 +3980,7 @@ the statements in sequence. For example:
@example @example
foo : bar/lose foo : bar/lose
cd $(@@D) && gobble $(@@F) > ../$@@ cd $(<D) && gobble $(<F) > ../$@@
@end example @end example
@noindent @noindent
@@ -5523,17 +5523,19 @@ replaced; other occurrences of @var{a} in the value are unaltered. For
example:@refill example:@refill
@example @example
foo := a.o b.o c.o foo := a.o b.o l.a c.o
bar := $(foo:.o=.c) bar := $(foo:.o=.c)
@end example @end example
@noindent @noindent
sets @samp{bar} to @samp{a.c b.c c.c}. @xref{Setting, ,Setting Variables}. sets @samp{bar} to @samp{a.c b.c l.a c.c}. @xref{Setting, ,Setting Variables}.
A substitution reference is actually an abbreviation for use of the A substitution reference is shorthand for the @code{patsubst}
@code{patsubst} expansion function (@pxref{Text Functions, ,Functions for String Substitution and Analysis}). We provide expansion function (@pxref{Text Functions, ,Functions for String Substitution and Analysis}):
substitution references as well as @code{patsubst} for compatibility with @samp{$(@var{var}:@var{a}=@var{b})} is equivalent to
other implementations of @code{make}. @samp{$(patsubst %@var{a},%@var{b},@var{var})}. We provide
substitution references as well as @code{patsubst} for compatibility
with other implementations of @code{make}.
@findex patsubst @findex patsubst
Another type of substitution reference lets you use the full power of Another type of substitution reference lets you use the full power of
@@ -5548,13 +5550,13 @@ for a description of the @code{patsubst} function.@refill
@group @group
@exdent For example: @exdent For example:
foo := a.o b.o c.o foo := a.o b.o l.a c.o
bar := $(foo:%.o=%.c) bar := $(foo:%.o=%.c)
@end group @end group
@end example @end example
@noindent @noindent
sets @samp{bar} to @samp{a.c b.c c.c}. sets @samp{bar} to @samp{a.c b.c l.a c.c}.
@node Computed Names, , Substitution Refs, Advanced @node Computed Names, , Substitution Refs, Advanced
@subsection Computed Variable Names @subsection Computed Variable Names
@@ -11623,7 +11625,8 @@ On POSIX systems the jobserver is implemented as a simple UNIX pipe.
The pipe will be pre-loaded with one single-character token for each The pipe will be pre-loaded with one single-character token for each
available job. To obtain an extra slot you must read a single available job. To obtain an extra slot you must read a single
character from the jobserver pipe; to release a slot you must write a character from the jobserver pipe; to release a slot you must write a
single character back into the jobserver pipe. single character back into the jobserver pipe. Note that the read
side of the jobserver pipe is set to ``blocking'' mode.
To access the pipe you must parse the @code{MAKEFLAGS} variable and To access the pipe you must parse the @code{MAKEFLAGS} variable and
look for the argument string @code{--jobserver-auth=R,W} where look for the argument string @code{--jobserver-auth=R,W} where

View File

@@ -2,6 +2,33 @@ 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. a very old version of the globbing library.
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])])
# Tell automake about this, so it can build the right .c files.
AM_CONDITIONAL([USE_SYSTEM_GLOB], [test "$make_cv_sys_gnu_glob" = yes])
# Tell build.sh which to use
USE_SYSTEM_GLOB="$make_cv_sys_gnu_glob"
AC_SUBST([USE_SYSTEM_GLOB])
Makefile.am: Makefile.am:
if !USE_SYSTEM_GLOB if !USE_SYSTEM_GLOB
libgnu_a_SOURCES += fnmatch.c libgnu_a_SOURCES += fnmatch.c

View File

@@ -117,7 +117,7 @@ extern int errno;
/* When used in the GNU libc the symbol _DIRENT_HAVE_D_TYPE is available /* When used in the GNU libc the symbol _DIRENT_HAVE_D_TYPE is available
if the `d_type' member for `struct dirent' is available. */ if the `d_type' member for `struct dirent' is available. */
#ifdef _DIRENT_HAVE_D_TYPE #if defined(_DIRENT_HAVE_D_TYPE) || defined(HAVE_STRUCT_DIRENT_D_TYPE)
# define HAVE_D_TYPE 1 # define HAVE_D_TYPE 1
#endif #endif

View File

@@ -29,11 +29,13 @@ MAKEWEBDIR ?= $(SRCROOTDIR)/make/make-web
# We like mondo-warnings! # We like mondo-warnings!
# Also force comments to be preserved. This helps when using ccache, in # Also force comments to be preserved. This helps when using ccache, in
# combination with GCC 7's implicit-fallthrough warning. # combination with GCC 7's implicit-fallthrough warning.
AM_CFLAGS += -C -Wall -Wextra -Werror -Wwrite-strings -Wshadow \ MAKE_CFLAGS := -C -Wall -Wextra -Werror -Wwrite-strings -Wshadow \
-Wdeclaration-after-statement -Wbad-function-cast -Wformat-security \ -Wdeclaration-after-statement -Wbad-function-cast -Wformat-security \
-Wtype-limits -Wunused-but-set-parameter -Wlogical-op -Wpointer-arith \ -Wtype-limits -Wunused-but-set-parameter -Wlogical-op -Wpointer-arith \
-Wignored-qualifiers -Wformat-signedness -Wduplicated-cond -Wignored-qualifiers -Wformat-signedness -Wduplicated-cond
AM_CFLAGS += $(MAKE_CFLAGS)
# Unfortunately the Guile headers are sometimes broken. Convince GCC # Unfortunately the Guile headers are sometimes broken. Convince GCC
# to treat them as system headers so warnings are ignored. # to treat them as system headers so warnings are ignored.
GUILE_CFLAGS := $(patsubst -I%,-isystem %,$(GUILE_CFLAGS)) GUILE_CFLAGS := $(patsubst -I%,-isystem %,$(GUILE_CFLAGS))
@@ -83,16 +85,6 @@ Basic.mk: Basic.mk.template .dep_segment Makefile
$(word 2,$^) >>$@ $(word 2,$^) >>$@
chmod a-w $@ chmod a-w $@
# Construct build.sh.in
#
build.sh.in: build.template Makefile
rm -f $@
sed -e 's@%objs%@$(patsubst %.o,%.$${OBJEXT},$(filter-out src/remote-%,$(make_OBJECTS)))@g' \
$< > $@
chmod a-w+x $@
all: build.sh.in
# Use automake to build a dependency list file, for Makebase.mk. # Use automake to build a dependency list file, for Makebase.mk.
# #
@@ -264,9 +256,9 @@ $(CONFIG_CHECKS): checkcfg.%: distdir
$(AM_DISTCHECK_CONFIGURE_FLAGS) $(DISTCHECK_CONFIGURE_FLAGS) $(AM_DISTCHECK_CONFIGURE_FLAGS) $(DISTCHECK_CONFIGURE_FLAGS)
exec >>'checkcfg.$*.log' 2>&1; set -x; \ exec >>'checkcfg.$*.log' 2>&1; set -x; \
cd $(distdir)/_build \ cd $(distdir)/_build \
&& ./build.sh \ && OUTDIR=_bld ../build.sh \
&& ./make $(AM_MAKEFLAGS) check \ && _bld/make $(AM_MAKEFLAGS) check-local \
&& ./make $(AM_MAKEFLAGS) clean && _bld/make $(AM_MAKEFLAGS) clean
exec >>'checkcfg.$*.log' 2>&1; set -x; \ exec >>'checkcfg.$*.log' 2>&1; set -x; \
cd $(distdir)/_build \ cd $(distdir)/_build \
&& $(NR_MAKE) $(AM_MAKEFLAGS) CFLAGS='$(AM_CFLAGS)' \ && $(NR_MAKE) $(AM_MAKEFLAGS) CFLAGS='$(AM_CFLAGS)' \
@@ -403,7 +395,7 @@ $(COV_BUILD_FILE): $(filter %.c %.h,$(DISTFILES))
CFLAGS='$(AM_CFLAGS)' CFLAGS='$(AM_CFLAGS)'
PATH="$${COVERITY_PATH:+$$COVERITY_PATH/bin:}$$PATH"; \ PATH="$${COVERITY_PATH:+$$COVERITY_PATH/bin:}$$PATH"; \
cd '$(distdir)'/_build \ cd '$(distdir)'/_build \
&& cov-build --dir cov-int ./build.sh && cov-build --dir cov-int ../build.sh
rm -f '$@' rm -f '$@'
(cd '$(distdir)'/_build && tar czf - cov-int) > '$@' (cd '$(distdir)'/_build && tar czf - cov-int) > '$@'

View File

@@ -40,7 +40,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#include <rmsdef.h> #include <rmsdef.h>
/* This symbol should be present in lbrdef.h. */ /* This symbol should be present in lbrdef.h. */
#ifndef LBR$_HDRTRUNC #if !defined LBR$_HDRTRUNC
#pragma extern_model save #pragma extern_model save
#pragma extern_model globalvalue #pragma extern_model globalvalue
extern unsigned int LBR$_HDRTRUNC; extern unsigned int LBR$_HDRTRUNC;
@@ -909,7 +909,7 @@ ar_member_touch (const char *arname, const char *memname)
for (ui = 0; ui < sizeof ar_hdr.ar_date; ui++) for (ui = 0; ui < sizeof ar_hdr.ar_date; ui++)
ar_hdr.ar_date[ui] = ' '; ar_hdr.ar_date[ui] = ' ';
sprintf (TOCHAR (ar_hdr.ar_date), "%lu", (long unsigned) statbuf.st_mtime); sprintf (TOCHAR (ar_hdr.ar_date), "%lu", (long unsigned) statbuf.st_mtime);
ar_hdr.ar_date[strlen (ar_hdr.ar_date)] = ' '; ar_hdr.ar_date[strlen ((char *) ar_hdr.ar_date)] = ' ';
#else #else
ar_hdr.ar_date = statbuf.st_mtime; ar_hdr.ar_date = statbuf.st_mtime;
#endif #endif

View File

@@ -291,6 +291,9 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Define to 1 if you have the 'strsignal' function. */ /* Define to 1 if you have the 'strsignal' function. */
/* #undef HAVE_STRSIGNAL */ /* #undef HAVE_STRSIGNAL */
/* Define to 1 if `d_type' is a member of `struct dirent'. */
#define HAVE_STRUCT_DIRENT_D_TYPE 1
/* Define to 1 if you have the `isatty' function. */ /* Define to 1 if you have the `isatty' function. */
#define HAVE_ISATTY 1 #define HAVE_ISATTY 1
@@ -298,6 +301,11 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#define HAVE_TTYNAME 1 #define HAVE_TTYNAME 1
char *ttyname (int); char *ttyname (int);
/* Define to 1 if you have the `umask' function. */
#ifdef __MINGW32__
# define HAVE_UMASK 1
#endif
/* Define to 1 if 'n_un.n_name' is a member of 'struct nlist'. */ /* Define to 1 if 'n_un.n_name' is a member of 'struct nlist'. */
/* #undef HAVE_STRUCT_NLIST_N_UN_N_NAME */ /* #undef HAVE_STRUCT_NLIST_N_UN_N_NAME */
@@ -470,6 +478,11 @@ char *ttyname (int);
/* Define to empty if 'const' does not conform to ANSI C. */ /* Define to empty if 'const' does not conform to ANSI C. */
/* #undef const */ /* #undef const */
#ifdef __MINGW32__
# undef __USE_MINGW_ANSI_STDIO
# define __USE_MINGW_ANSI_STDIO 1
#endif
#include <sys/types.h> #include <sys/types.h>
/* Define to 'int' if <sys/types.h> doesn't define. */ /* Define to 'int' if <sys/types.h> doesn't define. */

View File

@@ -44,11 +44,11 @@ struct nameseq
NAMESEQ (_t); \ NAMESEQ (_t); \
struct file *file; \ struct file *file; \
const char *stem; \ const char *stem; \
unsigned short flags : 8; \ unsigned int flags : 8; \
unsigned short changed : 1; \ unsigned int changed : 1; \
unsigned short ignore_mtime : 1; \ unsigned int ignore_mtime : 1; \
unsigned short staticpattern : 1; \ unsigned int staticpattern : 1; \
unsigned short need_2nd_expansion : 1 unsigned int need_2nd_expansion : 1
struct dep struct dep
{ {

View File

@@ -732,7 +732,7 @@ dir_contents_file_exists_p (struct directory_contents *dir,
#else #else
df->name = strcache_add_len (d->d_name, len); df->name = strcache_add_len (d->d_name, len);
#endif #endif
#ifdef _DIRENT_HAVE_D_TYPE #ifdef HAVE_STRUCT_DIRENT_D_TYPE
df->type = d->d_type; df->type = d->d_type;
#endif #endif
df->length = len; df->length = len;
@@ -1245,7 +1245,7 @@ read_dirstream (__ptr_t stream)
#ifdef _DIRENT_HAVE_D_NAMLEN #ifdef _DIRENT_HAVE_D_NAMLEN
d->d_namlen = len - 1; d->d_namlen = len - 1;
#endif #endif
#ifdef _DIRENT_HAVE_D_TYPE #ifdef HAVE_STRUCT_DIRENT_D_TYPE
d->d_type = df->type; d->d_type = df->type;
#endif #endif
memcpy (d->d_name, df->name, len); memcpy (d->d_name, df->name, len);
@@ -1332,6 +1332,7 @@ local_lstat (const char *path, struct stat *buf)
void void
dir_setup_glob (glob_t *gl) dir_setup_glob (glob_t *gl)
{ {
gl->gl_offs = 0;
gl->gl_opendir = open_dirstream; gl->gl_opendir = open_dirstream;
gl->gl_readdir = read_dirstream; gl->gl_readdir = read_dirstream;
gl->gl_closedir = free; gl->gl_closedir = free;

View File

@@ -38,8 +38,8 @@ struct function_table_entry
unsigned char len; unsigned char len;
unsigned char minimum_args; unsigned char minimum_args;
unsigned char maximum_args; unsigned char maximum_args;
unsigned char expand_args:1; unsigned int expand_args:1;
unsigned char alloc_fn:1; unsigned int alloc_fn:1;
}; };
static unsigned long static unsigned long
@@ -1780,12 +1780,16 @@ func_shell_base (char *o, char **argv, int trim_newlines)
fd_noinherit (pipedes[0]); fd_noinherit (pipedes[0]);
{ {
struct output out; struct childbase child;
out.syncout = 1; child.cmd_name = NULL;
out.out = pipedes[1]; child.output.syncout = 1;
out.err = errfd; child.output.out = pipedes[1];
child.output.err = errfd;
child.environment = envp;
pid = child_execute_job (&out, 1, command_argv, envp); pid = child_execute_job (&child, 1, command_argv);
free (child.cmd_name);
} }
if (pid < 0) if (pid < 0)

162
src/job.c
View File

@@ -17,6 +17,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#include "makeint.h" #include "makeint.h"
#include <assert.h> #include <assert.h>
#include <string.h>
#include "job.h" #include "job.h"
#include "debug.h" #include "debug.h"
@@ -25,8 +26,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#include "variable.h" #include "variable.h"
#include "os.h" #include "os.h"
#include <string.h>
/* Default shell to use. */ /* Default shell to use. */
#ifdef WINDOWS32 #ifdef WINDOWS32
# ifdef HAVE_STRINGS_H # ifdef HAVE_STRINGS_H
@@ -139,6 +138,7 @@ extern int wait3 ();
#ifdef USE_POSIX_SPAWN #ifdef USE_POSIX_SPAWN
# include <spawn.h> # include <spawn.h>
# include "findprog.h"
#endif #endif
#if !defined (wait) && !defined (POSIX) #if !defined (wait) && !defined (POSIX)
@@ -724,7 +724,9 @@ reap_children (int block, int err)
else if (pid < 0) else if (pid < 0)
{ {
/* A remote status command failed miserably. Punt. */ /* A remote status command failed miserably. Punt. */
#if !defined(__MSDOS__) && !defined(_AMIGA) && !defined(WINDOWS32)
remote_status_lose: remote_status_lose:
#endif
pfatal_with_name ("remote_status"); pfatal_with_name ("remote_status");
} }
else else
@@ -905,6 +907,36 @@ reap_children (int block, int err)
--job_counter; --job_counter;
process_child: process_child:
#if defined(USE_POSIX_SPAWN)
/* Some versions of posix_spawn() do not detect errors such as command
not found until after they fork. In that case they will exit with a
code of 127. Try to detect that and provide a useful error message.
Otherwise we'll just show the error below, as normal. */
if (exit_sig == 0 && exit_code == 127 && c->cmd_name)
{
const char *e = NULL;
struct stat st;
int r;
/* There are various ways that this will show a different error than
fork/exec. To really get the right error we'd have to fall back
to fork/exec but I don't want to bother with that. Just do the
best we can. */
EINTRLOOP(r, stat(c->cmd_name, &st));
if (r < 0)
e = strerror (errno);
else if (S_ISDIR(st.st_mode) || !(st.st_mode & S_IXUSR))
e = strerror (EACCES);
else if (st.st_size == 0)
e = strerror (ENOEXEC);
if (e)
OSS(error, NILF, "%s: %s", c->cmd_name, e);
}
#endif
/* Determine the failure status: 0 for success, 1 for updating target in /* Determine the failure status: 0 for success, 1 for updating target in
question mode, 2 for anything else. */ question mode, 2 for anything else. */
if (exit_sig == 0 && exit_code == 0) if (exit_sig == 0 && exit_code == 0)
@@ -1113,6 +1145,7 @@ free_child (struct child *child)
free (child->environment); free (child->environment);
} }
free (child->cmd_name);
free (child); free (child);
} }
@@ -1207,12 +1240,11 @@ start_job_command (struct child *child)
} }
argv = p; argv = p;
/* Although construct_command_argv contains some code for VMS, it was/is /* Please note, for VMS argv is a string (not an array of strings) which
not called/used. Please note, for VMS argv is a string (not an array contains the complete command line, which for multi-line variables
of strings) which contains the complete command line, which for still includes the newlines. So detect newlines and set 'end' (which
multi-line variables still includes the newlines. So detect newlines is used for child->command_ptr) instead of (re-)writing
and set 'end' (which is used for child->command_ptr) instead of construct_command_argv */
(re-)writing construct_command_argv */
if (!one_shell) if (!one_shell)
{ {
char *s = p; char *s = p;
@@ -1420,8 +1452,7 @@ start_job_command (struct child *child)
child->remote = 0; child->remote = 0;
#ifdef VMS #ifdef VMS
if (!child_execute_job (child, argv)) child->pid = child_execute_job ((struct childbase *)child, 1, argv);
child->pid = -1;
#else #else
@@ -1429,11 +1460,12 @@ start_job_command (struct child *child)
jobserver_pre_child (flags & COMMANDS_RECURSE); jobserver_pre_child (flags & COMMANDS_RECURSE);
child->pid = child_execute_job (&child->output, child->good_stdin, child->pid = child_execute_job ((struct childbase *)child,
argv, child->environment); child->good_stdin, argv);
environ = parent_environ; /* Restore value child may have clobbered. */ environ = parent_environ; /* Restore value child may have clobbered. */
jobserver_post_child (flags & COMMANDS_RECURSE); jobserver_post_child (flags & COMMANDS_RECURSE);
#endif /* !VMS */ #endif /* !VMS */
} }
@@ -2128,7 +2160,7 @@ start_waiting_jobs (void)
/* EMX: Start a child process. This function returns the new pid. */ /* EMX: Start a child process. This function returns the new pid. */
# if defined __EMX__ # if defined __EMX__
pid_t pid_t
child_execute_job (struct output *out, int good_stdin, char **argv, char **envp) child_execute_job (struct childbase *child, int good_stdin, char **argv)
{ {
pid_t pid; pid_t pid;
int fdin = good_stdin ? FD_STDIN : get_bad_stdin (); int fdin = good_stdin ? FD_STDIN : get_bad_stdin ();
@@ -2139,12 +2171,12 @@ child_execute_job (struct output *out, int good_stdin, char **argv, char **envp)
int save_fderr = -1; int save_fderr = -1;
/* Divert child output if we want to capture output. */ /* Divert child output if we want to capture output. */
if (out && out->syncout) if (child->output.syncout)
{ {
if (out->out >= 0) if (child->output.out >= 0)
fdout = out->out; fdout = child->output.out;
if (out->err >= 0) if (child->output.err >= 0)
fderr = out->err; fderr = child->output.err;
} }
/* For each FD which needs to be redirected first make a dup of the standard /* For each FD which needs to be redirected first make a dup of the standard
@@ -2190,7 +2222,7 @@ child_execute_job (struct output *out, int good_stdin, char **argv, char **envp)
} }
/* Run the command. */ /* Run the command. */
pid = exec_command (argv, envp); pid = exec_command (argv, child->environment);
/* Restore stdout/stdin/stderr of the parent and close temporary FDs. */ /* Restore stdout/stdin/stderr of the parent and close temporary FDs. */
if (save_fdin >= 0) if (save_fdin >= 0)
@@ -2227,9 +2259,9 @@ child_execute_job (struct output *out, int good_stdin, char **argv, char **envp)
/* POSIX: /* POSIX:
Create a child process executing the command in ARGV. Create a child process executing the command in ARGV.
ENVP is the environment of the new program. Returns the PID or -1. */ Returns the PID or -1. */
pid_t pid_t
child_execute_job (struct output *out, int good_stdin, char **argv, char **envp) child_execute_job (struct childbase *child, int good_stdin, char **argv)
{ {
const int fdin = good_stdin ? FD_STDIN : get_bad_stdin (); const int fdin = good_stdin ? FD_STDIN : get_bad_stdin ();
int fdout = FD_STDOUT; int fdout = FD_STDOUT;
@@ -2237,18 +2269,19 @@ child_execute_job (struct output *out, int good_stdin, char **argv, char **envp)
pid_t pid; pid_t pid;
int r; int r;
#if defined(USE_POSIX_SPAWN) #if defined(USE_POSIX_SPAWN)
short flags = 0; char *cmd;
posix_spawnattr_t attr; posix_spawnattr_t attr;
posix_spawn_file_actions_t fa; posix_spawn_file_actions_t fa;
short flags = 0;
#endif #endif
/* Divert child output if we want to capture it. */ /* Divert child output if we want to capture it. */
if (out && out->syncout) if (child->output.syncout)
{ {
if (out->out >= 0) if (child->output.out >= 0)
fdout = out->out; fdout = child->output.out;
if (out->err >= 0) if (child->output.err >= 0)
fderr = out->err; fderr = child->output.err;
} }
#if !defined(USE_POSIX_SPAWN) #if !defined(USE_POSIX_SPAWN)
@@ -2276,9 +2309,9 @@ child_execute_job (struct output *out, int good_stdin, char **argv, char **envp)
EINTRLOOP (r, dup2 (fderr, FD_STDERR)); EINTRLOOP (r, dup2 (fderr, FD_STDERR));
/* Run the command. */ /* Run the command. */
exec_command (argv, envp); exec_command (argv, child->environment);
#else /* use posix_spawn() */ #else /* USE_POSIX_SPAWN */
if ((r = posix_spawnattr_init (&attr)) != 0) if ((r = posix_spawnattr_init (&attr)) != 0)
goto done; goto done;
@@ -2306,10 +2339,6 @@ child_execute_job (struct output *out, int good_stdin, char **argv, char **envp)
flags |= POSIX_SPAWN_USEVFORK; flags |= POSIX_SPAWN_USEVFORK;
#endif #endif
#ifdef SET_STACK_SIZE
/* No support for resetting the stack limit with posix_spawn(). */
#endif
/* For any redirected FD, dup2() it to the standard FD. /* For any redirected FD, dup2() it to the standard FD.
They are all marked close-on-exec already. */ They are all marked close-on-exec already. */
if (fdin >= 0 && fdin != FD_STDIN) if (fdin >= 0 && fdin != FD_STDIN)
@@ -2329,10 +2358,67 @@ child_execute_job (struct output *out, int good_stdin, char **argv, char **envp)
if ((r = posix_spawnattr_setflags (&attr, flags)) != 0) if ((r = posix_spawnattr_setflags (&attr, flags)) != 0)
goto cleanup; goto cleanup;
/* Look up the program on the child's PATH, if needed. */
{
const char *p = NULL;
char **pp;
for (pp = child->environment; *pp != NULL; ++pp)
if ((*pp)[0] == 'P' && (*pp)[1] == 'A' && (*pp)[2] == 'T'
&& (*pp)[3] == 'H' &&(*pp)[4] == '=')
{
p = (*pp) + 5;
break;
}
cmd = (char *)find_in_given_path (argv[0], p, 0);
}
if (!cmd)
{
r = errno;
goto cleanup;
}
/* Start the program. */ /* Start the program. */
while ((r = posix_spawnp (&pid, argv[0], &fa, &attr, argv, envp)) == EINTR) while ((r = posix_spawn (&pid, cmd, &fa, &attr, argv,
child->environment)) == EINTR)
; ;
/* posix_spawn() doesn't provide sh fallback like exec() does; implement
it here. POSIX doesn't specify the path to sh so use the default. */
if (r == ENOEXEC)
{
char **nargv;
char **pp;
size_t l = 0;
for (pp = argv; *pp != NULL; ++pp)
++l;
nargv = xmalloc (sizeof (char *) * (l + 2));
nargv[0] = (char *)default_shell;
nargv[1] = cmd;
memcpy (&nargv[2], &argv[1], sizeof (char *) * l);
while ((r = posix_spawn (&pid, nargv[0], &fa, &attr, nargv,
child->environment)) == EINTR)
;
free (nargv);
}
if (r == 0)
{
/* Spawn succeeded but may fail later: remember the command. */
free (child->cmd_name);
if (cmd != argv[0])
child->cmd_name = cmd;
else
child->cmd_name = xstrdup(cmd);
}
cleanup: cleanup:
posix_spawn_file_actions_destroy (&fa); posix_spawn_file_actions_destroy (&fa);
posix_spawnattr_destroy (&attr); posix_spawnattr_destroy (&attr);
@@ -2341,7 +2427,7 @@ child_execute_job (struct output *out, int good_stdin, char **argv, char **envp)
if (r != 0) if (r != 0)
pid = -1; pid = -1;
#endif /* have posix_spawn() */ #endif /* USE_POSIX_SPAWN */
if (pid < 0) if (pid < 0)
OSS (error, NILF, "%s: %s", argv[0], strerror (r)); OSS (error, NILF, "%s: %s", argv[0], strerror (r));
@@ -2662,7 +2748,7 @@ construct_command_argv_internal (char *line, char **restp, const char *shell,
can handle quoted file names just fine, removing the quote lifts can handle quoted file names just fine, removing the quote lifts
the limit from a very frequent use case, because using quoted the limit from a very frequent use case, because using quoted
file names is commonplace on MS-Windows. */ file names is commonplace on MS-Windows. */
static const char *sh_chars_dos = "|&<>%"; static const char *sh_chars_dos = "|&<>";
static const char *sh_cmds_dos[] = static const char *sh_cmds_dos[] =
{ "assoc", "break", "call", "cd", "chcp", "chdir", "cls", "color", "copy", { "assoc", "break", "call", "cd", "chcp", "chdir", "cls", "color", "copy",
"ctty", "date", "del", "dir", "echo", "echo.", "endlocal", "erase", "ctty", "date", "del", "dir", "echo", "echo.", "endlocal", "erase",
@@ -2863,9 +2949,9 @@ construct_command_argv_internal (char *line, char **restp, const char *shell,
else if (instring == '"' && strchr ("\\$`", *p) != 0 && unixy_shell) else if (instring == '"' && strchr ("\\$`", *p) != 0 && unixy_shell)
goto slow; goto slow;
#ifdef WINDOWS32 #ifdef WINDOWS32
/* Quoted wildcard and % characters must be passed quoted to the /* Quoted wildcard characters must be passed quoted to the
command, so give up the fast route. */ command, so give up the fast route. */
else if (instring == '"' && strchr ("*?%", *p) != 0 && !unixy_shell) else if (instring == '"' && strchr ("*?", *p) != 0 && !unixy_shell)
goto slow; goto slow;
else if (instring == '"' && strncmp (p, "\\\"", 2) == 0) else if (instring == '"' && strncmp (p, "\\\"", 2) == 0)
*ap++ = *++p; *ap++ = *++p;

View File

@@ -18,30 +18,44 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Structure describing a running or dead child process. */ /* Structure describing a running or dead child process. */
#ifdef VMS
#define VMSCHILD \
char *comname; /* Temporary command file name */ \
int efn; /* Completion event flag number */ \
int cstatus; /* Completion status */ \
int vms_launch_status; /* non-zero if lib$spawn, etc failed */
#else
#define VMSCHILD
#endif
#define CHILDBASE \
char *cmd_name; /* Alloced copy of command run. */ \
char **environment; /* Environment for commands. */ \
VMSCHILD \
struct output output /* Output for this child. */
struct childbase
{
CHILDBASE;
};
struct child struct child
{ {
CHILDBASE;
struct child *next; /* Link in the chain. */ struct child *next; /* Link in the chain. */
struct file *file; /* File being remade. */ struct file *file; /* File being remade. */
char **environment; /* Environment for commands. */
char *sh_batch_file; /* Script file for shell commands */ char *sh_batch_file; /* Script file for shell commands */
char **command_lines; /* Array of variable-expanded cmd lines. */ char **command_lines; /* Array of variable-expanded cmd lines. */
char *command_ptr; /* Ptr into command_lines[command_line]. */ char *command_ptr; /* Ptr into command_lines[command_line]. */
struct output output; /* Output for this child. */
#ifdef VMS
char *comname; /* Temporary command file name */
int efn; /* Completion event flag number */
int cstatus; /* Completion status */
int vms_launch_status; /* non-zero if lib$spawn, etc failed */
#endif
unsigned int command_line; /* Index into command_lines. */ unsigned int command_line; /* Index into command_lines. */
pid_t pid; /* Child process's ID number. */ pid_t pid; /* Child process's ID number. */
unsigned int remote:1; /* Nonzero if executing remotely. */ unsigned int remote:1; /* Nonzero if executing remotely. */
unsigned int noerror:1; /* Nonzero if commands contained a '-'. */ unsigned int noerror:1; /* Nonzero if commands contained a '-'. */
unsigned int good_stdin:1; /* Nonzero if this child has a good stdin. */ unsigned int good_stdin:1; /* Nonzero if this child has a good stdin. */
@@ -62,12 +76,7 @@ void start_waiting_jobs (void);
char **construct_command_argv (char *line, char **restp, struct file *file, char **construct_command_argv (char *line, char **restp, struct file *file,
int cmd_flags, char** batch_file); int cmd_flags, char** batch_file);
#ifdef VMS pid_t child_execute_job (struct childbase *child, int good_stdin, char **argv);
int child_execute_job (struct child *child, char *argv);
#else
pid_t child_execute_job (struct output *out, int good_stdin,
char **argv, char **envp);
#endif
#ifdef _AMIGA #ifdef _AMIGA
void exec_command (char **argv) __attribute__ ((noreturn)); void exec_command (char **argv) __attribute__ ((noreturn));

View File

@@ -2469,7 +2469,12 @@ main (int argc, char **argv, char **envp)
termination. */ termination. */
pid_t pid; pid_t pid;
int r; int r;
pid = child_execute_job (NULL, 1, nargv, environ); struct childbase child;
child.cmd_name = NULL;
child.output.syncout = 0;
child.environment = environ;
pid = child_execute_job (&child, 1, nargv);
/* is this loop really necessary? */ /* is this loop really necessary? */
do { do {
@@ -2639,8 +2644,8 @@ init_switches (void)
for (i = 0; switches[i].c != '\0'; ++i) for (i = 0; switches[i].c != '\0'; ++i)
{ {
long_options[i].name = (switches[i].long_name == 0 ? "" : long_options[i].name = (char *) (switches[i].long_name == 0 ? "" :
switches[i].long_name); switches[i].long_name);
long_options[i].flag = 0; long_options[i].flag = 0;
long_options[i].val = switches[i].c; long_options[i].val = switches[i].c;
if (short_option (switches[i].c)) if (short_option (switches[i].c))

View File

@@ -292,12 +292,9 @@ char *strerror (int errnum);
char *strsignal (int signum); char *strsignal (int signum);
#endif #endif
#if defined(HAVE_UMASK) #if !defined(HAVE_UMASK)
# define UMASK(_m) umask (_m) typedef int mode_t;
# define MODE_T mode_t extern mode_t umask (mode_t);
#else
# define UMASK(_m) 0
# define MODE_T int
#endif #endif
/* ISDIGIT offers the following features: /* ISDIGIT offers the following features:
@@ -451,7 +448,8 @@ extern int unixy_shell;
#define NEXT_TOKEN(s) while (ISSPACE (*(s))) ++(s) #define NEXT_TOKEN(s) while (ISSPACE (*(s))) ++(s)
#define END_OF_TOKEN(s) while (! STOP_SET (*(s), MAP_SPACE|MAP_NUL)) ++(s) #define END_OF_TOKEN(s) while (! STOP_SET (*(s), MAP_SPACE|MAP_NUL)) ++(s)
#if defined(HAVE_SYS_RESOURCE_H) && defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT) /* 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 # define SET_STACK_SIZE
#endif #endif
#ifdef SET_STACK_SIZE #ifdef SET_STACK_SIZE

View File

@@ -437,6 +437,14 @@ char *mktemp (char *template);
# endif # endif
#endif #endif
#ifndef HAVE_UMASK
mode_t
umask (mode_t mask)
{
return 0;
}
#endif
FILE * FILE *
get_tmpfile (char **name, const char *template) get_tmpfile (char **name, const char *template)
{ {
@@ -446,7 +454,7 @@ get_tmpfile (char **name, const char *template)
#endif #endif
/* Preserve the current umask, and set a restrictive one for temp files. */ /* Preserve the current umask, and set a restrictive one for temp files. */
MODE_T mask = UMASK (0077); mode_t mask = umask (0077);
#if defined(HAVE_MKSTEMP) || defined(HAVE_MKTEMP) #if defined(HAVE_MKSTEMP) || defined(HAVE_MKTEMP)
# define TEMPLATE_LEN strlen (template) # define TEMPLATE_LEN strlen (template)
@@ -482,7 +490,7 @@ get_tmpfile (char **name, const char *template)
# endif # endif
#endif #endif
UMASK (mask); umask (mask);
return file; return file;
} }

View File

@@ -281,7 +281,7 @@ release_semaphore (void *sem)
int int
output_tmpfd (void) output_tmpfd (void)
{ {
MODE_T mask = UMASK (0077); mode_t mask = umask (0077);
int fd = -1; int fd = -1;
FILE *tfile = tmpfile (); FILE *tfile = tmpfile ();
@@ -297,7 +297,7 @@ output_tmpfd (void)
set_append_mode (fd); set_append_mode (fd);
UMASK (mask); umask (mask);
return fd; return fd;
} }

View File

@@ -1395,14 +1395,7 @@ eval (struct ebuffer *ebuf, int set_default)
} }
} }
} }
continue;
} }
/* We get here except in the case that we just read a rule line.
Record now the last rule we read, so following spurious
commands are properly diagnosed. */
record_waiting_files ();
} }
#undef word1eq #undef word1eq
@@ -2836,9 +2829,9 @@ get_next_mword (char *buffer, char **startp, size_t *length)
/* A word CAN include a colon in its drive spec. The drive /* A word CAN include a colon in its drive spec. The drive
spec is allowed either at the beginning of a word, or as part spec is allowed either at the beginning of a word, or as part
of the archive member name, like in "libfoo.a(d:/foo/bar.o)". */ of the archive member name, like in "libfoo.a(d:/foo/bar.o)". */
if (!(p - beg >= 2 if ((p - beg == 2 || (p - beg > 2 && p[-3] == '('))
&& (*p == '/' || *p == '\\') && isalpha ((unsigned char)p[-2]) && isalpha ((unsigned char)p[-2]))
&& (p - beg == 2 || p[-3] == '('))) break;
#endif #endif
goto done_word; goto done_word;
@@ -3182,7 +3175,7 @@ parse_file_seq (char **stringp, size_t size, int stopmap,
#endif #endif
char *s; char *s;
size_t nlen; size_t nlen;
int i; int tot, i;
/* Skip whitespace; at the end of the string or STOPCHAR we're done. */ /* Skip whitespace; at the end of the string or STOPCHAR we're done. */
NEXT_TOKEN (p); NEXT_TOKEN (p);
@@ -3391,7 +3384,7 @@ parse_file_seq (char **stringp, size_t size, int stopmap,
if (NONE_SET (flags, PARSEFS_EXISTS) && strpbrk (name, "?*[") == NULL) if (NONE_SET (flags, PARSEFS_EXISTS) && strpbrk (name, "?*[") == NULL)
{ {
globme = 0; globme = 0;
i = 1; tot = 1;
nlist = &name; nlist = &name;
} }
else else
@@ -3402,7 +3395,7 @@ parse_file_seq (char **stringp, size_t size, int stopmap,
case 0: case 0:
/* Success. */ /* Success. */
i = gl.gl_pathc; tot = gl.gl_pathc;
nlist = (const char **)gl.gl_pathv; nlist = (const char **)gl.gl_pathv;
break; break;
@@ -3410,20 +3403,20 @@ parse_file_seq (char **stringp, size_t size, int stopmap,
/* If we want only existing items, skip this one. */ /* If we want only existing items, skip this one. */
if (ANY_SET (flags, PARSEFS_EXISTS)) if (ANY_SET (flags, PARSEFS_EXISTS))
{ {
i = 0; tot = 0;
break; break;
} }
/* FALLTHROUGH */ /* FALLTHROUGH */
default: default:
/* By default keep this name. */ /* By default keep this name. */
i = 1; tot = 1;
nlist = &name; nlist = &name;
break; break;
} }
/* For each matched element, add it to the list. */ /* For each matched element, add it to the list. */
while (i-- > 0) for (i = 0; i < tot; ++i)
#ifndef NO_ARCHIVES #ifndef NO_ARCHIVES
if (memname != 0) if (memname != 0)
{ {

View File

@@ -104,11 +104,12 @@ static int ctrlYPressed= 0;
inner mode level AST. inner mode level AST.
*/ */
static int static int
vmsHandleChildTerm (struct child *child) vmsHandleChildTerm (struct childbase *cbase)
{ {
int exit_code; struct child *child = (struct child*)cbase;
struct child *lastc, *c; struct child *lastc, *c;
int child_failed; int child_failed;
int exit_code;
/* The child efn is 0 when a built-in or null command is executed /* The child efn is 0 when a built-in or null command is executed
successfully with out actually creating a child. successfully with out actually creating a child.
@@ -803,8 +804,8 @@ build_vms_cmd (char **cmd_tokens,
return cmd_dsc; return cmd_dsc;
} }
int pid_t
child_execute_job (struct child *child, char *argv) child_execute_job (struct childbase *child, int good_stdin UNUSED, char *argv)
{ {
int i; int i;
@@ -841,11 +842,10 @@ child_execute_job (struct child *child, char *argv)
/* Only a built-in or a null command - Still need to run term AST */ /* Only a built-in or a null command - Still need to run term AST */
child->cstatus = VMS_POSIX_EXIT_MASK; child->cstatus = VMS_POSIX_EXIT_MASK;
child->vms_launch_status = SS$_NORMAL; child->vms_launch_status = SS$_NORMAL;
/* TODO what is this "magic number" */
child->pid = 270163; /* Special built-in */
child->efn = 0; child->efn = 0;
vmsHandleChildTerm (child); vmsHandleChildTerm (child);
return 1; /* TODO what is this "magic number" */
return 270163; /* Special built-in */
} }
sprintf (procname, "GMAKE_%05x", getpid () & 0xfffff); sprintf (procname, "GMAKE_%05x", getpid () & 0xfffff);
@@ -1162,11 +1162,9 @@ child_execute_job (struct child *child, char *argv)
free (cmd_tokens[cmd_tkn_index++]); free (cmd_tokens[cmd_tkn_index++]);
child->cstatus = VMS_POSIX_EXIT_MASK | (MAKE_TROUBLE << 3); child->cstatus = VMS_POSIX_EXIT_MASK | (MAKE_TROUBLE << 3);
child->vms_launch_status = SS$_ABORT; child->vms_launch_status = SS$_ABORT;
/* TODO what is this "magic number" */
child->pid = 270163; /* Special built-in */
child->efn = 0; child->efn = 0;
errno = token.cmd_errno; errno = token.cmd_errno;
return 0; return -1;
} }
/* Save any redirection to append file */ /* Save any redirection to append file */
@@ -1206,21 +1204,18 @@ child_execute_job (struct child *child, char *argv)
free (cmd_dsc); free (cmd_dsc);
child->cstatus = VMS_POSIX_EXIT_MASK | (MAKE_TROUBLE << 3); child->cstatus = VMS_POSIX_EXIT_MASK | (MAKE_TROUBLE << 3);
child->vms_launch_status = SS$_ABORT; child->vms_launch_status = SS$_ABORT;
/* TODO what is this "magic number" */
child->pid = 270163; /* Special built-in */
child->efn = 0; child->efn = 0;
return 0; return -1;
} }
/* Only a built-in or a null command - Still need to run term AST */ /* Only a built-in or a null command - Still need to run term AST */
free (cmd_dsc); free (cmd_dsc);
child->cstatus = VMS_POSIX_EXIT_MASK; child->cstatus = VMS_POSIX_EXIT_MASK;
child->vms_launch_status = SS$_NORMAL; child->vms_launch_status = SS$_NORMAL;
/* TODO what is this "magic number" */
child->pid = 270163; /* Special built-in */
child->efn = 0; child->efn = 0;
vmsHandleChildTerm (child); vmsHandleChildTerm (child);
return 1; /* TODO what is this "magic number" */
return 270163; /* Special built-in */
} }
if (cmd_dsc->dsc$w_length > MAX_DCL_LINE_LENGTH) if (cmd_dsc->dsc$w_length > MAX_DCL_LINE_LENGTH)
@@ -1339,7 +1334,7 @@ child_execute_job (struct child *child, char *argv)
unlink (child->comname); unlink (child->comname);
free (child->comname); free (child->comname);
} }
return 0; return -1;
} }
} }
@@ -1465,5 +1460,6 @@ child_execute_job (struct child *child, char *argv)
} }
} }
return (status & 1); /* TODO what is this "magic number" */
return (status & 1) ? 270163 : -1 ;
} }

View File

@@ -135,6 +135,13 @@ readdir(DIR* pDir)
pDir->dir_sdReturn.d_ino = (ino_t)-1; pDir->dir_sdReturn.d_ino = (ino_t)-1;
strcpy(pDir->dir_sdReturn.d_name, wfdFindData.cFileName); strcpy(pDir->dir_sdReturn.d_name, wfdFindData.cFileName);
if (wfdFindData.dwFileAttributes & FILE_ATTRIBUTE_DEVICE)
pDir->dir_sdReturn.d_type = DT_CHR;
else if (wfdFindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
pDir->dir_sdReturn.d_type = DT_DIR;
else
pDir->dir_sdReturn.d_type = DT_REG;
return &pDir->dir_sdReturn; return &pDir->dir_sdReturn;
} }

View File

@@ -33,20 +33,46 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#define __DIRENT_COOKIE 0xfefeabab #define __DIRENT_COOKIE 0xfefeabab
/* File types for `d_type'.
Windows only supports DT_CHR, DT_DIR, and DT_REG. */
enum
{
DT_UNKNOWN = 0,
# define DT_UNKNOWN DT_UNKNOWN
DT_FIFO = 1,
# define DT_FIFO DT_FIFO
DT_CHR = 2,
# define DT_CHR DT_CHR
DT_DIR = 4,
# define DT_DIR DT_DIR
DT_BLK = 6,
# define DT_BLK DT_BLK
DT_REG = 8,
# define DT_REG DT_REG
DT_LNK = 10,
# define DT_LNK DT_LNK
DT_SOCK = 12,
# define DT_SOCK DT_SOCK
DT_WHT = 14
# define DT_WHT DT_WHT
};
struct dirent struct dirent
{ {
ino_t d_ino; /* unused - no equivalent on WINDOWS32 */ ino_t d_ino; /* unused - no equivalent on WINDOWS32. */
char d_name[NAME_MAX+1]; unsigned char d_type;
}; char d_name[NAME_MAX+1]; /* must come last due to dir.c assumptions. */
};
typedef struct dir_struct { typedef struct dir_struct
ULONG dir_ulCookie; {
HANDLE dir_hDirHandle; ULONG dir_ulCookie;
DWORD dir_nNumFiles; HANDLE dir_hDirHandle;
char dir_pDirectoryName[NAME_MAX+1]; DWORD dir_nNumFiles;
struct dirent dir_sdReturn; char dir_pDirectoryName[NAME_MAX+1];
} DIR; struct dirent dir_sdReturn;
} DIR;
DIR *opendir(const char *); DIR *opendir(const char *);
struct dirent *readdir(DIR *); struct dirent *readdir(DIR *);

View File

@@ -108,7 +108,7 @@ DWORD process_wait_for_multiple_objects(
continue; continue;
break; break;
case WAIT_FAILED: case WAIT_FAILED:
fprintf(stderr,"WaitForMultipleOjbects failed waiting with error %d\n", GetLastError()); fprintf(stderr,"WaitForMultipleOjbects failed waiting with error %lu\n", GetLastError());
break; break;
default: default:
if (retVal >= WAIT_ABANDONED_0) { if (retVal >= WAIT_ABANDONED_0) {

View File

@@ -4,16 +4,17 @@
# during the tests. # during the tests.
%CONFIG_FLAGS = ( %CONFIG_FLAGS = (
AM_LDFLAGS => '@AM_LDFLAGS@', AM_LDFLAGS => '@AM_LDFLAGS@',
AR => '@AR@', AR => '@AR@',
CC => '@CC@', CC => '@CC@',
CFLAGS => '@CFLAGS@', CFLAGS => '@CFLAGS@',
CPP => '@CPP@', CPP => '@CPP@',
CPPFLAGS => '@CPPFLAGS@', CPPFLAGS => '@CPPFLAGS@',
GUILE_CFLAGS => '@GUILE_CFLAGS@', GUILE_CFLAGS => '@GUILE_CFLAGS@',
GUILE_LIBS => '@GUILE_LIBS@', GUILE_LIBS => '@GUILE_LIBS@',
LDFLAGS => '@LDFLAGS@', LDFLAGS => '@LDFLAGS@',
LIBS => '@LIBS@' LIBS => '@LIBS@',
USE_SYSTEM_GLOB => '@USE_SYSTEM_GLOB@'
); );
1; 1;

View File

@@ -24,7 +24,7 @@ $ open/read cfpm_in config-flags.pm.in
$! $!
$ outfile = "sys$disk:[]config-flags.pm" $ outfile = "sys$disk:[]config-flags.pm"
$! $!
$ cflags = "/include=([],[.glob]" $ cflags = "/include=([],[.lib]"
$! $!
$ create 'outfile' $ create 'outfile'
$ open/append cfpm 'outfile' $ open/append cfpm 'outfile'
@@ -42,6 +42,7 @@ $ if key .eqs. "CC" then value = "CC"
$ if key .eqs. "CPP" then value = "CPP" $ if key .eqs. "CPP" then value = "CPP"
$ if key .eqs. "CFLAGS" then value = cflags $ if key .eqs. "CFLAGS" then value = cflags
$ if key .eqs. "GUILE_CFLAGS" then value = cflags $ if key .eqs. "GUILE_CFLAGS" then value = cflags
$ if key .eqs. "USE_SYSTEM_GLOB" then value = "no"
$ write cfpm part1, value, part2 $ write cfpm part1, value, part2
$ goto cfpm_read_loop $ goto cfpm_read_loop
$ endif $ endif

View File

@@ -27,6 +27,21 @@
# You should have received a copy of the GNU General Public License along with # 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 <http://www.gnu.org/licenses/>.
# Add the working directory to @INC and load the test driver
use FindBin;
use lib "$FindBin::Bin";
require "test_driver.pl";
use File::Spec::Functions qw(:DEFAULT splitdir splitpath catpath);
use Cwd;
$cwdpath = cwd();
($cwdvol, $cwddir, $_) = splitpath($cwdpath, 1);
# Some target systems might not have the POSIX module...
$has_POSIX = eval { require "POSIX.pm" };
%FEATURES = (); %FEATURES = ();
$valgrind = 0; # invoke make with valgrind $valgrind = 0; # invoke make with valgrind
@@ -36,7 +51,12 @@ $massif_args = '--num-callers=15 --tool=massif --alloc-fn=xmalloc --alloc-fn=xca
$pure_log = undef; $pure_log = undef;
# The location of the GNU make source directory # The location of the GNU make source directory
$srcdir = ''; $srcdir = undef;
$srcvol = undef;
# The location of the build directory
$blddir = undef;
$bldvol = undef;
$command_string = ''; $command_string = '';
@@ -67,24 +87,71 @@ if ($^O eq 'VMS')
$CMD_rmfile = 'delete_file -no_ask'; $CMD_rmfile = 'delete_file -no_ask';
} }
use FindBin;
use lib "$FindBin::Bin";
require "test_driver.pl";
%CONFIG_FLAGS = (); %CONFIG_FLAGS = ();
my $statnm = "$FindBin::Bin/../config.status"; # Find the strings that will be generated for various error codes.
if (open(my $fh, '<', $statnm)) { # We want them from the C locale regardless of our current locale.
while (my $line = <$fh>) {
$line =~ m/^[SD]\["([^\"]+)"\]=" *(.*)"/ and $CONFIG_FLAGS{$1} = $2;
}
} else {
warn "Failed to open $statnm: $!";
}
# Some target systems might not have the POSIX module... $ERR_no_such_file = undef;
$has_POSIX = eval { require "POSIX.pm" }; $ERR_read_only_file = undef;
$ERR_unreadable_file = undef;
$ERR_noexe_file = undef;
$ERR_exe_dir = 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');
}
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>/dev/null`;
if ($? == 0) {
print "Executed non-executable file! Skipping related tests.\n";
} else {
$ERR_nonexe_file = "$!";
}
$_ = `./. 2>/dev/null`;
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";
$loc and POSIX::setlocale(&POSIX::LC_ALL, $loc);
}
#$SIG{INT} = sub { print STDERR "Caught a signal!\n"; die @_; }; #$SIG{INT} = sub { print STDERR "Caught a signal!\n"; die @_; };
@@ -103,7 +170,7 @@ sub valid_option
if ($option =~ /^-srcdir$/i) { if ($option =~ /^-srcdir$/i) {
$srcdir = shift @argv; $srcdir = shift @argv;
if (! -f "$srcdir/src/gnumake.h") { if (! -f catfile($srcdir, 'src', 'gnumake.h')) {
print "$option $srcdir: Not a valid GNU make source directory.\n"; print "$option $srcdir: Not a valid GNU make source directory.\n";
exit 0; exit 0;
} }
@@ -155,7 +222,7 @@ sub subst_make_string
s/#MAKEPATH#/$mkpath/g; s/#MAKEPATH#/$mkpath/g;
s/#MAKE#/$make_name/g; s/#MAKE#/$make_name/g;
s/#PERL#/$perl_name/g; s/#PERL#/$perl_name/g;
s/#PWD#/$pwd/g; s/#PWD#/$cwdpath/g;
return $_; return $_;
} }
@@ -170,7 +237,7 @@ sub run_make_test
if (! defined $makestring) { if (! defined $makestring) {
defined $old_makefile defined $old_makefile
|| die "run_make_test(undef) invoked before run_make_test('...')\n"; or die "run_make_test(undef) invoked before run_make_test('...')\n";
$makefile = $old_makefile; $makefile = $old_makefile;
} else { } else {
if (! defined($makefile)) { if (! defined($makefile)) {
@@ -182,9 +249,9 @@ sub run_make_test
$makestring = subst_make_string($makestring); $makestring = subst_make_string($makestring);
# Populate the makefile! # Populate the makefile!
open(MAKEFILE, "> $makefile") || die "Failed to open $makefile: $!\n"; open(MAKEFILE, "> $makefile") or die "Failed to open $makefile: $!\n";
print MAKEFILE $makestring; print MAKEFILE $makestring;
close(MAKEFILE) || die "Failed to write $makefile: $!\n"; close(MAKEFILE) or die "Failed to write $makefile: $!\n";
} }
# Do the same processing on $answer as we did on $makestring. # Do the same processing on $answer as we did on $makestring.
@@ -317,8 +384,7 @@ sub run_make_with_options {
# If we have a purify log, save it # If we have a purify log, save it
$tn = $pure_testname . ($num_of_logfiles ? ".$num_of_logfiles" : ""); $tn = $pure_testname . ($num_of_logfiles ? ".$num_of_logfiles" : "");
print("Renaming purify log file to $tn\n") if $debug; print("Renaming purify log file to $tn\n") if $debug;
rename($pure_log, "$tn") rename($pure_log, "$tn") or die "Can't rename $log to $tn: $!\n";
|| die "Can't rename $log to $tn: $!\n";
++$purify_errors; ++$purify_errors;
} else { } else {
unlink($pure_log); unlink($pure_log);
@@ -363,168 +429,227 @@ sub print_help
"\tRun the test suite under valgrind's memcheck tool.", "\tRun the test suite under valgrind's memcheck tool.",
"\tChange the default valgrind args with the VALGRIND_ARGS env var.", "\tChange the default valgrind args with the VALGRIND_ARGS env var.",
"-massif", "-massif",
"\tRun the test suite under valgrind's massif toool.", "\tRun the test suite under valgrind's massif tool.",
"\tChange the default valgrind args with the VALGRIND_ARGS env var." "\tChange the default valgrind args with the VALGRIND_ARGS env var."
); );
} }
sub get_this_pwd {
if ($has_POSIX) {
$__pwd = POSIX::getcwd();
} elsif ($vos) {
$__pwd = `++(current_dir)`;
} else {
# No idea... just try using pwd as a last resort.
chop ($__pwd = `pwd`);
}
return $__pwd;
}
sub set_defaults sub set_defaults
{ {
# $profile = 1; # $profile = 1;
$testee = "GNU make"; $testee = "GNU make";
$make_path = "make"; $make_path = "make";
$tmpfilesuffix = "mk"; $tmpfilesuffix = "mk";
$pwd = &get_this_pwd; if ($port_type eq 'UNIX') {
$scriptsuffix = '.sh';
} elsif ($port_type eq 'VMS') {
$scriptsuffix = '.com';
} else {
$scriptsuffix = '.bat';
}
}
# This is no longer used: we import config-flags.pm instead
# sub parse_status
# {
# if (open(my $fh, '<', "$_[0]/config.status")) {
# while (my $line = <$fh>) {
# $line =~ m/^[SD]\["([^\"]+)"\]=" *(.*)"/ and $CONFIG_FLAGS{$1} = $2;
# }
# return 1;
# }
# return 0;
# }
sub find_prog
{
my $prog = $_[0];
my ($v, $d, $f) = splitpath($prog);
# If there's no directory then we need to search the PATH
if (! $d) {
foreach my $e (path()) {
$prog = catfile($e, $f);
-x $prog or continue;
($v, $d, $f) = splitpath($prog);
last;
}
}
return ($v, $d, $f);
} }
sub set_more_defaults sub set_more_defaults
{ {
local($string); local($string);
local($index); local($index);
# On DOS/Windows system the filesystem apparently can't track # Now that we have located make_path, locate the srcdir and blddir
# timestamps with second granularity (!!). Change the sleep time my ($mpv, $mpd, $mpf) = find_prog($make_path);
# needed to force a file to be considered "old".
$wtime = $port_type eq 'UNIX' ? 1 : $port_type eq 'OS/2' ? 2 : 4;
# Find the full pathname of Make. For DOS systems this is more # We have a make program so try to compute the blddir.
# complicated, so we ask make itself. if ($mpd) {
if ($osname eq 'VMS') { my $f = catpath($mpv, catdir($mpd, 'tests'), 'config-flags.pm');
$port_type = 'VMS-DCL' unless defined $ENV{"SHELL"}; if (-f $f) {
# On VMS pre-setup make to be found with simply 'make'. $bldvol = $mpv;
$make_path = 'make'; $blddir = $mpd;
} else { }
create_file('make.mk', 'all:;$(info $(MAKE))'); }
my $mk = `$make_path -sf make.mk`;
unlink('make.mk');
chop $mk;
$mk or die "FATAL ERROR: Cannot determine the value of \$(MAKE)\n";
$make_path = $mk;
}
# Ask make what shell to use # If srcdir wasn't provided on the command line, try to find it.
create_file('shell.mk', 'all:;$(info $(SHELL))'); if (! $srcdir && $blddir) {
$sh_name = `$make_path -sf shell.mk`; # See if the blddir is the srcdir
unlink('shell.mk'); my $f = catpath($bldvol, catdir($blddir, 'src'), 'gnumake.h');
chop $sh_name; if (-f $f) {
if (! $sh_name) { $srcdir = $blddir;
print "Cannot determine shell\n"; $srcvol = $bldvol;
$is_posix_sh = 0; }
} else { }
my $o = `$sh_name -c ': do nothing' 2>&1`;
$is_posix_sh = $? == 0 && $o == '';
}
$string = `$make_path -v`; if (! $srcdir) {
$string =~ /^(GNU Make [^,\n]*)/ or die "$make_path is not GNU make. Version:\n$string"; # Not found, see if our parent is the source dir
$testee_version = "$1\n"; my $f = catpath($cwdvol, catdir(updir(), 'src'), 'gnumake.h');
if (-f $f) {
$srcdir = updir();
$srcvol = $cwdvol;
}
}
create_file('null.mk', ''); # If we have srcdir but not blddir, set them equal
if ($srcdir && !$blddir) {
$blddir = $srcdir;
$bldvol = $srcvol;
}
my $redir = '2>&1'; # Load the config flags
$redir = '' if os_name eq 'VMS'; if (!$blddir) {
$string = `sh -c "$make_path -f null.mk $redir"`; warn "Cannot locate config-flags.pm (no blddir)\n";
if ($string =~ /(.*): \*\*\* No targets\. Stop\./) { } else {
$make_name = $1; my $f = catpath($bldvol, catdir($blddir, 'tests'), 'config-flags.pm');
} if (! -f $f) {
else { warn "Cannot locate $f\n";
$make_path =~ /^(?:.*$pathsep)?(.+)$/; } else {
$make_name = $1; unshift(@INC, catpath($bldvol, catdir($blddir, 'tests'), ''));
} require "config-flags.pm";
}
}
# prepend pwd if this is a relative path (ie, does not # On DOS/Windows system the filesystem apparently can't track
# start with a slash, but contains one). Thanks for the # timestamps with second granularity (!!). Change the sleep time
# clue, Roland. # needed to force a file to be considered "old".
$wtime = $port_type eq 'UNIX' ? 1 : $port_type eq 'OS/2' ? 2 : 4;
if (index ($make_path, ":") != 1 && index ($make_path, "/") > 0) # Find the full pathname of Make. For DOS systems this is more
{ # complicated, so we ask make itself.
$mkpath = "$pwd$pathsep$make_path"; if ($osname eq 'VMS') {
} $port_type = 'VMS-DCL' unless defined $ENV{"SHELL"};
else # On VMS pre-setup make to be found with simply 'make'.
{ $make_path = 'make';
$mkpath = $make_path; } else {
} create_file('make.mk', 'all:;$(info $(MAKE))');
my $mk = `$make_path -sf make.mk`;
unlink('make.mk');
chop $mk;
$mk or die "FATAL ERROR: Cannot determine the value of \$(MAKE)\n";
$make_path = $mk;
}
($mpv, $mpd, $mpf) = splitpath($make_path);
# If srcdir wasn't provided on the command line, see if the # Ask make what shell to use
# location of the make program gives us a clue. Don't fail if not; create_file('shell.mk', 'all:;$(info $(SHELL))');
# we'll assume it's been installed into /usr/include or wherever. $sh_name = `$make_path -sf shell.mk`;
if (! $srcdir) { unlink('shell.mk');
$make_path =~ /^(.*$pathsep)?/; chop $sh_name;
my $d = $1 || '../'; if (! $sh_name) {
-f "${d}/src/gnumake.h" and $srcdir = $d; print "Cannot determine shell\n";
} $is_posix_sh = 0;
} else {
my $o = `$sh_name -c ': do nothing' 2>&1`;
$is_posix_sh = $? == 0 && $o eq '';
}
# Not with the make program, so see if we can get it out of the makefile $string = `$make_path -v`;
if (! $srcdir && open(MF, "< ../Makefile")) { $string =~ /^(GNU Make [^,\n]*)/ or die "$make_path is not GNU make. Version:\n$string";
local $/ = undef; $testee_version = "$1\n";
$_ = <MF>;
close(MF);
/^abs_srcdir\s*=\s*(.*?)\s*$/m;
-f "$1/src/gnumake.h" and $srcdir = $1;
}
# Get Purify log info--if any. create_file('null.mk', '');
if (exists $ENV{PURIFYOPTIONS} my $redir = '2>&1';
&& $ENV{PURIFYOPTIONS} =~ /.*-logfile=([^ ]+)/) { $redir = '' if os_name eq 'VMS';
$pure_log = $1 || ''; $string = `$make_path -f null.mk $redir`;
$pure_log =~ s/%v/$make_name/; if ($string =~ /(.*): \*\*\* No targets\. Stop\./) {
$purify_errors = 0; $make_name = $1;
} } else {
$make_name = $mpf;
}
$string = `sh -c "$make_path -j 2 -f null.mk $redir"`; # prepend pwd if this is a relative path (ie, does not
if ($string =~ /not supported/) { # start with a slash, but contains one). Thanks for the
$parallel_jobs = 0; # clue, Roland.
}
else {
$parallel_jobs = 1;
}
unlink('null.mk'); if ($mpd && !file_name_is_absolute($make_path) && $cwdvol == $mpv) {
$mkpath = catpath($cwdvol, catdir($cwd, $mpd), $mpf);
} else {
$mkpath = $make_path;
}
create_file('features.mk', 'all:;$(info $(.FEATURES))'); # Not with the make program, so see if we can get it out of the makefile
%FEATURES = map { $_ => 1 } split /\s+/, `$make_path -sf features.mk`; if (! $srcdir && open(MF, '<', catfile(updir(), 'Makefile'))) {
unlink('features.mk'); local $/ = undef;
$_ = <MF>;
close(MF);
/^abs_srcdir\s*=\s*(.*?)\s*$/m;
-f catfile($1, 'src', 'gnumake.h') and $srcdir = $1;
}
# Set up for valgrind, if requested. # Get Purify log info--if any.
$make_command = $make_path; if (exists $ENV{PURIFYOPTIONS}
&& $ENV{PURIFYOPTIONS} =~ /.*-logfile=([^ ]+)/) {
$pure_log = $1 || '';
$pure_log =~ s/%v/$make_name/;
$purify_errors = 0;
}
if ($valgrind) { $string = `$make_path -j 2 -f null.mk $redir`;
my $args = $valgrind_args; if ($string =~ /not supported/) {
open(VALGRIND, "> valgrind.out") $parallel_jobs = 0;
|| die "Cannot open valgrind.out: $!\n"; }
# -q --leak-check=yes else {
exists $ENV{VALGRIND_ARGS} and $args = $ENV{VALGRIND_ARGS}; $parallel_jobs = 1;
$make_path = "valgrind --log-fd=".fileno(VALGRIND)." $args $make_path"; }
# F_SETFD is 2
fcntl(VALGRIND, 2, 0) or die "fcntl(setfd) failed: $!\n";
system("echo Starting on `date` 1>&".fileno(VALGRIND));
print "Enabled valgrind support.\n";
}
if ($debug) { unlink('null.mk');
print "Port type: $port_type\n";
print "Make path: $make_path\n"; create_file('features.mk', 'all:;$(info $(.FEATURES))');
print "Shell path: $sh_name".($is_posix_sh ? ' (POSIX)' : '')."\n"; %FEATURES = map { $_ => 1 } split /\s+/, `$make_path -sf features.mk`;
print "#PWD#: $pwd\n"; unlink('features.mk');
print "#PERL#: $perl_name\n";
print "#MAKEPATH#: $mkpath\n"; # Set up for valgrind, if requested.
print "#MAKE#: $make_name\n";
} $make_command = $make_path;
if ($valgrind) {
my $args = $valgrind_args;
open(VALGRIND, "> valgrind.out") or die "Cannot open valgrind.out: $!\n";
# -q --leak-check=yes
exists $ENV{VALGRIND_ARGS} and $args = $ENV{VALGRIND_ARGS};
$make_path = "valgrind --log-fd=".fileno(VALGRIND)." $args $make_path";
# F_SETFD is 2
fcntl(VALGRIND, 2, 0) or die "fcntl(setfd) failed: $!\n";
system("echo Starting on `date` 1>&".fileno(VALGRIND));
print "Enabled valgrind support.\n";
}
if ($debug) {
print "Port type: $port_type\n";
print "Make path: $make_path\n";
print "Shell path: $sh_name".($is_posix_sh ? ' (POSIX)' : '')."\n";
print "#PWD#: $cwdpath\n";
print "#PERL#: $perl_name\n";
print "#MAKEPATH#: $mkpath\n";
print "#MAKE#: $make_name\n";
}
} }
sub setup_for_test sub setup_for_test

View File

@@ -14,8 +14,6 @@ $port_type eq 'W32' and return -1;
# Create some .o files to work with # Create some .o files to work with
if ($osname eq 'VMS') { if ($osname eq 'VMS') {
use Cwd;
my $pwd = getcwd;
# VMS AR needs real object files at this time. # VMS AR needs real object files at this time.
foreach $afile ('a1', 'a2', 'a3') { foreach $afile ('a1', 'a2', 'a3') {
# Use non-standard extension to prevent implicit rules from recreating # Use non-standard extension to prevent implicit rules from recreating
@@ -56,6 +54,7 @@ if ($? == 0) {
# Some versions of ar print different things on creation. Find out. # Some versions of ar print different things on creation. Find out.
unlink('libxx.a'); unlink('libxx.a');
my $created = `$ar $arflags libxx.a a1.o $redir`; my $created = `$ar $arflags libxx.a a1.o $redir`;
$created =~ s/a1\.o/#OBJECT#/g;
# Some versions of ar print different things on add. Find out. # Some versions of ar print different things on add. Find out.
my $add = `$ar $arflags libxx.a a2.o $redir`; my $add = `$ar $arflags libxx.a a2.o $redir`;
@@ -68,7 +67,8 @@ $repl =~ s/a2\.o/#OBJECT#/g;
unlink('libxx.a'); unlink('libxx.a');
# Very simple # Very simple
my $answer = "$ar $arflags libxx.a a1.o\n$created"; ($_ = $created) =~ s/#OBJECT#/a1.o/g;
my $answer = "$ar $arflags libxx.a a1.o\n$_";
if ($port_type eq 'VMS-DCL') { if ($port_type eq 'VMS-DCL') {
$answer = 'library /replace libxx.a a1.o'; $answer = 'library /replace libxx.a a1.o';
} }
@@ -208,7 +208,7 @@ run_make_test(undef, $arvar, "#MAKE#: Nothing to be done for 'default'.\n");
unlink('foo.vhd'); unlink('foo.vhd');
if ($osname eq 'VMS') { if ($osname eq 'VMS') {
remove_directory_tree("$pwd/artest"); remove_directory_tree("$cwdpath/artest");
} else { } else {
remove_directory_tree('artest'); remove_directory_tree('artest');
} }
@@ -220,7 +220,9 @@ if ($osname ne 'VMS') {
my $pre = '1234567890123456'; my $pre = '1234567890123456';
my $lib = 'libxx.a'; my $lib = 'libxx.a';
my $cr = $created; my $cr = $created;
$cr =~ s#a1\.o#${pre}a#; $cr =~ s/#OBJECT#/${pre}a/g;
my $ad = $add;
$ad =~ s/#OBJECT#/${pre}b/g;
run_make_test(qq! run_make_test(qq!
# Both member names > 16 characters long # Both member names > 16 characters long
@@ -230,7 +232,7 @@ default: $lib(${pre}a) $lib(${pre}b)
$pre%: ; touch \$\@ $pre%: ; touch \$\@
!, !,
$arvar, "touch ${pre}a\n$ar $arflags $lib ${pre}a\n${cr}touch ${pre}b\n$ar $arflags $lib ${pre}b\na - ${pre}b\nrm ${pre}a ${pre}b\n"); $arvar, "touch ${pre}a\n$ar $arflags $lib ${pre}a\n${cr}touch ${pre}b\n$ar $arflags $lib ${pre}b\n${ad}rm ${pre}a ${pre}b\n");
# Run it again; nothing should happen # Run it again; nothing should happen
run_make_test(undef, $arvar, "#MAKE#: Nothing to be done for 'default'.\n"); run_make_test(undef, $arvar, "#MAKE#: Nothing to be done for 'default'.\n");

View File

@@ -60,15 +60,36 @@ run_make_test(undef, 'two',
# Try failing due to non-executable file # Try failing due to non-executable file
my $noexe = './barfooblatboz'; if ($ERR_nonexe_file) {
touch($noexe); my $noexe = './barfooblatboz';
touch($noexe);
run_make_test(qq! run_make_test(qq!
one: ; -$noexe xx yy one: ; -$noexe xx yy
two: ; $noexe aa bb two: ; $noexe aa bb
!,
'one', "$noexe xx yy\n#MAKE#: $noexe: $ERR_nonexe_file\n#MAKE#: [#MAKEFILE#;2: one] Error 127 (ignored)\n");
unlink($noexe);
}
# Try failing by "running" a directory
if ($ERR_exe_dir) {
mkdir('sd', 0775);
run_make_test(q!
PATH := .
all: ; sd
!, !,
'one', "$noexe xx yy\n#MAKE#: $noexe: Permission denied\n#MAKE#: [#MAKEFILE#;2: one] Error 127 (ignored)\n"); '', "sd\n#MAKE#: sd: $ERR_exe_dir\n#MAKE#: *** [#MAKEFILE#;3: all] Error 127", 512);
unlink($noexe); run_make_test(q!
all: ; ./sd
!,
'', "./sd\n#MAKE#: ./sd: $ERR_exe_dir\n#MAKE#: *** [#MAKEFILE#;2: all] Error 127", 512);
rmdir('sd');
}
1; 1;

View File

@@ -9,7 +9,7 @@ $details = "Here we test for requirements like\n"
run_make_test(q{ run_make_test(q{
.PHONY: all .PHONY: all
&:; &:;
all: ;@echo -n all: ;@printf ''
}, },
'', ""); '', "");

View File

@@ -55,7 +55,7 @@ include $(F)',
# Now try with the file we're not updating being the actual file we're # Now try with the file we're not updating being the actual file we're
# including: this and the previous one test different parts of the code. # including: this and the previous one test different parts of the code.
run_make_test(undef, 'F=b', "[ -f b ] || echo >> b\nhello\n") run_make_test(undef, 'F=b', "[ -f b ] || echo >> b\nhello\n");
&rmfiles('a','b','c'); &rmfiles('a','b','c');

View File

@@ -255,6 +255,32 @@ a: ; @echo $(A)
!, !,
'', "hello; world\n"); '', "hello; world\n");
# TEST #21: SV-56834 Ensure setting PATH in a target var works properly
my $sname = "foobar$scriptsuffix";
mkdir('sd', 0775);
create_file("sd/$sname", "exit 0\n");
chmod 0755, "sd/$sname";
run_make_test(qq!
all: PATH := sd
all: ; $sname >/dev/null
!,
'', "$sname >/dev/null\n");
# Don't use the general PATH if not found on the target path
$extraENV{PATH} = "$ENV{PATH}:sd";
run_make_test(qq!
all: PATH := ..
all: ; $sname
!,
'', "$sname\n#MAKE#: $sname: $ERR_no_such_file\n#MAKE#: *** [#MAKEFILE#;3: all] Error 127", 512);
unlink("sd/$sname");
rmdir ('sd');
# TEST #19: Test define/endef variables as target-specific vars # TEST #19: Test define/endef variables as target-specific vars
# run_make_test(' # run_make_test('

View File

@@ -13,10 +13,10 @@ open(MAKEFILE,"> $makefile");
# The Contents of the MAKEFILE ... # The Contents of the MAKEFILE ...
print MAKEFILE "VPATH = $workdir:$sourcedir\n"; print MAKEFILE "VPATH = $workdir:$scriptdir\n";
print MAKEFILE "vpath %.c foo\n"; print MAKEFILE "vpath %.c foo\n";
print MAKEFILE "vpath %.c $workdir\n"; print MAKEFILE "vpath %.c $workdir\n";
print MAKEFILE "vpath %.c $sourcedir\n"; print MAKEFILE "vpath %.c $scriptdir\n";
print MAKEFILE "vpath %.h $workdir\n"; print MAKEFILE "vpath %.h $workdir\n";
print MAKEFILE "vpath %.c\n"; print MAKEFILE "vpath %.c\n";
print MAKEFILE "vpath\n"; print MAKEFILE "vpath\n";

View File

@@ -7,7 +7,7 @@ $details = "This is a test of the foreach function in gnu make.
This function starts with a space separated list of This function starts with a space separated list of
names and a variable. Each name in the list is subsituted names and a variable. Each name in the list is subsituted
into the variable and the given text evaluated. The general into the variable and the given text evaluated. The general
form of the command is $(foreach var,$list,$text). Several form of the command is $(foreach var,\$list,\$text). Several
types of foreach loops are tested\n"; types of foreach loops are tested\n";

View File

@@ -13,52 +13,33 @@ test echo's all files which match '?.example' and
[a-z0-9].example. Lastly we clean up all of the files using [a-z0-9].example. Lastly we clean up all of the files using
the '*' wildcard as in the first test"; the '*' wildcard as in the first test";
open(MAKEFILE,"> $makefile"); touch("example.1");
touch("example.two");
# The Contents of the MAKEFILE ... touch("example.3");
touch("example.for");
print MAKEFILE <<EOM; touch("example._");
.PHONY: print1 print2 clean
print1: ;\@echo \$(sort \$(wildcard example.*))
print2:
\t\@echo \$(sort \$(wildcard example.?))
\t\@echo \$(sort \$(wildcard example.[a-z0-9]))
\t\@echo \$(sort \$(wildcard example.[!A-Za-z_\\!]))
clean:
\t$CMD_rmfile \$(sort \$(wildcard example.*))
EOM
# END of Contents of MAKEFILE
close(MAKEFILE);
&touch("example.1");
&touch("example.two");
&touch("example.3");
&touch("example.for");
&touch("example._");
# TEST #1 # TEST #1
# ------- # -------
$answer = "example.1 example.3 example._ example.for example.two\n"; run_make_test(qq/
.PHONY: print1 print2 clean
&run_make_with_options($makefile,"print1",&get_logfile); print1: ;\@echo \$(wildcard example.*)
print2:
&compare_output($answer,&get_logfile(1)); \t\@echo \$(wildcard example.?)
\t\@echo \$(wildcard example.[a-z0-9])
\t\@echo \$(wildcard example.[!A-Za-z_\\!])
clean:
\t$CMD_rmfile \$(wildcard example.*)
/,
'print1', "example.1 example.3 example._ example.for example.two\n");
# TEST #2 # TEST #2
# ------- # -------
$answer = "example.1 example.3 example._\n" run_make_test(undef, 'print2', "example.1 example.3 example._\n"
."example.1 example.3\n" ."example.1 example.3\n"
."example.1 example.3\n"; ."example.1 example.3\n");
&run_make_with_options($makefile,"print2",&get_logfile);
&compare_output($answer,&get_logfile(1));
# TEST #3 # TEST #3
# ------- # -------
@@ -73,13 +54,7 @@ else
$answer .= "\n"; $answer .= "\n";
} }
&run_make_with_options($makefile,"clean",&get_logfile); run_make_test(undef, 'clean', $answer);
if ((-f "example.1")||(-f "example.two")||(-f "example.3")||(-f "example.for")) {
$test_passed = 0;
}
&compare_output($answer,&get_logfile(1));
# TEST #4: Verify that failed wildcards don't return the pattern # TEST #4: Verify that failed wildcards don't return the pattern
@@ -92,13 +67,65 @@ all: ; @echo $(wildcard xz--y*.7)
touch('xxx.yyy'); touch('xxx.yyy');
run_make_test(q!exists: ; @echo file=$(wildcard xxx.yyy)!, run_make_test(q!exists: ; @echo file=$(wildcard xxx.yyy)!, '', "file=xxx.yyy\n");
'', "file=xxx.yyy\n");
unlink('xxx.yyy'); unlink('xxx.yyy');
run_make_test(q!exists: ; @echo file=$(wildcard xxx.yyy)!, run_make_test(q!exists: ; @echo file=$(wildcard xxx.yyy)!, '', "file=\n");
'', "file=\n");
# TEST #7: verify that when the input pattern has a trailing slash wildcard
# returns only directories.
# -------
touch("hellof");
mkdir("hellod", 0770);
mkdir("hellod/worldd", 0770);
touch("hellod/worldf");
mkdir("hellod/worldd/kend1", 0770);
mkdir("hellod/worldd/kend2", 0770);
touch("hellod/worldd/kenf1");
touch("hellod/worldd/kenf2");
run_make_test(qq!
print3:
\t\@echo \$(wildcard hello*)
\t\@echo \$(wildcard hello*/)
\t\@echo \$(wildcard hellod/world*)
\t\@echo \$(wildcard hellod/world*/)
\t\@echo \$(wildcard hello* hellod/world*)
\t\@echo \$(wildcard hello*/ hellod/world*/)
\t\@echo \$(wildcard hellod/*)
\t\@echo \$(wildcard hellod/*/)
\t\@echo \$(wildcard */world*)
\t\@echo \$(wildcard */worldd/)
\t\@echo \$(wildcard hellod/*/ken*/)
\t\@echo \$(wildcard hellod/*/ken?[12])
\t\@echo \$(wildcard hellod/*/ken?[12]/)
!, '',
"hellod hellof\n"
."hellod/\n"
."hellod/worldd hellod/worldf\n"
."hellod/worldd/\n"
."hellod hellof hellod/worldd hellod/worldf\n"
."hellod/ hellod/worldd/\n"
."hellod/worldd hellod/worldf\n"
."hellod/worldd/\n"
."hellod/worldd hellod/worldf\n"
."hellod/worldd/\n"
."hellod/worldd/kend1/ hellod/worldd/kend2/\n"
."hellod/worldd/kend1 hellod/worldd/kend2 "
."hellod/worldd/kenf1 hellod/worldd/kenf2\n"
."hellod/worldd/kend1/ hellod/worldd/kend2/\n");
unlink('hellof', 'hellod/worldf', 'hellod/worldd/kenf1', 'hellod/worldd/kenf2');
foreach $d ('hellod/worldd/kend1', 'hellod/worldd/kend2', 'hellod/worldd', 'hellod') {
rmdir($d);
}
if ($port_type ne 'W32') {
# Check wildcard on the root directory
run_make_test('print4: ; @echo $(wildcard /)', '', "/\n");
}
if ($port_type ne 'W32' && eval { symlink("",""); 1 }) { if ($port_type ne 'W32' && eval { symlink("",""); 1 }) {
@@ -116,12 +143,15 @@ if ($port_type ne 'W32' && eval { symlink("",""); 1 }) {
rmdir($dir); rmdir($dir);
# Test for dangling symlinks # Test for dangling symlinks
# This doesn't work with the built-in glob... needs to be updated!
symlink($dir, $lnk); if ($CONFIG_FLAGS{USE_SYSTEM_GLOB} eq 'yes') {
symlink($dir, $lnk);
run_make_test(qq!all: ; \@echo \$(wildcard $lnk)!, '', "$lnk"); run_make_test(qq!all: ; \@echo \$(wildcard $lnk)!, '', "$lnk");
unlink($lnk); unlink($lnk);
}
} }
1; 1;

View File

@@ -139,7 +139,6 @@ sub xlate
s/\\r/\r/g; s/\\r/\r/g;
s/\\t/\t/g; s/\\t/\t/g;
s/\\f/\f/g; s/\\f/\f/g;
s/\\v/\v/g;
s/\\n/\n/g; s/\\n/\n/g;
return $_; return $_;
} }

View File

@@ -79,4 +79,43 @@ all: ; \@echo hi
", ",
'', "hi\n"); '', "hi\n");
# SV-56834 Ensure setting PATH in the makefile works properly
my $sname = "foobar$scriptsuffix";
mkdir('sd', 0775);
create_file("sd/$sname", "exit 0\n");
chmod 0755, "sd/$sname";
run_make_test(qq!
PATH := sd
all: ; $sname >/dev/null
!,
'', "$sname >/dev/null\n");
# Don't use the general PATH if not found on the target path
$extraENV{PATH} = "$ENV{PATH}:sd";
run_make_test(qq!
PATH := ..
all: ; $sname
!,
'', "$sname\n#MAKE#: $sname: $ERR_no_such_file\n#MAKE#: *** [#MAKEFILE#;3: all] Error 127", 512);
unlink("sd/$sname");
rmdir('sd');
# Ensure that local programs are not found if "." is not on the PATH
create_file($sname, '');
chmod 0755, $sname;
run_make_test(qq!
PATH := ..
all: ; $sname
!,
'', "$sname\n#MAKE#: $sname: $ERR_no_such_file\n#MAKE#: *** [#MAKEFILE#;3: all] Error 127", 512);
unlink($sname);
1; 1;

View File

@@ -23,9 +23,11 @@ touch($example);
run_make_with_options("${testname}.mk", "-C $workdir clean", &get_logfile); run_make_with_options("${testname}.mk", "-C $workdir clean", &get_logfile);
use Cwd;
chdir $workdir; chdir $workdir;
$wpath = &get_this_pwd; $wpath = cwd();
chdir $pwd; chdir $cwdpath;
if (-f $example) { if (-f $example) {
$test_passed = 0; $test_passed = 0;
@@ -49,10 +51,6 @@ touch($example);
run_make_with_options("${testname}.mk", "-C $workdir/ clean ext=slash", &get_logfile); run_make_with_options("${testname}.mk", "-C $workdir/ clean ext=slash", &get_logfile);
chdir $workdir;
$wpath = &get_this_pwd;
chdir $pwd;
if (-f $example) { if (-f $example) {
$test_passed = 0; $test_passed = 0;
} }

View File

@@ -50,10 +50,12 @@ $answer = "This is another included makefile\n";
&compare_output($answer,&get_logfile(1)); &compare_output($answer,&get_logfile(1));
$answer = "$mkpath ANOTHER -f $makefile $answer = subst_make_string("$mkpath ANOTHER -f $makefile
${make_name}[1]: Entering directory '$pwd' #MAKE#[1]: Entering directory '#PWD#'
This is another included makefile This is another included makefile
${make_name}[1]: Leaving directory '$pwd'\n"; #MAKE#[1]: Leaving directory '#PWD#'\n");
&run_make_with_options($makefile,"-I $workdir recurse",&get_logfile); &run_make_with_options($makefile,"-I $workdir recurse",&get_logfile);
&compare_output($answer,&get_logfile(1)); &compare_output($answer,&get_logfile(1));
1;

View File

@@ -11,58 +11,57 @@ $details = "Verify that symlink handling with and without -L works properly.";
# check for it explicitly. # check for it explicitly.
if ($port_type eq 'W32' || !( eval { symlink("",""); 1 })) { if ($port_type eq 'W32' || !( eval { symlink("",""); 1 })) {
# This test is N/A # This test is N/A
-1; return -1;
} else {
# Set up a symlink sym -> dep
# We'll make both dep and targ older than sym
$pwd =~ m%/([^/]+)$%;
$dirnm = $1;
&utouch(-10, 'dep');
&utouch(-5, 'targ');
symlink("../$dirnm/dep", 'sym');
# Without -L, nothing should happen
# With -L, it should update targ
run_make_test('targ: sym ; @echo make $@ from $<', '',
"#MAKE#: 'targ' is up to date.");
run_make_test(undef, '-L', "make targ from sym");
# Now update dep; in all cases targ should be out of date.
&touch('dep');
run_make_test(undef, '', "make targ from sym");
run_make_test(undef, '-L', "make targ from sym");
# Now update targ; in all cases targ should be up to date.
&touch('targ');
run_make_test(undef, '', "#MAKE#: 'targ' is up to date.");
run_make_test(undef, '-L', "#MAKE#: 'targ' is up to date.");
# Add in a new link between sym and dep. Be sure it's newer than targ.
sleep(1);
rename('dep', 'dep1');
symlink('dep1', 'dep');
# Without -L, nothing should happen
# With -L, it should update targ
run_make_test(undef, '', "#MAKE#: 'targ' is up to date.");
run_make_test(undef, '-L', "make targ from sym");
rmfiles('targ', 'dep', 'sym', 'dep1');
# Check handling when symlinks point to non-existent files. Without -L we
# should get an error: with -L we should use the timestamp of the symlink.
symlink("../$dirname/dep", 'sym');
run_make_test('targ: sym ; @echo make $@ from $<', '',
"#MAKE#: *** No rule to make target 'sym', needed by 'targ'. Stop.", 512);
run_make_test('targ: sym ; @echo make $@ from $<', '-L',
'make targ from sym');
rmfiles('targ', 'sym');
1;
} }
# Set up a symlink sym -> dep
# We'll make both dep and targ older than sym
&utouch(-10, 'dep');
&utouch(-5, 'targ');
$dirnm = (splitdir($cwddir))[-1];
symlink(catfile(updir(), $dirnm, 'dep'), 'sym');
# Without -L, nothing should happen
# With -L, it should update targ
run_make_test('targ: sym ; @echo make $@ from $<', '',
"#MAKE#: 'targ' is up to date.");
run_make_test(undef, '-L', "make targ from sym");
# Now update dep; in all cases targ should be out of date.
&touch('dep');
run_make_test(undef, '', "make targ from sym");
run_make_test(undef, '-L', "make targ from sym");
# Now update targ; in all cases targ should be up to date.
&touch('targ');
run_make_test(undef, '', "#MAKE#: 'targ' is up to date.");
run_make_test(undef, '-L', "#MAKE#: 'targ' is up to date.");
# Add in a new link between sym and dep. Be sure it's newer than targ.
sleep(1);
rename('dep', 'dep1');
symlink('dep1', 'dep');
# Without -L, nothing should happen
# With -L, it should update targ
run_make_test(undef, '', "#MAKE#: 'targ' is up to date.");
run_make_test(undef, '-L', "make targ from sym");
rmfiles('targ', 'dep', 'sym', 'dep1');
# Check handling when symlinks point to non-existent files. Without -L we
# should get an error: with -L we should use the timestamp of the symlink.
symlink("../$dirnm/dep", 'sym');
run_make_test('targ: sym ; @echo make $@ from $<', '',
"#MAKE#: *** No rule to make target 'sym', needed by 'targ'. Stop.", 512);
run_make_test('targ: sym ; @echo make $@ from $<', '-L',
'make targ from sym');
rmfiles('targ', 'sym');
1;

View File

@@ -1,3 +1,5 @@
# -*-perl-*-
$description = "The following test creates a makefile to override part\n" $description = "The following test creates a makefile to override part\n"
."of one Makefile with Another Makefile with the .DEFAULT\n" ."of one Makefile with Another Makefile with the .DEFAULT\n"
."rule."; ."rule.";
@@ -9,41 +11,21 @@ $details = "This tests the use of the .DEFAULT special target to say that \n"
."defined here but passes the target bar on to another makefile\n" ."defined here but passes the target bar on to another makefile\n"
."which does have the target bar defined.\n"; ."which does have the target bar defined.\n";
$makefile2 = &get_tmpfile; create_file('defsub.mk', q!
bar: ; @echo Executing rule BAR
!);
open(MAKEFILE,"> $makefile"); run_make_test(q!
foo:; @echo Executing rule FOO
# The Contents of the MAKEFILE ... .DEFAULT: ; @$(MAKE) -f defsub.mk $@
!,
'bar',"#MAKE#[1]: Entering directory '#PWD#'\n"
. "Executing rule BAR\n"
. "#MAKE#[1]: Leaving directory '#PWD#'\n");
print MAKEFILE "foo:\n"; unlink('defsub.mk');
print MAKEFILE "\t\@echo Executing rule FOO\n\n";
print MAKEFILE ".DEFAULT:\n";
print MAKEFILE "\t\@\$(MAKE) -f $makefile2 \$\@ \n";
# END of Contents of MAKEFILE
close(MAKEFILE);
open(MAKEFILE,"> $makefile2");
print MAKEFILE "bar:\n";
print MAKEFILE "\t\@echo Executing rule BAR\n\n";
close(MAKEFILE);
&run_make_with_options($makefile,'bar',&get_logfile);
# Create the answer to what should be produced by this Makefile
$answer = "${make_name}[1]: Entering directory '$pwd'\n"
. "Executing rule BAR\n"
. "${make_name}[1]: Leaving directory '$pwd'\n";
# COMPARE RESULTS
&compare_output($answer,&get_logfile(1));
# This tells the test driver that the perl test script executed properly.
1; 1;

View File

@@ -1,20 +1,16 @@
# -*-perl-*- # -*-perl-*-
$description = "This tests the CURDIR varaible."; $description = "This tests the CURDIR variable.";
$details = "Echo CURDIR both with and without -C. Also ensure overrides work."; $details = "Echo CURDIR both with and without -C. Also ensure overrides work.";
open(MAKEFILE,"> $makefile");
print MAKEFILE "all: ; \@echo \$(CURDIR)\n";
close(MAKEFILE);
# TEST #1 # TEST #1
# ------- # -------
&run_make_with_options($makefile,"",&get_logfile); run_make_test(q!
$answer = "$pwd\n"; all: ; @echo $(CURDIR)
&compare_output($answer,&get_logfile(1)); !,
'', "#PWD#\n");
1; 1;

View File

@@ -72,7 +72,7 @@ $answer = ".x\n$dir/foo.x\nx\n\$@.x\n$dir.x\nfoo.x\n$dir/bar.x\nbar.x\n";
&compare_output($answer, &get_logfile(1)); &compare_output($answer, &get_logfile(1));
&run_make_with_options($makefile2, "$dir/x.z $dir/y.z", &get_logfile); &run_make_with_options($makefile2, "$dir/x.z $dir/y.z", &get_logfile);
$answer = ".x\n$dir/x.z.x\nx\n\$@.x\n$dir.x\nx.z.x\n.y\n$dir/y.z.y\n\y\n\$@.y\n$dir.y\ny.z.y\n"; $answer = ".x\n$dir/x.z.x\nx\n\$@.x\n$dir.x\nx.z.x\n.y\n$dir/y.z.y\ny\n\$@.y\n$dir.y\ny.z.y\n";
&compare_output($answer, &get_logfile(1)); &compare_output($answer, &get_logfile(1));
&run_make_with_options($makefile2, "$dir/biz", &get_logfile); &run_make_with_options($makefile2, "$dir/biz", &get_logfile);

View File

@@ -25,7 +25,7 @@ $mk_string = "text : text.tlb(file1.txt)\n\n" .
"file1.txt :\n" . "file1.txt :\n" .
"\t\@pipe open/write xxx file1.txt ; write xxx \"text file\" ; close xxx\n"; "\t\@pipe open/write xxx file1.txt ; write xxx \"text file\" ; close xxx\n";
my $answer = "library /replace text.tlb file1.txt"; $answer = "library /replace text.tlb file1.txt";
run_make_test($mk_string, run_make_test($mk_string,
'', $answer); '', $answer);
@@ -37,10 +37,10 @@ unlink('file1.txt');
#Macro library #Macro library
$mk_string = "macro : macro.mlb(file1.mar)\n\n" . $mk_string = "macro : macro.mlb(file1.mar)\n\n" .
"file1.mar :\n" . "file1.mar :\n" .
"\t\pipe open/write xxx file1.mar ; " . "\tpipe open/write xxx file1.mar ; " .
"write xxx \".macro a b\" ; write xxx \".endm\" ; close xxx\n"; "write xxx \".macro a b\" ; write xxx \".endm\" ; close xxx\n";
my $answer = "library /replace macro.mlb file1.mar"; $answer = "library /replace macro.mlb file1.mar";
run_make_test($mk_string, run_make_test($mk_string,
'', $answer); '', $answer);
@@ -58,7 +58,7 @@ $mk_string =
"file2.c :\n" . "file2.c :\n" .
"\t\@pipe open/write xxx file2.c ; write xxx \"file2(){}\" ; close xxx\n"; "\t\@pipe open/write xxx file2.c ; write xxx \"file2(){}\" ; close xxx\n";
my $answer = "library /replace imagelib.olb file2.exe"; $answer = "library /replace imagelib.olb file2.exe";
run_make_test($mk_string, run_make_test($mk_string,
'', $answer); '', $answer);

File diff suppressed because it is too large Load Diff