mirror of
https://github.com/mirror/make.git
synced 2026-08-20 00:43:29 +08:00
Compare commits
39 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
00e590fdef | ||
|
|
4c64a5f986 | ||
|
|
414af96a50 | ||
|
|
1b976397e5 | ||
|
|
9bc5491712 | ||
|
|
57b13c8020 | ||
|
|
02a4c2913a | ||
|
|
8acb89c8c4 | ||
|
|
271e572ba2 | ||
|
|
bde990bfea | ||
|
|
60e54608bd | ||
|
|
60905a8afb | ||
|
|
ebe1d37104 | ||
|
|
c0cb9c8b3d | ||
|
|
34ee9adaed | ||
|
|
64f5375fe0 | ||
|
|
da81e0815f | ||
|
|
9be3c0e2b2 | ||
|
|
9da708772c | ||
|
|
0967624050 | ||
|
|
ba950a796a | ||
|
|
005a251689 | ||
|
|
76b6e668a6 | ||
|
|
5ff6ae6177 | ||
|
|
7c202b50fa | ||
|
|
f0182df865 | ||
|
|
0a6c38eff8 | ||
|
|
4b45e2828d | ||
|
|
4f3a41c60a | ||
|
|
757a9d06e3 | ||
|
|
31394f7f53 | ||
|
|
b6884c73b7 | ||
|
|
8bffc8d53c | ||
|
|
a9609084f4 | ||
|
|
8d820d57f6 | ||
|
|
73e11a5024 | ||
|
|
85cdc9e9ae | ||
|
|
7e60ffe83e | ||
|
|
715c787dc6 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -60,8 +60,7 @@ README
|
||||
README.DOS
|
||||
README.OS2
|
||||
README.W32
|
||||
build.sh
|
||||
build.sh.in
|
||||
build.cfg
|
||||
config.ami
|
||||
config.h-vms
|
||||
config.h.W32
|
||||
|
||||
@@ -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
|
||||
# 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.Amiga SCOPTIONS src/config.ami \
|
||||
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 \
|
||||
$(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
|
||||
|
||||
src/guile.$(OBJEXT): src/gmk-default.h
|
||||
|
||||
21
NEWS
21
NEWS
@@ -1,6 +1,6 @@
|
||||
GNU make NEWS -*-indented-text-*-
|
||||
History of user-visible changes.
|
||||
26 August 2019
|
||||
16 September 2019
|
||||
|
||||
See the end of this file for copyrights and conditions.
|
||||
|
||||
@@ -9,7 +9,7 @@ which is contained in this distribution as the file doc/make.texi.
|
||||
See the README file and the GNU make manual for instructions for
|
||||
reporting bugs.
|
||||
|
||||
Version 4.2.90 (26 Aug 2019)
|
||||
Version 4.2.91 (16 Sep 2019)
|
||||
|
||||
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!
|
||||
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
|
||||
determine how many jobs are running at any given instant, and compare that
|
||||
value to the load value requested. This allows usage such as "-j -lN" for
|
||||
N-processor systems without fear of overload.
|
||||
syntax, the -l/--load-average option will consult that file to determine how
|
||||
many CPUs are busy at that moment and compare that value to the load value
|
||||
requested. This allows usage such as "-j -lN" for N-processor systems
|
||||
without fear of overload during initial startup.
|
||||
Patch provided by Sven C. Dack <sven.c.dack@sky.com>
|
||||
|
||||
* 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
|
||||
this will cause make to enable that parallelism mode.
|
||||
|
||||
* GNU make will now use pthread_spawn() on systems where it is available.
|
||||
It will select POSIX_SPAWN_USEVFORK where that is available. If you prefer
|
||||
to use fork/exec even on systems where pthread_spawn() is present, you can
|
||||
use the --disable-pthread-spawn option to configure.
|
||||
Aron Barath <baratharon@caesar.elte.hu> provided the basic implementation.
|
||||
* GNU make will now use posix_spawn() on systems where it is available.
|
||||
If you prefer to use fork/exec even on systems where posix_spawn() is
|
||||
present, you can use the --disable-posix-spawn option to configure. Aron
|
||||
Barath <baratharon@caesar.elte.hu> provided the basic implementation.
|
||||
|
||||
* Error messages printed when invoking non-existent commands have been cleaned
|
||||
up and made consistent.
|
||||
|
||||
33
README.git
33
README.git
@@ -85,6 +85,8 @@ need to install the following extra software:
|
||||
* autopoint
|
||||
* pkg-config
|
||||
* 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.)
|
||||
|
||||
@@ -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.
|
||||
|
||||
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
|
||||
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
|
||||
builds" from remote directories are not supported. Once you've created
|
||||
@@ -114,9 +119,24 @@ That is, you can just run:
|
||||
|
||||
$ ./configure
|
||||
$ 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
|
||||
@@ -155,9 +175,10 @@ Even better, you should run this:
|
||||
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
|
||||
everything works, you get the same results, _and_ no extraneous files
|
||||
are left over after the "distclean" rule--whew!! Now, _that_ is why
|
||||
converting to Automake is worth the trouble! A big "huzzah!" to Tom
|
||||
T. and the AutoToolers!
|
||||
are left over after the "distclean" rule.
|
||||
|
||||
This package can be unpacked and built to give a "normal" (non-maintainer
|
||||
mode) result.
|
||||
|
||||
|
||||
Steps to Release
|
||||
|
||||
@@ -46,6 +46,7 @@ gnulib_files=doc/make-stds.texi
|
||||
gnulib_modules="\
|
||||
alloca
|
||||
fdl
|
||||
findprog-in
|
||||
getloadavg
|
||||
host-cpu-c-abi
|
||||
strerror
|
||||
|
||||
38
build.cfg.in
Normal file
38
build.cfg.in
Normal 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
149
build.sh
Executable 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.
|
||||
@@ -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}
|
||||
@@ -154,9 +154,11 @@ exit 1
|
||||
|
||||
:FoundMSVC
|
||||
set OUTDIR=.\WinRel
|
||||
set LNKOUT=./WinRel
|
||||
set "OPTS=/O2 /D NDEBUG"
|
||||
set LINKOPTS=
|
||||
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 LINKOPTS=/DEBUG
|
||||
if "%MAINT%" == "Y" set "OPTS=%OPTS% /D MAKE_MAINTAINER_MODE"
|
||||
@@ -168,9 +170,11 @@ goto Build
|
||||
|
||||
:FindGcc
|
||||
set OUTDIR=.\GccRel
|
||||
set LNKOUT=./GccRel
|
||||
set OPTS=-O2
|
||||
if "%DEBUG%" == "Y" set OPTS=-O0
|
||||
if "%DEBUG%" == "Y" set OUTDIR=.\GccDebug
|
||||
if "%DEBUG%" == "Y" set LNKOUT=./GccDebug
|
||||
if "%MAINT%" == "Y" set "OPTS=%OPTS% -DMAKE_MAINTAINER_MODE"
|
||||
:: Show the compiler version that we found
|
||||
echo.
|
||||
@@ -204,43 +208,43 @@ copy lib\fnmatch.in.h %OUTDIR%\lib\fnmatch.h
|
||||
|
||||
if exist %OUTDIR%\link.sc del %OUTDIR%\link.sc
|
||||
|
||||
call :Compile src\ar
|
||||
call :Compile src\arscan
|
||||
call :Compile src\commands
|
||||
call :Compile src\default
|
||||
call :Compile src\dir
|
||||
call :Compile src\expand
|
||||
call :Compile src\file
|
||||
call :Compile src\function
|
||||
call :Compile src\getopt
|
||||
call :Compile src\getopt1
|
||||
call :Compile src\guile GUILE
|
||||
call :Compile src\hash
|
||||
call :Compile src\implicit
|
||||
call :Compile src\job
|
||||
call :Compile src\load
|
||||
call :Compile src\loadapi
|
||||
call :Compile src\main GUILE
|
||||
call :Compile src\misc
|
||||
call :Compile src\output
|
||||
call :Compile src\read
|
||||
call :Compile src\remake
|
||||
call :Compile src\remote-stub
|
||||
call :Compile src\rule
|
||||
call :Compile src\signame
|
||||
call :Compile src\strcache
|
||||
call :Compile src\variable
|
||||
call :Compile src\version
|
||||
call :Compile src\vpath
|
||||
call :Compile src\w32\pathstuff
|
||||
call :Compile src\w32\w32os
|
||||
call :Compile src\w32\compat\posixfcn
|
||||
call :Compile src\w32\subproc\misc
|
||||
call :Compile src\w32\subproc\sub_proc
|
||||
call :Compile src\w32\subproc\w32err
|
||||
call :Compile lib\fnmatch
|
||||
call :Compile lib\glob
|
||||
call :Compile lib\getloadavg
|
||||
call :Compile src/ar
|
||||
call :Compile src/arscan
|
||||
call :Compile src/commands
|
||||
call :Compile src/default
|
||||
call :Compile src/dir
|
||||
call :Compile src/expand
|
||||
call :Compile src/file
|
||||
call :Compile src/function
|
||||
call :Compile src/getopt
|
||||
call :Compile src/getopt1
|
||||
call :Compile src/guile GUILE
|
||||
call :Compile src/hash
|
||||
call :Compile src/implicit
|
||||
call :Compile src/job
|
||||
call :Compile src/load
|
||||
call :Compile src/loadapi
|
||||
call :Compile src/main GUILE
|
||||
call :Compile src/misc
|
||||
call :Compile src/output
|
||||
call :Compile src/read
|
||||
call :Compile src/remake
|
||||
call :Compile src/remote-stub
|
||||
call :Compile src/rule
|
||||
call :Compile src/signame
|
||||
call :Compile src/strcache
|
||||
call :Compile src/variable
|
||||
call :Compile src/version
|
||||
call :Compile src/vpath
|
||||
call :Compile src/w32/pathstuff
|
||||
call :Compile src/w32/w32os
|
||||
call :Compile src/w32/compat/posixfcn
|
||||
call :Compile src/w32/subproc/misc
|
||||
call :Compile src/w32/subproc/sub_proc
|
||||
call :Compile src/w32/subproc/w32err
|
||||
call :Compile lib/fnmatch
|
||||
call :Compile lib/glob
|
||||
call :Compile lib/getloadavg
|
||||
|
||||
if not "%COMPILER%" == "gcc" call :Compile src\w32\compat\dirent
|
||||
|
||||
@@ -262,7 +266,7 @@ goto :EOF
|
||||
::
|
||||
|
||||
:Compile
|
||||
echo %OUTDIR%\%1.%O% >>%OUTDIR%\link.sc
|
||||
echo %LNKOUT%/%1.%O% >>%OUTDIR%\link.sc
|
||||
set EXTRAS=
|
||||
if "%2" == "GUILE" set "EXTRAS=%GUILECFLAGS%"
|
||||
if exist "%OUTDIR%\%1.%O%" del "%OUTDIR%\%1.%O%"
|
||||
@@ -277,7 +281,7 @@ goto CompileDone
|
||||
:GccCompile
|
||||
:: GCC Compile
|
||||
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
|
||||
|
||||
:CompileDone
|
||||
@@ -285,13 +289,14 @@ if not exist "%OUTDIR%\%1.%O%" exit 1
|
||||
goto :EOF
|
||||
|
||||
:Link
|
||||
echo Linking %OUTDIR%/%MAKE%.exe
|
||||
echo.
|
||||
echo Linking %LNKOUT%/%MAKE%.exe
|
||||
if "%COMPILER%" == "gcc" goto GccLink
|
||||
|
||||
:: MSVC Link
|
||||
echo %GUILELIBS% kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib >>%OUTDIR%\link.sc
|
||||
echo on
|
||||
link.exe /NOLOGO /SUBSYSTEM:console /PDB:%OUTDIR%\%MAKE%.pdb %LINKOPTS% /OUT:%OUTDIR%\%MAKE%.exe @%OUTDIR%\link.sc
|
||||
link.exe /NOLOGO /SUBSYSTEM:console /PDB:%LNKOUT%\%MAKE%.pdb %LINKOPTS% /OUT:%LNKOUT%\%MAKE%.exe @%LNKOUT%\link.sc
|
||||
@echo off
|
||||
goto :EOF
|
||||
|
||||
@@ -299,7 +304,7 @@ goto :EOF
|
||||
:: GCC Link
|
||||
echo on
|
||||
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
|
||||
goto :EOF
|
||||
|
||||
@@ -390,6 +395,7 @@ set NOGUILE=
|
||||
set O=
|
||||
set OPTS=
|
||||
set OUTDIR=
|
||||
set LNKOUT=
|
||||
set PKGMSC=
|
||||
set VSVARS=
|
||||
goto :EOF
|
||||
|
||||
46
configure.ac
46
configure.ac
@@ -16,7 +16,7 @@
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
AC_INIT([GNU make],[4.2.90],[bug-make@gnu.org])
|
||||
AC_INIT([GNU make],[4.2.91],[bug-make@gnu.org])
|
||||
|
||||
AC_PREREQ([2.69])
|
||||
|
||||
@@ -164,6 +164,9 @@ AC_CHECK_FUNCS([strcasecmp strncasecmp strcmpi strncmpi stricmp strnicmp])
|
||||
AC_FUNC_STRCOLL
|
||||
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
|
||||
AC_ARG_WITH([guile], [AS_HELP_STRING([--with-guile],
|
||||
[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
|
||||
|
||||
# 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
|
||||
|
||||
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.
|
||||
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])
|
||||
# We don't need this: the standard automake output suffices for POSIX systems.
|
||||
#mk/Posix.mk
|
||||
@@ -530,13 +501,6 @@ AC_CONFIG_FILES([Makefile lib/Makefile po/Makefile.in doc/Makefile \
|
||||
|
||||
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 comment-start: "dnl "
|
||||
dnl comment-end: ""
|
||||
|
||||
@@ -3980,7 +3980,7 @@ the statements in sequence. For example:
|
||||
|
||||
@example
|
||||
foo : bar/lose
|
||||
cd $(@@D) && gobble $(@@F) > ../$@@
|
||||
cd $(<D) && gobble $(<F) > ../$@@
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
@@ -5523,17 +5523,19 @@ replaced; other occurrences of @var{a} in the value are unaltered. For
|
||||
example:@refill
|
||||
|
||||
@example
|
||||
foo := a.o b.o c.o
|
||||
foo := a.o b.o l.a c.o
|
||||
bar := $(foo:.o=.c)
|
||||
@end example
|
||||
|
||||
@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
|
||||
@code{patsubst} expansion function (@pxref{Text Functions, ,Functions for String Substitution and Analysis}). We provide
|
||||
substitution references as well as @code{patsubst} for compatibility with
|
||||
other implementations of @code{make}.
|
||||
A substitution reference is shorthand for the @code{patsubst}
|
||||
expansion function (@pxref{Text Functions, ,Functions for String Substitution and Analysis}):
|
||||
@samp{$(@var{var}:@var{a}=@var{b})} is equivalent to
|
||||
@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
|
||||
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
|
||||
@exdent For example:
|
||||
|
||||
foo := a.o b.o c.o
|
||||
foo := a.o b.o l.a c.o
|
||||
bar := $(foo:%.o=%.c)
|
||||
@end group
|
||||
@end example
|
||||
|
||||
@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
|
||||
@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
|
||||
available job. To obtain an extra slot you must read a single
|
||||
character from the jobserver pipe; to release a slot you must write a
|
||||
single character back into the jobserver pipe.
|
||||
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
|
||||
look for the argument string @code{--jobserver-auth=R,W} where
|
||||
|
||||
@@ -2,6 +2,33 @@ Description:
|
||||
GNU make version of fnmatch()/glob() functions. This is a holdover from
|
||||
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:
|
||||
if !USE_SYSTEM_GLOB
|
||||
libgnu_a_SOURCES += fnmatch.c
|
||||
|
||||
@@ -117,7 +117,7 @@ extern int errno;
|
||||
|
||||
/* When used in the GNU libc the symbol _DIRENT_HAVE_D_TYPE 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
|
||||
#endif
|
||||
|
||||
|
||||
@@ -29,11 +29,13 @@ MAKEWEBDIR ?= $(SRCROOTDIR)/make/make-web
|
||||
# We like mondo-warnings!
|
||||
# Also force comments to be preserved. This helps when using ccache, in
|
||||
# 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 \
|
||||
-Wtype-limits -Wunused-but-set-parameter -Wlogical-op -Wpointer-arith \
|
||||
-Wignored-qualifiers -Wformat-signedness -Wduplicated-cond
|
||||
|
||||
AM_CFLAGS += $(MAKE_CFLAGS)
|
||||
|
||||
# Unfortunately the Guile headers are sometimes broken. Convince GCC
|
||||
# to treat them as system headers so warnings are ignored.
|
||||
GUILE_CFLAGS := $(patsubst -I%,-isystem %,$(GUILE_CFLAGS))
|
||||
@@ -83,16 +85,6 @@ Basic.mk: Basic.mk.template .dep_segment Makefile
|
||||
$(word 2,$^) >>$@
|
||||
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.
|
||||
#
|
||||
@@ -264,9 +256,9 @@ $(CONFIG_CHECKS): checkcfg.%: distdir
|
||||
$(AM_DISTCHECK_CONFIGURE_FLAGS) $(DISTCHECK_CONFIGURE_FLAGS)
|
||||
exec >>'checkcfg.$*.log' 2>&1; set -x; \
|
||||
cd $(distdir)/_build \
|
||||
&& ./build.sh \
|
||||
&& ./make $(AM_MAKEFLAGS) check \
|
||||
&& ./make $(AM_MAKEFLAGS) clean
|
||||
&& OUTDIR=_bld ../build.sh \
|
||||
&& _bld/make $(AM_MAKEFLAGS) check-local \
|
||||
&& _bld/make $(AM_MAKEFLAGS) clean
|
||||
exec >>'checkcfg.$*.log' 2>&1; set -x; \
|
||||
cd $(distdir)/_build \
|
||||
&& $(NR_MAKE) $(AM_MAKEFLAGS) CFLAGS='$(AM_CFLAGS)' \
|
||||
@@ -403,7 +395,7 @@ $(COV_BUILD_FILE): $(filter %.c %.h,$(DISTFILES))
|
||||
CFLAGS='$(AM_CFLAGS)'
|
||||
PATH="$${COVERITY_PATH:+$$COVERITY_PATH/bin:}$$PATH"; \
|
||||
cd '$(distdir)'/_build \
|
||||
&& cov-build --dir cov-int ./build.sh
|
||||
&& cov-build --dir cov-int ../build.sh
|
||||
rm -f '$@'
|
||||
(cd '$(distdir)'/_build && tar czf - cov-int) > '$@'
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
#include <rmsdef.h>
|
||||
|
||||
/* This symbol should be present in lbrdef.h. */
|
||||
#ifndef LBR$_HDRTRUNC
|
||||
#if !defined LBR$_HDRTRUNC
|
||||
#pragma extern_model save
|
||||
#pragma extern_model globalvalue
|
||||
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++)
|
||||
ar_hdr.ar_date[ui] = ' ';
|
||||
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
|
||||
ar_hdr.ar_date = statbuf.st_mtime;
|
||||
#endif
|
||||
|
||||
@@ -291,6 +291,9 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
/* Define to 1 if you have the 'strsignal' function. */
|
||||
/* #undef HAVE_STRSIGNAL */
|
||||
|
||||
/* Define to 1 if `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 HAVE_ISATTY 1
|
||||
|
||||
@@ -298,6 +301,11 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
#define HAVE_TTYNAME 1
|
||||
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'. */
|
||||
/* #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. */
|
||||
/* #undef const */
|
||||
|
||||
#ifdef __MINGW32__
|
||||
# undef __USE_MINGW_ANSI_STDIO
|
||||
# define __USE_MINGW_ANSI_STDIO 1
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
/* Define to 'int' if <sys/types.h> doesn't define. */
|
||||
|
||||
10
src/dep.h
10
src/dep.h
@@ -44,11 +44,11 @@ struct nameseq
|
||||
NAMESEQ (_t); \
|
||||
struct file *file; \
|
||||
const char *stem; \
|
||||
unsigned short flags : 8; \
|
||||
unsigned short changed : 1; \
|
||||
unsigned short ignore_mtime : 1; \
|
||||
unsigned short staticpattern : 1; \
|
||||
unsigned short need_2nd_expansion : 1
|
||||
unsigned int flags : 8; \
|
||||
unsigned int changed : 1; \
|
||||
unsigned int ignore_mtime : 1; \
|
||||
unsigned int staticpattern : 1; \
|
||||
unsigned int need_2nd_expansion : 1
|
||||
|
||||
struct dep
|
||||
{
|
||||
|
||||
@@ -732,7 +732,7 @@ dir_contents_file_exists_p (struct directory_contents *dir,
|
||||
#else
|
||||
df->name = strcache_add_len (d->d_name, len);
|
||||
#endif
|
||||
#ifdef _DIRENT_HAVE_D_TYPE
|
||||
#ifdef HAVE_STRUCT_DIRENT_D_TYPE
|
||||
df->type = d->d_type;
|
||||
#endif
|
||||
df->length = len;
|
||||
@@ -1245,7 +1245,7 @@ read_dirstream (__ptr_t stream)
|
||||
#ifdef _DIRENT_HAVE_D_NAMLEN
|
||||
d->d_namlen = len - 1;
|
||||
#endif
|
||||
#ifdef _DIRENT_HAVE_D_TYPE
|
||||
#ifdef HAVE_STRUCT_DIRENT_D_TYPE
|
||||
d->d_type = df->type;
|
||||
#endif
|
||||
memcpy (d->d_name, df->name, len);
|
||||
@@ -1332,6 +1332,7 @@ local_lstat (const char *path, struct stat *buf)
|
||||
void
|
||||
dir_setup_glob (glob_t *gl)
|
||||
{
|
||||
gl->gl_offs = 0;
|
||||
gl->gl_opendir = open_dirstream;
|
||||
gl->gl_readdir = read_dirstream;
|
||||
gl->gl_closedir = free;
|
||||
|
||||
@@ -38,8 +38,8 @@ struct function_table_entry
|
||||
unsigned char len;
|
||||
unsigned char minimum_args;
|
||||
unsigned char maximum_args;
|
||||
unsigned char expand_args:1;
|
||||
unsigned char alloc_fn:1;
|
||||
unsigned int expand_args:1;
|
||||
unsigned int alloc_fn:1;
|
||||
};
|
||||
|
||||
static unsigned long
|
||||
@@ -1780,12 +1780,16 @@ func_shell_base (char *o, char **argv, int trim_newlines)
|
||||
fd_noinherit (pipedes[0]);
|
||||
|
||||
{
|
||||
struct output out;
|
||||
out.syncout = 1;
|
||||
out.out = pipedes[1];
|
||||
out.err = errfd;
|
||||
struct childbase child;
|
||||
child.cmd_name = NULL;
|
||||
child.output.syncout = 1;
|
||||
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)
|
||||
|
||||
162
src/job.c
162
src/job.c
@@ -17,6 +17,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
#include "makeint.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "job.h"
|
||||
#include "debug.h"
|
||||
@@ -25,8 +26,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
#include "variable.h"
|
||||
#include "os.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* Default shell to use. */
|
||||
#ifdef WINDOWS32
|
||||
# ifdef HAVE_STRINGS_H
|
||||
@@ -139,6 +138,7 @@ extern int wait3 ();
|
||||
|
||||
#ifdef USE_POSIX_SPAWN
|
||||
# include <spawn.h>
|
||||
# include "findprog.h"
|
||||
#endif
|
||||
|
||||
#if !defined (wait) && !defined (POSIX)
|
||||
@@ -724,7 +724,9 @@ reap_children (int block, int err)
|
||||
else if (pid < 0)
|
||||
{
|
||||
/* A remote status command failed miserably. Punt. */
|
||||
#if !defined(__MSDOS__) && !defined(_AMIGA) && !defined(WINDOWS32)
|
||||
remote_status_lose:
|
||||
#endif
|
||||
pfatal_with_name ("remote_status");
|
||||
}
|
||||
else
|
||||
@@ -905,6 +907,36 @@ reap_children (int block, int err)
|
||||
--job_counter;
|
||||
|
||||
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
|
||||
question mode, 2 for anything else. */
|
||||
if (exit_sig == 0 && exit_code == 0)
|
||||
@@ -1113,6 +1145,7 @@ free_child (struct child *child)
|
||||
free (child->environment);
|
||||
}
|
||||
|
||||
free (child->cmd_name);
|
||||
free (child);
|
||||
}
|
||||
|
||||
@@ -1207,12 +1240,11 @@ start_job_command (struct child *child)
|
||||
}
|
||||
|
||||
argv = p;
|
||||
/* Although construct_command_argv contains some code for VMS, it was/is
|
||||
not called/used. Please note, for VMS argv is a string (not an array
|
||||
of strings) which contains the complete command line, which for
|
||||
multi-line variables still includes the newlines. So detect newlines
|
||||
and set 'end' (which is used for child->command_ptr) instead of
|
||||
(re-)writing construct_command_argv */
|
||||
/* Please note, for VMS argv is a string (not an array of strings) which
|
||||
contains the complete command line, which for multi-line variables
|
||||
still includes the newlines. So detect newlines and set 'end' (which
|
||||
is used for child->command_ptr) instead of (re-)writing
|
||||
construct_command_argv */
|
||||
if (!one_shell)
|
||||
{
|
||||
char *s = p;
|
||||
@@ -1420,8 +1452,7 @@ start_job_command (struct child *child)
|
||||
child->remote = 0;
|
||||
|
||||
#ifdef VMS
|
||||
if (!child_execute_job (child, argv))
|
||||
child->pid = -1;
|
||||
child->pid = child_execute_job ((struct childbase *)child, 1, argv);
|
||||
|
||||
#else
|
||||
|
||||
@@ -1429,11 +1460,12 @@ start_job_command (struct child *child)
|
||||
|
||||
jobserver_pre_child (flags & COMMANDS_RECURSE);
|
||||
|
||||
child->pid = child_execute_job (&child->output, child->good_stdin,
|
||||
argv, child->environment);
|
||||
child->pid = child_execute_job ((struct childbase *)child,
|
||||
child->good_stdin, argv);
|
||||
|
||||
environ = parent_environ; /* Restore value child may have clobbered. */
|
||||
jobserver_post_child (flags & COMMANDS_RECURSE);
|
||||
|
||||
#endif /* !VMS */
|
||||
}
|
||||
|
||||
@@ -2128,7 +2160,7 @@ start_waiting_jobs (void)
|
||||
/* EMX: Start a child process. This function returns the new pid. */
|
||||
# if defined __EMX__
|
||||
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;
|
||||
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;
|
||||
|
||||
/* Divert child output if we want to capture output. */
|
||||
if (out && out->syncout)
|
||||
if (child->output.syncout)
|
||||
{
|
||||
if (out->out >= 0)
|
||||
fdout = out->out;
|
||||
if (out->err >= 0)
|
||||
fderr = out->err;
|
||||
if (child->output.out >= 0)
|
||||
fdout = child->output.out;
|
||||
if (child->output.err >= 0)
|
||||
fderr = child->output.err;
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
pid = exec_command (argv, envp);
|
||||
pid = exec_command (argv, child->environment);
|
||||
|
||||
/* Restore stdout/stdin/stderr of the parent and close temporary FDs. */
|
||||
if (save_fdin >= 0)
|
||||
@@ -2227,9 +2259,9 @@ child_execute_job (struct output *out, int good_stdin, char **argv, char **envp)
|
||||
|
||||
/* POSIX:
|
||||
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
|
||||
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 ();
|
||||
int fdout = FD_STDOUT;
|
||||
@@ -2237,18 +2269,19 @@ child_execute_job (struct output *out, int good_stdin, char **argv, char **envp)
|
||||
pid_t pid;
|
||||
int r;
|
||||
#if defined(USE_POSIX_SPAWN)
|
||||
short flags = 0;
|
||||
char *cmd;
|
||||
posix_spawnattr_t attr;
|
||||
posix_spawn_file_actions_t fa;
|
||||
short flags = 0;
|
||||
#endif
|
||||
|
||||
/* Divert child output if we want to capture it. */
|
||||
if (out && out->syncout)
|
||||
if (child->output.syncout)
|
||||
{
|
||||
if (out->out >= 0)
|
||||
fdout = out->out;
|
||||
if (out->err >= 0)
|
||||
fderr = out->err;
|
||||
if (child->output.out >= 0)
|
||||
fdout = child->output.out;
|
||||
if (child->output.err >= 0)
|
||||
fderr = child->output.err;
|
||||
}
|
||||
|
||||
#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));
|
||||
|
||||
/* 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)
|
||||
goto done;
|
||||
@@ -2306,10 +2339,6 @@ child_execute_job (struct output *out, int good_stdin, char **argv, char **envp)
|
||||
flags |= POSIX_SPAWN_USEVFORK;
|
||||
#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.
|
||||
They are all marked close-on-exec already. */
|
||||
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)
|
||||
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. */
|
||||
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:
|
||||
posix_spawn_file_actions_destroy (&fa);
|
||||
posix_spawnattr_destroy (&attr);
|
||||
@@ -2341,7 +2427,7 @@ child_execute_job (struct output *out, int good_stdin, char **argv, char **envp)
|
||||
if (r != 0)
|
||||
pid = -1;
|
||||
|
||||
#endif /* have posix_spawn() */
|
||||
#endif /* USE_POSIX_SPAWN */
|
||||
|
||||
if (pid < 0)
|
||||
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
|
||||
the limit from a very frequent use case, because using quoted
|
||||
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[] =
|
||||
{ "assoc", "break", "call", "cd", "chcp", "chdir", "cls", "color", "copy",
|
||||
"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)
|
||||
goto slow;
|
||||
#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. */
|
||||
else if (instring == '"' && strchr ("*?%", *p) != 0 && !unixy_shell)
|
||||
else if (instring == '"' && strchr ("*?", *p) != 0 && !unixy_shell)
|
||||
goto slow;
|
||||
else if (instring == '"' && strncmp (p, "\\\"", 2) == 0)
|
||||
*ap++ = *++p;
|
||||
|
||||
45
src/job.h
45
src/job.h
@@ -18,30 +18,44 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* 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
|
||||
{
|
||||
CHILDBASE;
|
||||
|
||||
struct child *next; /* Link in the chain. */
|
||||
|
||||
struct file *file; /* File being remade. */
|
||||
|
||||
char **environment; /* Environment for commands. */
|
||||
|
||||
char *sh_batch_file; /* Script file for shell commands */
|
||||
char **command_lines; /* Array of variable-expanded cmd lines. */
|
||||
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. */
|
||||
|
||||
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 noerror:1; /* Nonzero if commands contained a '-'. */
|
||||
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,
|
||||
int cmd_flags, char** batch_file);
|
||||
|
||||
#ifdef VMS
|
||||
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
|
||||
pid_t child_execute_job (struct childbase *child, int good_stdin, char **argv);
|
||||
|
||||
#ifdef _AMIGA
|
||||
void exec_command (char **argv) __attribute__ ((noreturn));
|
||||
|
||||
11
src/main.c
11
src/main.c
@@ -2469,7 +2469,12 @@ main (int argc, char **argv, char **envp)
|
||||
termination. */
|
||||
pid_t pid;
|
||||
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? */
|
||||
do {
|
||||
@@ -2639,8 +2644,8 @@ init_switches (void)
|
||||
|
||||
for (i = 0; switches[i].c != '\0'; ++i)
|
||||
{
|
||||
long_options[i].name = (switches[i].long_name == 0 ? "" :
|
||||
switches[i].long_name);
|
||||
long_options[i].name = (char *) (switches[i].long_name == 0 ? "" :
|
||||
switches[i].long_name);
|
||||
long_options[i].flag = 0;
|
||||
long_options[i].val = switches[i].c;
|
||||
if (short_option (switches[i].c))
|
||||
|
||||
@@ -292,12 +292,9 @@ char *strerror (int errnum);
|
||||
char *strsignal (int signum);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_UMASK)
|
||||
# define UMASK(_m) umask (_m)
|
||||
# define MODE_T mode_t
|
||||
#else
|
||||
# define UMASK(_m) 0
|
||||
# define MODE_T int
|
||||
#if !defined(HAVE_UMASK)
|
||||
typedef int mode_t;
|
||||
extern mode_t umask (mode_t);
|
||||
#endif
|
||||
|
||||
/* ISDIGIT offers the following features:
|
||||
@@ -451,7 +448,8 @@ extern int unixy_shell;
|
||||
#define NEXT_TOKEN(s) while (ISSPACE (*(s))) ++(s)
|
||||
#define END_OF_TOKEN(s) while (! STOP_SET (*(s), MAP_SPACE|MAP_NUL)) ++(s)
|
||||
|
||||
#if defined(HAVE_SYS_RESOURCE_H) && defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT)
|
||||
/* 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
|
||||
#endif
|
||||
#ifdef SET_STACK_SIZE
|
||||
|
||||
12
src/misc.c
12
src/misc.c
@@ -437,6 +437,14 @@ char *mktemp (char *template);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_UMASK
|
||||
mode_t
|
||||
umask (mode_t mask)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
FILE *
|
||||
get_tmpfile (char **name, const char *template)
|
||||
{
|
||||
@@ -446,7 +454,7 @@ get_tmpfile (char **name, const char *template)
|
||||
#endif
|
||||
|
||||
/* 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)
|
||||
# define TEMPLATE_LEN strlen (template)
|
||||
@@ -482,7 +490,7 @@ get_tmpfile (char **name, const char *template)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
UMASK (mask);
|
||||
umask (mask);
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
@@ -281,7 +281,7 @@ release_semaphore (void *sem)
|
||||
int
|
||||
output_tmpfd (void)
|
||||
{
|
||||
MODE_T mask = UMASK (0077);
|
||||
mode_t mask = umask (0077);
|
||||
int fd = -1;
|
||||
FILE *tfile = tmpfile ();
|
||||
|
||||
@@ -297,7 +297,7 @@ output_tmpfd (void)
|
||||
|
||||
set_append_mode (fd);
|
||||
|
||||
UMASK (mask);
|
||||
umask (mask);
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
25
src/read.c
25
src/read.c
@@ -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
|
||||
@@ -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
|
||||
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)". */
|
||||
if (!(p - beg >= 2
|
||||
&& (*p == '/' || *p == '\\') && isalpha ((unsigned char)p[-2])
|
||||
&& (p - beg == 2 || p[-3] == '(')))
|
||||
if ((p - beg == 2 || (p - beg > 2 && p[-3] == '('))
|
||||
&& isalpha ((unsigned char)p[-2]))
|
||||
break;
|
||||
#endif
|
||||
goto done_word;
|
||||
|
||||
@@ -3182,7 +3175,7 @@ parse_file_seq (char **stringp, size_t size, int stopmap,
|
||||
#endif
|
||||
char *s;
|
||||
size_t nlen;
|
||||
int i;
|
||||
int tot, i;
|
||||
|
||||
/* Skip whitespace; at the end of the string or STOPCHAR we're done. */
|
||||
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)
|
||||
{
|
||||
globme = 0;
|
||||
i = 1;
|
||||
tot = 1;
|
||||
nlist = &name;
|
||||
}
|
||||
else
|
||||
@@ -3402,7 +3395,7 @@ parse_file_seq (char **stringp, size_t size, int stopmap,
|
||||
|
||||
case 0:
|
||||
/* Success. */
|
||||
i = gl.gl_pathc;
|
||||
tot = gl.gl_pathc;
|
||||
nlist = (const char **)gl.gl_pathv;
|
||||
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 (ANY_SET (flags, PARSEFS_EXISTS))
|
||||
{
|
||||
i = 0;
|
||||
tot = 0;
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
|
||||
default:
|
||||
/* By default keep this name. */
|
||||
i = 1;
|
||||
tot = 1;
|
||||
nlist = &name;
|
||||
break;
|
||||
}
|
||||
|
||||
/* For each matched element, add it to the list. */
|
||||
while (i-- > 0)
|
||||
for (i = 0; i < tot; ++i)
|
||||
#ifndef NO_ARCHIVES
|
||||
if (memname != 0)
|
||||
{
|
||||
|
||||
@@ -104,11 +104,12 @@ static int ctrlYPressed= 0;
|
||||
inner mode level AST.
|
||||
*/
|
||||
static int
|
||||
vmsHandleChildTerm (struct child *child)
|
||||
vmsHandleChildTerm (struct childbase *cbase)
|
||||
{
|
||||
int exit_code;
|
||||
struct child *child = (struct child*)cbase;
|
||||
struct child *lastc, *c;
|
||||
int child_failed;
|
||||
int exit_code;
|
||||
|
||||
/* The child efn is 0 when a built-in or null command is executed
|
||||
successfully with out actually creating a child.
|
||||
@@ -803,8 +804,8 @@ build_vms_cmd (char **cmd_tokens,
|
||||
return cmd_dsc;
|
||||
}
|
||||
|
||||
int
|
||||
child_execute_job (struct child *child, char *argv)
|
||||
pid_t
|
||||
child_execute_job (struct childbase *child, int good_stdin UNUSED, char *argv)
|
||||
{
|
||||
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 */
|
||||
child->cstatus = VMS_POSIX_EXIT_MASK;
|
||||
child->vms_launch_status = SS$_NORMAL;
|
||||
/* TODO what is this "magic number" */
|
||||
child->pid = 270163; /* Special built-in */
|
||||
child->efn = 0;
|
||||
vmsHandleChildTerm (child);
|
||||
return 1;
|
||||
/* TODO what is this "magic number" */
|
||||
return 270163; /* Special built-in */
|
||||
}
|
||||
|
||||
sprintf (procname, "GMAKE_%05x", getpid () & 0xfffff);
|
||||
@@ -1162,11 +1162,9 @@ child_execute_job (struct child *child, char *argv)
|
||||
free (cmd_tokens[cmd_tkn_index++]);
|
||||
child->cstatus = VMS_POSIX_EXIT_MASK | (MAKE_TROUBLE << 3);
|
||||
child->vms_launch_status = SS$_ABORT;
|
||||
/* TODO what is this "magic number" */
|
||||
child->pid = 270163; /* Special built-in */
|
||||
child->efn = 0;
|
||||
errno = token.cmd_errno;
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Save any redirection to append file */
|
||||
@@ -1206,21 +1204,18 @@ child_execute_job (struct child *child, char *argv)
|
||||
free (cmd_dsc);
|
||||
child->cstatus = VMS_POSIX_EXIT_MASK | (MAKE_TROUBLE << 3);
|
||||
child->vms_launch_status = SS$_ABORT;
|
||||
/* TODO what is this "magic number" */
|
||||
child->pid = 270163; /* Special built-in */
|
||||
child->efn = 0;
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Only a built-in or a null command - Still need to run term AST */
|
||||
free (cmd_dsc);
|
||||
child->cstatus = VMS_POSIX_EXIT_MASK;
|
||||
child->vms_launch_status = SS$_NORMAL;
|
||||
/* TODO what is this "magic number" */
|
||||
child->pid = 270163; /* Special built-in */
|
||||
child->efn = 0;
|
||||
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)
|
||||
@@ -1339,7 +1334,7 @@ child_execute_job (struct child *child, char *argv)
|
||||
unlink (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 ;
|
||||
}
|
||||
|
||||
@@ -135,6 +135,13 @@ readdir(DIR* pDir)
|
||||
pDir->dir_sdReturn.d_ino = (ino_t)-1;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,20 +33,46 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#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
|
||||
{
|
||||
ino_t d_ino; /* unused - no equivalent on WINDOWS32 */
|
||||
char d_name[NAME_MAX+1];
|
||||
};
|
||||
{
|
||||
ino_t d_ino; /* unused - no equivalent on WINDOWS32. */
|
||||
unsigned char d_type;
|
||||
char d_name[NAME_MAX+1]; /* must come last due to dir.c assumptions. */
|
||||
};
|
||||
|
||||
typedef struct dir_struct {
|
||||
ULONG dir_ulCookie;
|
||||
HANDLE dir_hDirHandle;
|
||||
DWORD dir_nNumFiles;
|
||||
char dir_pDirectoryName[NAME_MAX+1];
|
||||
struct dirent dir_sdReturn;
|
||||
} DIR;
|
||||
typedef struct dir_struct
|
||||
{
|
||||
ULONG dir_ulCookie;
|
||||
HANDLE dir_hDirHandle;
|
||||
DWORD dir_nNumFiles;
|
||||
char dir_pDirectoryName[NAME_MAX+1];
|
||||
struct dirent dir_sdReturn;
|
||||
} DIR;
|
||||
|
||||
DIR *opendir(const char *);
|
||||
struct dirent *readdir(DIR *);
|
||||
|
||||
@@ -108,7 +108,7 @@ DWORD process_wait_for_multiple_objects(
|
||||
continue;
|
||||
break;
|
||||
case WAIT_FAILED:
|
||||
fprintf(stderr,"WaitForMultipleOjbects failed waiting with error %d\n", GetLastError());
|
||||
fprintf(stderr,"WaitForMultipleOjbects failed waiting with error %lu\n", GetLastError());
|
||||
break;
|
||||
default:
|
||||
if (retVal >= WAIT_ABANDONED_0) {
|
||||
|
||||
@@ -4,16 +4,17 @@
|
||||
# during the tests.
|
||||
|
||||
%CONFIG_FLAGS = (
|
||||
AM_LDFLAGS => '@AM_LDFLAGS@',
|
||||
AR => '@AR@',
|
||||
CC => '@CC@',
|
||||
CFLAGS => '@CFLAGS@',
|
||||
CPP => '@CPP@',
|
||||
CPPFLAGS => '@CPPFLAGS@',
|
||||
GUILE_CFLAGS => '@GUILE_CFLAGS@',
|
||||
GUILE_LIBS => '@GUILE_LIBS@',
|
||||
LDFLAGS => '@LDFLAGS@',
|
||||
LIBS => '@LIBS@'
|
||||
AM_LDFLAGS => '@AM_LDFLAGS@',
|
||||
AR => '@AR@',
|
||||
CC => '@CC@',
|
||||
CFLAGS => '@CFLAGS@',
|
||||
CPP => '@CPP@',
|
||||
CPPFLAGS => '@CPPFLAGS@',
|
||||
GUILE_CFLAGS => '@GUILE_CFLAGS@',
|
||||
GUILE_LIBS => '@GUILE_LIBS@',
|
||||
LDFLAGS => '@LDFLAGS@',
|
||||
LIBS => '@LIBS@',
|
||||
USE_SYSTEM_GLOB => '@USE_SYSTEM_GLOB@'
|
||||
);
|
||||
|
||||
1;
|
||||
|
||||
@@ -24,7 +24,7 @@ $ open/read cfpm_in config-flags.pm.in
|
||||
$!
|
||||
$ outfile = "sys$disk:[]config-flags.pm"
|
||||
$!
|
||||
$ cflags = "/include=([],[.glob]"
|
||||
$ cflags = "/include=([],[.lib]"
|
||||
$!
|
||||
$ create '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. "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
|
||||
$ goto cfpm_read_loop
|
||||
$ endif
|
||||
|
||||
@@ -27,6 +27,21 @@
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# 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 = ();
|
||||
|
||||
$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;
|
||||
|
||||
# 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 = '';
|
||||
|
||||
@@ -67,24 +87,71 @@ if ($^O eq 'VMS')
|
||||
$CMD_rmfile = 'delete_file -no_ask';
|
||||
}
|
||||
|
||||
use FindBin;
|
||||
use lib "$FindBin::Bin";
|
||||
|
||||
require "test_driver.pl";
|
||||
|
||||
%CONFIG_FLAGS = ();
|
||||
|
||||
my $statnm = "$FindBin::Bin/../config.status";
|
||||
if (open(my $fh, '<', $statnm)) {
|
||||
while (my $line = <$fh>) {
|
||||
$line =~ m/^[SD]\["([^\"]+)"\]=" *(.*)"/ and $CONFIG_FLAGS{$1} = $2;
|
||||
}
|
||||
} else {
|
||||
warn "Failed to open $statnm: $!";
|
||||
}
|
||||
# Find the strings that will be generated for various error codes.
|
||||
# We want them from the C locale regardless of our current locale.
|
||||
|
||||
# Some target systems might not have the POSIX module...
|
||||
$has_POSIX = eval { require "POSIX.pm" };
|
||||
$ERR_no_such_file = undef;
|
||||
$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 @_; };
|
||||
|
||||
@@ -103,7 +170,7 @@ sub valid_option
|
||||
|
||||
if ($option =~ /^-srcdir$/i) {
|
||||
$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";
|
||||
exit 0;
|
||||
}
|
||||
@@ -155,7 +222,7 @@ sub subst_make_string
|
||||
s/#MAKEPATH#/$mkpath/g;
|
||||
s/#MAKE#/$make_name/g;
|
||||
s/#PERL#/$perl_name/g;
|
||||
s/#PWD#/$pwd/g;
|
||||
s/#PWD#/$cwdpath/g;
|
||||
return $_;
|
||||
}
|
||||
|
||||
@@ -170,7 +237,7 @@ sub run_make_test
|
||||
|
||||
if (! defined $makestring) {
|
||||
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;
|
||||
} else {
|
||||
if (! defined($makefile)) {
|
||||
@@ -182,9 +249,9 @@ sub run_make_test
|
||||
$makestring = subst_make_string($makestring);
|
||||
|
||||
# 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;
|
||||
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.
|
||||
@@ -317,8 +384,7 @@ sub run_make_with_options {
|
||||
# If we have a purify log, save it
|
||||
$tn = $pure_testname . ($num_of_logfiles ? ".$num_of_logfiles" : "");
|
||||
print("Renaming purify log file to $tn\n") if $debug;
|
||||
rename($pure_log, "$tn")
|
||||
|| die "Can't rename $log to $tn: $!\n";
|
||||
rename($pure_log, "$tn") or die "Can't rename $log to $tn: $!\n";
|
||||
++$purify_errors;
|
||||
} else {
|
||||
unlink($pure_log);
|
||||
@@ -363,168 +429,227 @@ sub print_help
|
||||
"\tRun the test suite under valgrind's memcheck tool.",
|
||||
"\tChange the default valgrind args with the VALGRIND_ARGS env var.",
|
||||
"-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."
|
||||
);
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
# $profile = 1;
|
||||
$testee = "GNU make";
|
||||
$make_path = "make";
|
||||
$tmpfilesuffix = "mk";
|
||||
$pwd = &get_this_pwd;
|
||||
# $profile = 1;
|
||||
$testee = "GNU make";
|
||||
$make_path = "make";
|
||||
$tmpfilesuffix = "mk";
|
||||
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
|
||||
{
|
||||
local($string);
|
||||
local($index);
|
||||
local($string);
|
||||
local($index);
|
||||
|
||||
# On DOS/Windows system the filesystem apparently can't track
|
||||
# timestamps with second granularity (!!). Change the sleep time
|
||||
# needed to force a file to be considered "old".
|
||||
$wtime = $port_type eq 'UNIX' ? 1 : $port_type eq 'OS/2' ? 2 : 4;
|
||||
# Now that we have located make_path, locate the srcdir and blddir
|
||||
my ($mpv, $mpd, $mpf) = find_prog($make_path);
|
||||
|
||||
# Find the full pathname of Make. For DOS systems this is more
|
||||
# complicated, so we ask make itself.
|
||||
if ($osname eq 'VMS') {
|
||||
$port_type = 'VMS-DCL' unless defined $ENV{"SHELL"};
|
||||
# On VMS pre-setup make to be found with simply 'make'.
|
||||
$make_path = 'make';
|
||||
} 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;
|
||||
}
|
||||
# We have a make program so try to compute the blddir.
|
||||
if ($mpd) {
|
||||
my $f = catpath($mpv, catdir($mpd, 'tests'), 'config-flags.pm');
|
||||
if (-f $f) {
|
||||
$bldvol = $mpv;
|
||||
$blddir = $mpd;
|
||||
}
|
||||
}
|
||||
|
||||
# Ask make what shell to use
|
||||
create_file('shell.mk', 'all:;$(info $(SHELL))');
|
||||
$sh_name = `$make_path -sf shell.mk`;
|
||||
unlink('shell.mk');
|
||||
chop $sh_name;
|
||||
if (! $sh_name) {
|
||||
print "Cannot determine shell\n";
|
||||
$is_posix_sh = 0;
|
||||
} else {
|
||||
my $o = `$sh_name -c ': do nothing' 2>&1`;
|
||||
$is_posix_sh = $? == 0 && $o == '';
|
||||
}
|
||||
# If srcdir wasn't provided on the command line, try to find it.
|
||||
if (! $srcdir && $blddir) {
|
||||
# See if the blddir is the srcdir
|
||||
my $f = catpath($bldvol, catdir($blddir, 'src'), 'gnumake.h');
|
||||
if (-f $f) {
|
||||
$srcdir = $blddir;
|
||||
$srcvol = $bldvol;
|
||||
}
|
||||
}
|
||||
|
||||
$string = `$make_path -v`;
|
||||
$string =~ /^(GNU Make [^,\n]*)/ or die "$make_path is not GNU make. Version:\n$string";
|
||||
$testee_version = "$1\n";
|
||||
if (! $srcdir) {
|
||||
# Not found, see if our parent is the source dir
|
||||
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';
|
||||
$redir = '' if os_name eq 'VMS';
|
||||
$string = `sh -c "$make_path -f null.mk $redir"`;
|
||||
if ($string =~ /(.*): \*\*\* No targets\. Stop\./) {
|
||||
$make_name = $1;
|
||||
}
|
||||
else {
|
||||
$make_path =~ /^(?:.*$pathsep)?(.+)$/;
|
||||
$make_name = $1;
|
||||
}
|
||||
# Load the config flags
|
||||
if (!$blddir) {
|
||||
warn "Cannot locate config-flags.pm (no blddir)\n";
|
||||
} else {
|
||||
my $f = catpath($bldvol, catdir($blddir, 'tests'), 'config-flags.pm');
|
||||
if (! -f $f) {
|
||||
warn "Cannot locate $f\n";
|
||||
} else {
|
||||
unshift(@INC, catpath($bldvol, catdir($blddir, 'tests'), ''));
|
||||
require "config-flags.pm";
|
||||
}
|
||||
}
|
||||
|
||||
# prepend pwd if this is a relative path (ie, does not
|
||||
# start with a slash, but contains one). Thanks for the
|
||||
# clue, Roland.
|
||||
# On DOS/Windows system the filesystem apparently can't track
|
||||
# timestamps with second granularity (!!). Change the sleep time
|
||||
# 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)
|
||||
{
|
||||
$mkpath = "$pwd$pathsep$make_path";
|
||||
}
|
||||
else
|
||||
{
|
||||
$mkpath = $make_path;
|
||||
}
|
||||
# Find the full pathname of Make. For DOS systems this is more
|
||||
# complicated, so we ask make itself.
|
||||
if ($osname eq 'VMS') {
|
||||
$port_type = 'VMS-DCL' unless defined $ENV{"SHELL"};
|
||||
# On VMS pre-setup make to be found with simply 'make'.
|
||||
$make_path = 'make';
|
||||
} 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
|
||||
# location of the make program gives us a clue. Don't fail if not;
|
||||
# we'll assume it's been installed into /usr/include or wherever.
|
||||
if (! $srcdir) {
|
||||
$make_path =~ /^(.*$pathsep)?/;
|
||||
my $d = $1 || '../';
|
||||
-f "${d}/src/gnumake.h" and $srcdir = $d;
|
||||
}
|
||||
# Ask make what shell to use
|
||||
create_file('shell.mk', 'all:;$(info $(SHELL))');
|
||||
$sh_name = `$make_path -sf shell.mk`;
|
||||
unlink('shell.mk');
|
||||
chop $sh_name;
|
||||
if (! $sh_name) {
|
||||
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
|
||||
if (! $srcdir && open(MF, "< ../Makefile")) {
|
||||
local $/ = undef;
|
||||
$_ = <MF>;
|
||||
close(MF);
|
||||
/^abs_srcdir\s*=\s*(.*?)\s*$/m;
|
||||
-f "$1/src/gnumake.h" and $srcdir = $1;
|
||||
}
|
||||
$string = `$make_path -v`;
|
||||
$string =~ /^(GNU Make [^,\n]*)/ or die "$make_path is not GNU make. Version:\n$string";
|
||||
$testee_version = "$1\n";
|
||||
|
||||
# Get Purify log info--if any.
|
||||
create_file('null.mk', '');
|
||||
|
||||
if (exists $ENV{PURIFYOPTIONS}
|
||||
&& $ENV{PURIFYOPTIONS} =~ /.*-logfile=([^ ]+)/) {
|
||||
$pure_log = $1 || '';
|
||||
$pure_log =~ s/%v/$make_name/;
|
||||
$purify_errors = 0;
|
||||
}
|
||||
my $redir = '2>&1';
|
||||
$redir = '' if os_name eq 'VMS';
|
||||
$string = `$make_path -f null.mk $redir`;
|
||||
if ($string =~ /(.*): \*\*\* No targets\. Stop\./) {
|
||||
$make_name = $1;
|
||||
} else {
|
||||
$make_name = $mpf;
|
||||
}
|
||||
|
||||
$string = `sh -c "$make_path -j 2 -f null.mk $redir"`;
|
||||
if ($string =~ /not supported/) {
|
||||
$parallel_jobs = 0;
|
||||
}
|
||||
else {
|
||||
$parallel_jobs = 1;
|
||||
}
|
||||
# prepend pwd if this is a relative path (ie, does not
|
||||
# start with a slash, but contains one). Thanks for the
|
||||
# clue, Roland.
|
||||
|
||||
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))');
|
||||
%FEATURES = map { $_ => 1 } split /\s+/, `$make_path -sf features.mk`;
|
||||
unlink('features.mk');
|
||||
# Not with the make program, so see if we can get it out of the makefile
|
||||
if (! $srcdir && open(MF, '<', catfile(updir(), 'Makefile'))) {
|
||||
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) {
|
||||
my $args = $valgrind_args;
|
||||
open(VALGRIND, "> valgrind.out")
|
||||
|| 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";
|
||||
}
|
||||
$string = `$make_path -j 2 -f null.mk $redir`;
|
||||
if ($string =~ /not supported/) {
|
||||
$parallel_jobs = 0;
|
||||
}
|
||||
else {
|
||||
$parallel_jobs = 1;
|
||||
}
|
||||
|
||||
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#: $pwd\n";
|
||||
print "#PERL#: $perl_name\n";
|
||||
print "#MAKEPATH#: $mkpath\n";
|
||||
print "#MAKE#: $make_name\n";
|
||||
}
|
||||
unlink('null.mk');
|
||||
|
||||
create_file('features.mk', 'all:;$(info $(.FEATURES))');
|
||||
%FEATURES = map { $_ => 1 } split /\s+/, `$make_path -sf features.mk`;
|
||||
unlink('features.mk');
|
||||
|
||||
# Set up for valgrind, if requested.
|
||||
|
||||
$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
|
||||
|
||||
@@ -14,8 +14,6 @@ $port_type eq 'W32' and return -1;
|
||||
|
||||
# Create some .o files to work with
|
||||
if ($osname eq 'VMS') {
|
||||
use Cwd;
|
||||
my $pwd = getcwd;
|
||||
# VMS AR needs real object files at this time.
|
||||
foreach $afile ('a1', 'a2', 'a3') {
|
||||
# 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.
|
||||
unlink('libxx.a');
|
||||
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.
|
||||
my $add = `$ar $arflags libxx.a a2.o $redir`;
|
||||
@@ -68,7 +67,8 @@ $repl =~ s/a2\.o/#OBJECT#/g;
|
||||
unlink('libxx.a');
|
||||
|
||||
# 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') {
|
||||
$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');
|
||||
if ($osname eq 'VMS') {
|
||||
remove_directory_tree("$pwd/artest");
|
||||
remove_directory_tree("$cwdpath/artest");
|
||||
} else {
|
||||
remove_directory_tree('artest');
|
||||
}
|
||||
@@ -220,7 +220,9 @@ if ($osname ne 'VMS') {
|
||||
my $pre = '1234567890123456';
|
||||
my $lib = 'libxx.a';
|
||||
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!
|
||||
# Both member names > 16 characters long
|
||||
@@ -230,7 +232,7 @@ default: $lib(${pre}a) $lib(${pre}b)
|
||||
|
||||
$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_make_test(undef, $arvar, "#MAKE#: Nothing to be done for 'default'.\n");
|
||||
|
||||
@@ -60,15 +60,36 @@ run_make_test(undef, 'two',
|
||||
|
||||
# Try failing due to non-executable file
|
||||
|
||||
my $noexe = './barfooblatboz';
|
||||
touch($noexe);
|
||||
if ($ERR_nonexe_file) {
|
||||
my $noexe = './barfooblatboz';
|
||||
touch($noexe);
|
||||
|
||||
run_make_test(qq!
|
||||
one: ; -$noexe xx yy
|
||||
two: ; $noexe aa bb
|
||||
run_make_test(qq!
|
||||
one: ; -$noexe xx yy
|
||||
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;
|
||||
|
||||
@@ -9,7 +9,7 @@ $details = "Here we test for requirements like\n"
|
||||
run_make_test(q{
|
||||
.PHONY: all
|
||||
&:;
|
||||
all: ;@echo -n
|
||||
all: ;@printf ''
|
||||
},
|
||||
'', "");
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ include $(F)',
|
||||
# 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.
|
||||
|
||||
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');
|
||||
|
||||
|
||||
@@ -255,6 +255,32 @@ a: ; @echo $(A)
|
||||
!,
|
||||
'', "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
|
||||
|
||||
# run_make_test('
|
||||
|
||||
@@ -13,10 +13,10 @@ open(MAKEFILE,"> $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 $workdir\n";
|
||||
print MAKEFILE "vpath %.c $sourcedir\n";
|
||||
print MAKEFILE "vpath %.c $scriptdir\n";
|
||||
print MAKEFILE "vpath %.h $workdir\n";
|
||||
print MAKEFILE "vpath %.c\n";
|
||||
print MAKEFILE "vpath\n";
|
||||
|
||||
@@ -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
|
||||
names and a variable. Each name in the list is subsituted
|
||||
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";
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
the '*' wildcard as in the first test";
|
||||
|
||||
open(MAKEFILE,"> $makefile");
|
||||
|
||||
# The Contents of the MAKEFILE ...
|
||||
|
||||
print MAKEFILE <<EOM;
|
||||
.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._");
|
||||
touch("example.1");
|
||||
touch("example.two");
|
||||
touch("example.3");
|
||||
touch("example.for");
|
||||
touch("example._");
|
||||
|
||||
# TEST #1
|
||||
# -------
|
||||
|
||||
$answer = "example.1 example.3 example._ example.for example.two\n";
|
||||
|
||||
&run_make_with_options($makefile,"print1",&get_logfile);
|
||||
|
||||
&compare_output($answer,&get_logfile(1));
|
||||
|
||||
run_make_test(qq/
|
||||
.PHONY: print1 print2 clean
|
||||
print1: ;\@echo \$(wildcard example.*)
|
||||
print2:
|
||||
\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
|
||||
# -------
|
||||
|
||||
$answer = "example.1 example.3 example._\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));
|
||||
|
||||
run_make_test(undef, 'print2', "example.1 example.3 example._\n"
|
||||
."example.1 example.3\n"
|
||||
."example.1 example.3\n");
|
||||
|
||||
# TEST #3
|
||||
# -------
|
||||
@@ -73,13 +54,7 @@ else
|
||||
$answer .= "\n";
|
||||
}
|
||||
|
||||
&run_make_with_options($makefile,"clean",&get_logfile);
|
||||
|
||||
if ((-f "example.1")||(-f "example.two")||(-f "example.3")||(-f "example.for")) {
|
||||
$test_passed = 0;
|
||||
}
|
||||
|
||||
&compare_output($answer,&get_logfile(1));
|
||||
run_make_test(undef, 'clean', $answer);
|
||||
|
||||
# TEST #4: Verify that failed wildcards don't return the pattern
|
||||
|
||||
@@ -92,13 +67,65 @@ all: ; @echo $(wildcard xz--y*.7)
|
||||
|
||||
touch('xxx.yyy');
|
||||
|
||||
run_make_test(q!exists: ; @echo file=$(wildcard xxx.yyy)!,
|
||||
'', "file=xxx.yyy\n");
|
||||
run_make_test(q!exists: ; @echo file=$(wildcard xxx.yyy)!, '', "file=xxx.yyy\n");
|
||||
|
||||
unlink('xxx.yyy');
|
||||
|
||||
run_make_test(q!exists: ; @echo file=$(wildcard xxx.yyy)!,
|
||||
'', "file=\n");
|
||||
run_make_test(q!exists: ; @echo file=$(wildcard xxx.yyy)!, '', "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 }) {
|
||||
|
||||
@@ -116,12 +143,15 @@ if ($port_type ne 'W32' && eval { symlink("",""); 1 }) {
|
||||
rmdir($dir);
|
||||
|
||||
# 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;
|
||||
|
||||
@@ -139,7 +139,6 @@ sub xlate
|
||||
s/\\r/\r/g;
|
||||
s/\\t/\t/g;
|
||||
s/\\f/\f/g;
|
||||
s/\\v/\v/g;
|
||||
s/\\n/\n/g;
|
||||
return $_;
|
||||
}
|
||||
|
||||
@@ -79,4 +79,43 @@ all: ; \@echo hi
|
||||
",
|
||||
'', "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;
|
||||
|
||||
@@ -23,9 +23,11 @@ touch($example);
|
||||
|
||||
run_make_with_options("${testname}.mk", "-C $workdir clean", &get_logfile);
|
||||
|
||||
use Cwd;
|
||||
|
||||
chdir $workdir;
|
||||
$wpath = &get_this_pwd;
|
||||
chdir $pwd;
|
||||
$wpath = cwd();
|
||||
chdir $cwdpath;
|
||||
|
||||
if (-f $example) {
|
||||
$test_passed = 0;
|
||||
@@ -49,10 +51,6 @@ touch($example);
|
||||
|
||||
run_make_with_options("${testname}.mk", "-C $workdir/ clean ext=slash", &get_logfile);
|
||||
|
||||
chdir $workdir;
|
||||
$wpath = &get_this_pwd;
|
||||
chdir $pwd;
|
||||
|
||||
if (-f $example) {
|
||||
$test_passed = 0;
|
||||
}
|
||||
|
||||
@@ -50,10 +50,12 @@ $answer = "This is another included makefile\n";
|
||||
&compare_output($answer,&get_logfile(1));
|
||||
|
||||
|
||||
$answer = "$mkpath ANOTHER -f $makefile
|
||||
${make_name}[1]: Entering directory '$pwd'
|
||||
$answer = subst_make_string("$mkpath ANOTHER -f $makefile
|
||||
#MAKE#[1]: Entering directory '#PWD#'
|
||||
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);
|
||||
&compare_output($answer,&get_logfile(1));
|
||||
|
||||
1;
|
||||
|
||||
@@ -11,58 +11,57 @@ $details = "Verify that symlink handling with and without -L works properly.";
|
||||
# check for it explicitly.
|
||||
|
||||
if ($port_type eq 'W32' || !( eval { symlink("",""); 1 })) {
|
||||
# This test is N/A
|
||||
-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;
|
||||
# This test is N/A
|
||||
return -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;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# -*-perl-*-
|
||||
|
||||
$description = "The following test creates a makefile to override part\n"
|
||||
."of one Makefile with Another Makefile with the .DEFAULT\n"
|
||||
."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"
|
||||
."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";
|
||||
print MAKEFILE "\t\@echo Executing rule FOO\n\n";
|
||||
print MAKEFILE ".DEFAULT:\n";
|
||||
print MAKEFILE "\t\@\$(MAKE) -f $makefile2 \$\@ \n";
|
||||
unlink('defsub.mk');
|
||||
|
||||
# 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,20 +1,16 @@
|
||||
# -*-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.";
|
||||
|
||||
open(MAKEFILE,"> $makefile");
|
||||
print MAKEFILE "all: ; \@echo \$(CURDIR)\n";
|
||||
close(MAKEFILE);
|
||||
|
||||
|
||||
# TEST #1
|
||||
# -------
|
||||
|
||||
&run_make_with_options($makefile,"",&get_logfile);
|
||||
$answer = "$pwd\n";
|
||||
&compare_output($answer,&get_logfile(1));
|
||||
|
||||
run_make_test(q!
|
||||
all: ; @echo $(CURDIR)
|
||||
!,
|
||||
'', "#PWD#\n");
|
||||
|
||||
1;
|
||||
|
||||
@@ -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));
|
||||
|
||||
&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));
|
||||
|
||||
&run_make_with_options($makefile2, "$dir/biz", &get_logfile);
|
||||
|
||||
@@ -25,7 +25,7 @@ $mk_string = "text : text.tlb(file1.txt)\n\n" .
|
||||
"file1.txt :\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,
|
||||
'', $answer);
|
||||
@@ -37,10 +37,10 @@ unlink('file1.txt');
|
||||
#Macro library
|
||||
$mk_string = "macro : macro.mlb(file1.mar)\n\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";
|
||||
|
||||
my $answer = "library /replace macro.mlb file1.mar";
|
||||
$answer = "library /replace macro.mlb file1.mar";
|
||||
|
||||
run_make_test($mk_string,
|
||||
'', $answer);
|
||||
@@ -58,7 +58,7 @@ $mk_string =
|
||||
"file2.c :\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,
|
||||
'', $answer);
|
||||
|
||||
1222
tests/test_driver.pl
1222
tests/test_driver.pl
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user