jobs after a failed job.
- Enhancements to WINDOWS32 code from Eli Zaretskii.
- Add Microsoft Project files from J. Grant.
+2005-08-07 Paul D. Smith <psmith@gnu.org>
+
+ * w32/pathstuff.c (getcwd_fs): Fix warning about assignment in a
+ conditional (slightly different version of a fix from Eli).
+
+ Fix a bug reported by Michael Matz <matz@suse.de>: patch included.
+ If make is running in parallel without -k and two jobs die in a
+ row, but not too close to each other, then make will quit without
+ waiting for the rest of the jobs to die.
+
+ * main.c (die): Don't reset err before calling reap_children() the
+ second time: we still want it to be in the error condition.
+ * job.c (reap_children): Use a static variable, rather than err,
+ to control whether or not the error message should be printed.
+
+2005-08-06 Eli Zaretskii <eliz@gnu.org>
+
+ * w32/subproc/sub_proc.c: Include signal.h.
+ (process_pipe_io, process_file_io): Pass a pointer to a local
+ DWORD variable to GetExitCodeProcess. If the exit code is
+ CONTROL_C_EXIT, put SIGINT into pproc->signal.
+
+ * job.c [WINDOWS32]: Include windows.h.
+ (main_thread) [WINDOWS32]: New global variable.
+ (reap_children) [WINDOWS32]: Get the handle for the main thread
+ and store it in main_thread.
+
+ * commands.c [WINDOWS32]: Include windows.h and w32err.h.
+ (fatal_error_signal) [WINDOWS32]: Suspend the main thread before
+ doing anything else. When we are done, close the main thread
+ handle and exit with status 130.
+
+2005-07-30 Eli Zaretskii <eliz@gnu.org>
+
+ * w32/subproc/sub_proc.c (process_begin): Don't pass a NULL
+ pointer to fprintf.
+
+ * main.c (find_and_set_default_shell): If found a DOSish shell,
+ set sh_found and the value of default_shell, and report the
+ findings in debug mode.
+
+ * job.c (construct_command_argv_internal): Check unixy_shell, not
+ no_default_sh_exe, to decide whether to use Unixy or DOSish
+ builtin commands.
+
+ * README.W32: Update with info about the MinGW build.
+
+ * build_w32.bat: Support MinGW.
+
+ * w32/subproc/build.bat: Likewise.
+
+ * w32/subproc/sub_proc.c (process_easy): Fix format strings for
+ printing DWORD args.
+
+ * function.c (windows32_openpipe): Fix format strings for printing
+ DWORD args.
+
+ * job.c (reap_children) [WINDOWS32]: Don't declare 'status' and
+ 'reap_mode'.
+ (start_job_command): Fix format string for printing the result of
+ process_easy.
+ (start_job_command) [WINDOWS32]: Do not define.
+ (exec_command): Fix format string for printing HANDLE args.
+
+ * main.c (handle_runtime_exceptions): Fix sprintf format strings
+ to avoid compiler warnings.
+ (open_tmpfile): Declare fd only if HAVE_FDOPEN is defined.
+ (Note: some of these fixes were submitted independently by J. Grant)
+
+2005-07-30 J. Grant <jg@jguk.org>
+
+ * prepare_w32.bat: Copy config.h.w32 to config.h if not exist.
+ * make_msvc_net2003.vcproj, make_msvc_net2003.sln: MSVC Project files.
+ * Makefile.am (EXTRA_DIST): Add MSVC Project files.
+
2005-07-08 Paul D. Smith <psmith@gnu.org>
* config.h.W32.template: Reorder to match the standard config.h,
README.Amiga Makefile.ami config.ami make.lnk amiga.c amiga.h \
README.DOS Makefile.DOS configure.bat dosbuild.bat configh.dos\
README.W32 NMakefile config.h.W32 build_w32.bat subproc.bat \
+ make_msvc_net2003.sln make_msvc_net2003.vcproj \
readme.vms makefile.vms makefile.com config.h-vms \
vmsdir.h vmsfunctions.c vmsify.c
Port of GNU make to Microsoft Windows 95/98/NT/2000/XP
Builds natively with MSVC 2.x, 4.x, 5.x, 6.x and MSVC.NET 7.x.
+Also builds with the MinGW port of GCC 3.x (tested with GCC 3.4.2).
The Windows 32-bit port of GNU make is maintained jointly by various
-people.
+people. It was originally made by Rob Tulloh.
-To build with nmake on MS-Windows:
+To build with MinGW:
+
+ 1. Edit config.h.W32 to your liking (especially the few
+ shell-related defines near the end).
+
+ 2. Invoke build_w32.bat with the "gcc" argument:
+
+ build_w32 gcc
+
+ This produces gnumake.exe in the current directory.
+
+To build with nmake:
1. Make sure cl.exe is in your %Path%. Example:
-set make=gnumake\r
if not exist config.h copy config.h.W32 config.h\r
cd w32\subproc\r
-echo "Creating the subproc library"\r
-%ComSpec% /c build.bat\r
+@echo "Creating the subproc library"\r
+%ComSpec% /c build.bat %1\r
cd ..\..\r
-del link.dbg link.rel\r
-del config.h\r
-copy config.h.W32 config.h\r
-echo off\r
-echo "Creating GNU make for Windows 95/NT"\r
+@echo off\r
+if exist link.dbg del link.dbg\r
+if exist link.rel del link.rel\r
+echo "Creating GNU Make for Windows 9X/NT/2K/XP"\r
+if "%1" == "gcc" GoTo GCCBuild\r
+set make=gnumake\r
echo on\r
if not exist .\WinDebug\nul mkdir .\WinDebug\r
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D TIVOLI /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c variable.c\r
link.exe /NOLOGO /SUBSYSTEM:console /INCREMENTAL:no /PDB:.\WinRel/%make%.pdb /MACHINE:I386 /OUT:.\WinRel/%make%.exe @link.rel\r
if not exist .\WinRel/%make%.exe echo "WinRel build failed"\r
if exist .\WinRel/%make%.exe echo "WinRel build succeeded!"\r
+set make=\r
+GoTo BuildEnd\r
+:GCCBuild\r
+echo on\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c variable.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c rule.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c remote-stub.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c commands.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c file.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c getloadavg.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c default.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c signame.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c expand.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c dir.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c main.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c getopt1.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c job.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c read.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c version.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c getopt.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c arscan.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c remake.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c hash.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c misc.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c ar.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c function.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c vpath.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c implicit.c\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c ./glob/glob.c -o glob.o\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c ./glob/fnmatch.c -o fnmatch.o\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c ./w32/pathstuff.c -o pathstuff.o\r
+gcc -mthreads -gstabs+ -ggdb3 -o gnumake.exe variable.o rule.o remote-stub.o commands.o file.o getloadavg.o default.o signame.o expand.o dir.o main.o getopt1.o job.o read.o version.o getopt.o arscan.o remake.o misc.o hash.o ar.o function.o vpath.o implicit.o glob.o fnmatch.o pathstuff.o w32_misc.o sub_proc.o w32err.o -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -luuid -lodbc32 -lodbccp32\r
+:BuildEnd\r
echo on\r
#include "variable.h"
#include "job.h"
#include "commands.h"
+#ifdef WINDOWS32
+#include <windows.h>
+#include "w32err.h"
+#endif
#if VMS
# define FILE_LIST_SEPARATOR ','
exit (10);
#else /* not Amiga */
+#ifdef WINDOWS32
+ extern HANDLE main_thread;
+
+ /* Windows creates a sperate thread for handling Ctrl+C, so we need
+ to suspend the main thread, or else we will have race conditions
+ when both threads call reap_children. */
+ if (main_thread)
+ {
+ DWORD susp_count = SuspendThread (main_thread);
+
+ if (susp_count != 0)
+ fprintf (stderr, "SuspendThread: suspend count = %ld\n", susp_count);
+ else if (susp_count == (DWORD)-1)
+ {
+ DWORD ierr = GetLastError ();
+
+ fprintf (stderr, "SuspendThread: error %ld: %s\n",
+ ierr, map_windows32_error_to_string (ierr));
+ }
+ }
+#endif
handling_fatal_signal = 1;
/* Set the handling for this signal to the default.
#endif
#ifdef WINDOWS32
- /* Cannot call W32_kill with a pid (it needs a handle) */
- exit (EXIT_FAILURE);
+ if (main_thread)
+ CloseHandle (main_thread);
+ /* Cannot call W32_kill with a pid (it needs a handle). The exit
+ status of 130 emulates what happens in Bash. */
+ exit (130);
#else
/* Signal the same code; this time it will really be fatal. The signal
will be unblocked when we return and arrive then to kill us. */
making it a simply-expanded variable, @samp{+=} adds to that
simply-expanded definition, and expands the new text before appending it
to the old value just as @samp{:=} does
-(@pxref{Setting, ,Setting Variables}, for a full explanation of @samp{:=}).
+(@pxref{Setting, ,Setting Variables} for a full explanation of @samp{:=}).
In fact,
@example
0,
TRUE,
DUPLICATE_SAME_ACCESS) == FALSE) {
- fatal (NILF, _("create_child_process: DuplicateHandle(In) failed (e=%d)\n"),
+ fatal (NILF, _("create_child_process: DuplicateHandle(In) failed (e=%ld)\n"),
GetLastError());
}
0,
TRUE,
DUPLICATE_SAME_ACCESS) == FALSE) {
- fatal (NILF, _("create_child_process: DuplicateHandle(Err) failed (e=%d)\n"),
+ fatal (NILF, _("create_child_process: DuplicateHandle(Err) failed (e=%ld)\n"),
GetLastError());
}
if (!CreatePipe(&hChildOutRd, &hChildOutWr, &saAttr, 0))
- fatal (NILF, _("CreatePipe() failed (e=%d)\n"), GetLastError());
+ fatal (NILF, _("CreatePipe() failed (e=%ld)\n"), GetLastError());
hProcess = process_init_fd(hIn, hChildOutWr, hErr);
/* Default shell to use. */
#ifdef WINDOWS32
+#include <windows.h>
char *default_shell = "sh.exe";
int no_default_sh_exe = 1;
int batch_mode_shell = 1;
+HANDLE main_thread;
#elif defined (_AMIGA)
void
reap_children (int block, int err)
{
+#ifndef WINDOWS32
WAIT_T status;
/* Initially, assume we have some. */
int reap_more = 1;
+#endif
#ifdef WAIT_NOHANG
# define REAP_MORE reap_more
if (err && block)
{
- /* We might block for a while, so let the user know why. */
+ static int printed = 0;
+
+ /* We might block for a while, so let the user know why.
+ Only print this message once no matter how many jobs are left. */
fflush (stdout);
- error (NILF, _("*** Waiting for unfinished jobs...."));
+ if (!printed)
+ error (NILF, _("*** Waiting for unfinished jobs...."));
+ printed = 1;
}
/* We have one less dead child to reap. As noted in
#ifdef WINDOWS32
{
HANDLE hPID;
- int err;
+ int werr;
+ HANDLE hcTID, hcPID;
exit_code = 0;
exit_sig = 0;
coredump = 0;
+ /* Record the thread ID of the main process, so that we
+ could suspend it in the signal handler. */
+ if (!main_thread)
+ {
+ hcTID = GetCurrentThread ();
+ hcPID = GetCurrentProcess ();
+ if (!DuplicateHandle (hcPID, hcTID, hcPID, &main_thread, 0,
+ FALSE, DUPLICATE_SAME_ACCESS))
+ {
+ DWORD e = GetLastError ();
+ fprintf (stderr,
+ "Determine main thread ID (Error %ld: %s)\n",
+ e, map_windows32_error_to_string(e));
+ }
+ else
+ DB (DB_VERBOSE, ("Main thread handle = 0x%08lx\n",
+ (unsigned long)main_thread));
+ }
+
/* wait for anything to finish */
hPID = process_wait_for_any();
if (hPID)
{
/* was an error found on this process? */
- err = process_last_err(hPID);
+ werr = process_last_err(hPID);
/* get exit data */
exit_code = process_exit_code(hPID);
- if (err)
+ if (werr)
fprintf(stderr, "make (e=%d): %s",
exit_code, map_windows32_error_to_string(exit_code));
static void
start_job_command (struct child *child)
{
-#ifndef _AMIGA
+#if !defined(_AMIGA) && !defined(WINDOWS32)
static int bad_stdin = -1;
#endif
register char *p;
int i;
unblock_sigs();
fprintf(stderr,
- _("process_easy() failed failed to launch process (e=%d)\n"),
+ _("process_easy() failed failed to launch process (e=%ld)\n"),
process_last_err(hPID));
for (i = 0; argv[i]; i++)
fprintf(stderr, "%s ", argv[i]);
{
int i;
fprintf(stderr,
- _("process_easy() failed failed to launch process (e=%d)\n"),
+ _("process_easy() failed failed to launch process (e=%ld)\n"),
process_last_err(hPID));
for (i = 0; argv[i]; i++)
fprintf(stderr, "%s ", argv[i]);
#ifdef WINDOWS32
int slow_flag = 0;
- if (no_default_sh_exe) {
+ if (!unixy_shell) {
sh_cmds = sh_cmds_dos;
sh_chars = sh_chars_dos;
} else {
else if (p[1] != '\0')
{
#ifdef HAVE_DOS_PATHS
- /* Only remove backslashes before characters special
- to Unixy shells. All other backslashes are copied
- verbatim, since they are probably DOS-style
- directory separators. This still leaves a small
- window for problems, but at least it should work
- for the vast majority of naive users. */
+ /* Only remove backslashes before characters special to Unixy
+ shells. All other backslashes are copied verbatim, since
+ they are probably DOS-style directory separators. This
+ still leaves a small window for problems, but at least it
+ should work for the vast majority of naive users. */
#ifdef __MSDOS__
/* A dot is only special as part of the "..."
#endif
if (p[1] != '\\' && p[1] != '\''
&& !isspace ((unsigned char)p[1])
- && (strchr (sh_chars_sh, p[1]) == 0))
+ && strchr (sh_chars_sh, p[1]) == 0)
/* back up one notch, to copy the backslash */
--p;
#endif /* HAVE_DOS_PATHS */
if (! ISDB (DB_VERBOSE))
{
sprintf(errmsg,
- _("%s: Interrupt/Exception caught (code = 0x%x, addr = 0x%x)\n"),
+ _("%s: Interrupt/Exception caught (code = 0x%lx, addr = 0x%lx)\n"),
prg, exrec->ExceptionCode, exrec->ExceptionAddress);
fprintf(stderr, errmsg);
exit(255);
}
sprintf(errmsg,
- _("\nUnhandled exception filter called from program %s\nExceptionCode = %x\nExceptionFlags = %x\nExceptionAddress = %x\n"),
+ _("\nUnhandled exception filter called from program %s\nExceptionCode = %lx\nExceptionFlags = %lx\nExceptionAddress = %lx\n"),
prg, exrec->ExceptionCode, exrec->ExceptionFlags,
exrec->ExceptionAddress);
&& exrec->NumberParameters >= 2)
sprintf(&errmsg[strlen(errmsg)],
(exrec->ExceptionInformation[0]
- ? _("Access violation: write operation at address %x\n")
- : _("Access violation: read operation at address %x\n")),
+ ? _("Access violation: write operation at address %lx\n")
+ : _("Access violation: read operation at address %lx\n")),
exrec->ExceptionInformation[1]);
/* turn this on if we want to put stuff in the event log too */
&& !strcmpi (tokend - 4, "cmd.exe"))) {
batch_mode_shell = 1;
unixy_shell = 0;
- sh_found = 0;
+ sprintf (sh_path, "%s", search_token);
+ default_shell = xstrdup (w32ify (sh_path, 0));
+ DB (DB_VERBOSE,
+ (_("find_and_set_shell setting default_shell = %s\n"), default_shell));
+ sh_found = 1;
} else if (!no_default_sh_exe &&
(token == NULL || !strcmp (search_token, default_shell))) {
/* no new information, path already set or known */
FILE *
open_tmpfile(char **name, const char *template)
{
+#ifdef HAVE_FDOPEN
int fd;
+#endif
#if defined HAVE_MKSTEMP || defined HAVE_MKTEMP
# define TEMPLATE_LEN strlen (template)
decode_switches (argc, argv, 0);
#ifdef WINDOWS32
if (suspend_flag) {
- fprintf(stderr, "%s (pid = %d)\n", argv[0], GetCurrentProcessId());
+ fprintf(stderr, "%s (pid = %ld)\n", argv[0], GetCurrentProcessId());
fprintf(stderr, _("%s is suspending for 30 seconds..."), argv[0]);
Sleep(30 * 1000);
fprintf(stderr, _("done sleep(30). Continuing.\n"));
print_version ();
/* Wait for children to die. */
- for (err = (status != 0); job_slots_used > 0; err = 0)
+ err = (status != 0);
+ while (job_slots_used > 0)
reap_children (1, err);
/* Let the remote job module clean up its state. */
--- /dev/null
+Microsoft Visual Studio Solution File, Format Version 8.00\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "make_msvc.net2003", "make_msvc_net2003.vcproj", "{E96B5060-3240-4723-91C9-E64F1C877A04}"\r
+ ProjectSection(ProjectDependencies) = postProject\r
+ EndProjectSection\r
+EndProject\r
+Global\r
+ GlobalSection(SolutionConfiguration) = preSolution\r
+ Debug = Debug\r
+ Release = Release\r
+ EndGlobalSection\r
+ GlobalSection(ProjectConfiguration) = postSolution\r
+ {E96B5060-3240-4723-91C9-E64F1C877A04}.Debug.ActiveCfg = Debug|Win32\r
+ {E96B5060-3240-4723-91C9-E64F1C877A04}.Debug.Build.0 = Debug|Win32\r
+ {E96B5060-3240-4723-91C9-E64F1C877A04}.Release.ActiveCfg = Release|Win32\r
+ {E96B5060-3240-4723-91C9-E64F1C877A04}.Release.Build.0 = Release|Win32\r
+ EndGlobalSection\r
+ GlobalSection(ExtensibilityGlobals) = postSolution\r
+ EndGlobalSection\r
+ GlobalSection(ExtensibilityAddIns) = postSolution\r
+ EndGlobalSection\r
+EndGlobal\r
--- /dev/null
+<?xml version="1.0" encoding="Windows-1252"?>\r
+<VisualStudioProject\r
+ ProjectType="Visual C++"\r
+ Version="7.10"\r
+ Name="make_msvc.net2003"\r
+ ProjectGUID="{E96B5060-3240-4723-91C9-E64F1C877A04}"\r
+ Keyword="Win32Proj">\r
+ <Platforms>\r
+ <Platform\r
+ Name="Win32"/>\r
+ </Platforms>\r
+ <Configurations>\r
+ <Configuration\r
+ Name="Debug|Win32"\r
+ OutputDirectory="Debug"\r
+ IntermediateDirectory="Debug"\r
+ ConfigurationType="1"\r
+ CharacterSet="2">\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="0"\r
+ AdditionalIncludeDirectories=".;w32/include;glob"\r
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;HAVE_CONFIG_H=1;WINDOWS32=1"\r
+ MinimalRebuild="TRUE"\r
+ BasicRuntimeChecks="3"\r
+ RuntimeLibrary="1"\r
+ ForceConformanceInForLoopScope="TRUE"\r
+ UsePrecompiledHeader="0"\r
+ WarningLevel="4"\r
+ Detect64BitPortabilityProblems="TRUE"\r
+ DebugInformationFormat="4"/>\r
+ <Tool\r
+ Name="VCCustomBuildTool"/>\r
+ <Tool\r
+ Name="VCLinkerTool"\r
+ OutputFile="$(OutDir)/make_msvc.net2003.exe"\r
+ LinkIncremental="2"\r
+ GenerateDebugInformation="TRUE"\r
+ ProgramDatabaseFile="$(OutDir)/make_msvc.net2003.pdb"\r
+ SubSystem="1"\r
+ TargetMachine="1"/>\r
+ <Tool\r
+ Name="VCMIDLTool"/>\r
+ <Tool\r
+ Name="VCPostBuildEventTool"/>\r
+ <Tool\r
+ Name="VCPreBuildEventTool"/>\r
+ <Tool\r
+ Name="VCPreLinkEventTool"/>\r
+ <Tool\r
+ Name="VCResourceCompilerTool"/>\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"/>\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"/>\r
+ <Tool\r
+ Name="VCWebDeploymentTool"/>\r
+ <Tool\r
+ Name="VCManagedWrapperGeneratorTool"/>\r
+ <Tool\r
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Release|Win32"\r
+ OutputDirectory="Release"\r
+ IntermediateDirectory="Release"\r
+ ConfigurationType="1"\r
+ CharacterSet="2">\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ AdditionalIncludeDirectories=".;w32/include;glob"\r
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;HAVE_CONFIG_H=1;WINDOWS32=1"\r
+ RuntimeLibrary="0"\r
+ ForceConformanceInForLoopScope="TRUE"\r
+ UsePrecompiledHeader="0"\r
+ WarningLevel="4"\r
+ Detect64BitPortabilityProblems="TRUE"\r
+ DebugInformationFormat="3"/>\r
+ <Tool\r
+ Name="VCCustomBuildTool"/>\r
+ <Tool\r
+ Name="VCLinkerTool"\r
+ OutputFile="$(OutDir)/make_msvc.net2003.exe"\r
+ LinkIncremental="1"\r
+ GenerateDebugInformation="TRUE"\r
+ SubSystem="1"\r
+ OptimizeReferences="2"\r
+ EnableCOMDATFolding="2"\r
+ TargetMachine="1"/>\r
+ <Tool\r
+ Name="VCMIDLTool"/>\r
+ <Tool\r
+ Name="VCPostBuildEventTool"/>\r
+ <Tool\r
+ Name="VCPreBuildEventTool"/>\r
+ <Tool\r
+ Name="VCPreLinkEventTool"/>\r
+ <Tool\r
+ Name="VCResourceCompilerTool"/>\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"/>\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"/>\r
+ <Tool\r
+ Name="VCWebDeploymentTool"/>\r
+ <Tool\r
+ Name="VCManagedWrapperGeneratorTool"/>\r
+ <Tool\r
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>\r
+ </Configuration>\r
+ </Configurations>\r
+ <References>\r
+ </References>\r
+ <Files>\r
+ <Filter\r
+ Name="src"\r
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">\r
+ <File\r
+ RelativePath=".\ar.c">\r
+ </File>\r
+ <File\r
+ RelativePath=".\arscan.c">\r
+ </File>\r
+ <File\r
+ RelativePath=".\commands.c">\r
+ </File>\r
+ <File\r
+ RelativePath=".\default.c">\r
+ </File>\r
+ <File\r
+ RelativePath=".\dir.c">\r
+ </File>\r
+ <File\r
+ RelativePath=".\expand.c">\r
+ </File>\r
+ <File\r
+ RelativePath=".\file.c">\r
+ </File>\r
+ <File\r
+ RelativePath=".\function.c">\r
+ </File>\r
+ <File\r
+ RelativePath=".\getloadavg.c">\r
+ </File>\r
+ <File\r
+ RelativePath=".\getopt.c">\r
+ </File>\r
+ <File\r
+ RelativePath=".\getopt1.c">\r
+ </File>\r
+ <File\r
+ RelativePath=".\hash.c">\r
+ </File>\r
+ <File\r
+ RelativePath=".\implicit.c">\r
+ </File>\r
+ <File\r
+ RelativePath=".\job.c">\r
+ </File>\r
+ <File\r
+ RelativePath=".\main.c">\r
+ </File>\r
+ <File\r
+ RelativePath=".\misc.c">\r
+ </File>\r
+ <File\r
+ RelativePath=".\read.c">\r
+ </File>\r
+ <File\r
+ RelativePath=".\remake.c">\r
+ </File>\r
+ <File\r
+ RelativePath=".\remote-stub.c">\r
+ </File>\r
+ <File\r
+ RelativePath=".\rule.c">\r
+ </File>\r
+ <File\r
+ RelativePath=".\signame.c">\r
+ </File>\r
+ <File\r
+ RelativePath=".\variable.c">\r
+ </File>\r
+ <File\r
+ RelativePath=".\version.c">\r
+ </File>\r
+ <File\r
+ RelativePath=".\vpath.c">\r
+ </File>\r
+ <Filter\r
+ Name="w32"\r
+ Filter="">\r
+ <File\r
+ RelativePath=".\w32\compat\dirent.c">\r
+ </File>\r
+ <File\r
+ RelativePath=".\w32\subproc\misc.c">\r
+ <FileConfiguration\r
+ Name="Debug|Win32">\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ ObjectFile="$(IntDir)/$(InputName)1.obj"/>\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Release|Win32">\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ ObjectFile="$(IntDir)/$(InputName)1.obj"/>\r
+ </FileConfiguration>\r
+ </File>\r
+ <File\r
+ RelativePath=".\w32\pathstuff.c">\r
+ </File>\r
+ <File\r
+ RelativePath=".\w32\subproc\sub_proc.c">\r
+ </File>\r
+ <File\r
+ RelativePath=".\w32\subproc\w32err.c">\r
+ </File>\r
+ </Filter>\r
+ <Filter\r
+ Name="glob"\r
+ Filter="">\r
+ <File\r
+ RelativePath=".\glob\fnmatch.c">\r
+ </File>\r
+ <File\r
+ RelativePath=".\glob\glob.c">\r
+ </File>\r
+ </Filter>\r
+ </Filter>\r
+ <Filter\r
+ Name="include"\r
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"\r
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">\r
+ <File\r
+ RelativePath=".\commands.h">\r
+ </File>\r
+ <File\r
+ RelativePath=".\config.h">\r
+ </File>\r
+ <File\r
+ RelativePath=".\debug.h">\r
+ </File>\r
+ <File\r
+ RelativePath=".\dep.h">\r
+ </File>\r
+ <File\r
+ RelativePath=".\filedef.h">\r
+ </File>\r
+ <File\r
+ RelativePath=".\getopt.h">\r
+ </File>\r
+ <File\r
+ RelativePath=".\gettext.h">\r
+ </File>\r
+ <File\r
+ RelativePath=".\hash.h">\r
+ </File>\r
+ <File\r
+ RelativePath=".\job.h">\r
+ </File>\r
+ <File\r
+ RelativePath=".\make.h">\r
+ </File>\r
+ <File\r
+ RelativePath=".\rule.h">\r
+ </File>\r
+ <File\r
+ RelativePath=".\variable.h">\r
+ </File>\r
+ <File\r
+ RelativePath=".\vmsdir.h">\r
+ </File>\r
+ <Filter\r
+ Name="w32"\r
+ Filter="">\r
+ <File\r
+ RelativePath=".\w32\include\dirent.h">\r
+ </File>\r
+ <File\r
+ RelativePath=".\w32\include\pathstuff.h">\r
+ </File>\r
+ <File\r
+ RelativePath=".\w32\subproc\proc.h">\r
+ </File>\r
+ <File\r
+ RelativePath=".\w32\include\sub_proc.h">\r
+ </File>\r
+ <File\r
+ RelativePath=".\w32\include\w32err.h">\r
+ </File>\r
+ </Filter>\r
+ <Filter\r
+ Name="glob"\r
+ Filter="">\r
+ <File\r
+ RelativePath=".\glob\fnmatch.h">\r
+ </File>\r
+ <File\r
+ RelativePath=".\glob\glob.h">\r
+ </File>\r
+ </Filter>\r
+ </Filter>\r
+ </Files>\r
+ <Globals>\r
+ </Globals>\r
+</VisualStudioProject>\r
@echo off\r
@echo Windows32 CVS build preparation of config.h.W32 and NMakefile.\r
if not exist config.h.W32 copy config.h.W32.template config.h.W32\r
+if not exist config.h copy config.h.W32 config.h\r
if not exist NMakefile copy NMakefile.template NMakefile\r
@echo Preparation complete. Run build_w32.bat to compile and link.\r
d_ptr = &(*d_ptr)->next;
if (cmds != 0)
- {
- /* This is the rule with commands, so put its deps
- last. The rationale behind this is that $< expands
- to the first dep in the chain, and commands use $<
- expecting to get the dep that rule specifies.
- However the second expansion algorithm reverses
- the order thus we need to make it last here. */
-
- (*d_ptr)->next = this;
- }
+ /* This is the rule with commands, so put its deps
+ last. The rationale behind this is that $< expands to
+ the first dep in the chain, and commands use $<
+ expecting to get the dep that rule specifies. However
+ the second expansion algorithm reverses the order thus
+ we need to make it last here. */
+ (*d_ptr)->next = this;
else
{
/* This is the rule without commands. Put its
- dependencies at the end but before dependencies
- from the rule with commands (if any). This way
- everything appears in makefile order. */
+ dependencies at the end but before dependencies from
+ the rule with commands (if any). This way everything
+ appears in makefile order. */
if (f->cmds != 0)
{
# define sys_siglist _sys_siglist
# elif HAVE_DECL___SYS_SIGLIST
# define sys_siglist __sys_siglist
-# endif
+# else
static char sig_initted = 0;
if (!sig_initted)
sig_initted = signame_init ();
+# endif
#endif
if (signal > 0 || signal < NSIG)
+2005-08-07 Paul D. Smith <psmith@gnu.org>
+
+ * scripts/features/parallelism: Add a test for a bug reported by
+ Michael Matz (matz@suse.de) in which make exits without waiting
+ for all its children in some situations during parallel builds.
+
2005-07-08 Paul D. Smith <psmith@gnu.org>
* test_driver.pl: Reset the environment to a clean value every
first second: ; \@echo \$\@; $sleep_command 1; echo \$\@",
'-j2', "first\nfirst\nsecond\nsecond");
+# Michael Matz <matz@suse.de> reported a bug where if make is running in
+# parallel without -k and two jobs die in a row, but not too close to each
+# other, then make will quit without waiting for the rest of the jobs to die.
+
+run_make_test("
+.PHONY: all fail.1 fail.2 fail.3 ok
+all: fail.1 ok fail.2 fail.3
+
+fail.1 fail.2 fail.3:
+ \@sleep \$(patsubst fail.%,%,\$\@)
+ \@echo Fail
+ \@exit 1
+
+ok:
+ \@sleep 4
+ \@echo Ok done",
+ '-rR -j5', 'Fail
+#MAKE#: *** [fail.1] Error 1
+#MAKE#: *** Waiting for unfinished jobs....
+Fail
+#MAKE#: *** [fail.2] Error 1
+Fail
+#MAKE#: *** [fail.3] Error 1
+Ok done',
+ 512);
+
+
1;
char *
getcwd_fs(char* buf, int len)
{
- char *p;
+ char *p = getcwd(buf, len);
- if (p = getcwd(buf, len)) {
+ if (p) {
char *q = w32ify(buf, 0);
strncpy(buf, q, len);
}
+@if "%1" == "gcc" GoTo GCCBuild\r
if not exist .\WinDebug\nul mkdir .\WinDebug\r
cl.exe /nologo /MT /W4 /GX /Z7 /YX /Od /I .. /I . /I ../include /D WIN32 /D WINDOWS32 /D _DEBUG /D _WINDOWS /FR.\WinDebug/ /Fp.\WinDebug/subproc.pch /Fo.\WinDebug/ /c misc.c\r
cl.exe /nologo /MT /W4 /GX /Z7 /YX /Od /I .. /I . /I ../include /I ../.. /D WIN32 /D WINDOWS32 /D _DEBUG /D _WINDOWS /FR.\WinDebug/ /Fp.\WinDebug/subproc.pch /Fo.\WinDebug/ /c sub_proc.c\r
cl.exe /nologo /MT /W4 /GX /YX /O2 /I ../include /I ../.. /D WIN32 /D WINDOWS32 /D NDEBUG /D _WINDOWS /FR.\WinRel/ /Fp.\WinRel/subproc.pch /Fo.\WinRel/ /c sub_proc.c\r
cl.exe /nologo /MT /W4 /GX /YX /O2 /I ../include /D WIN32 /D WINDOWS32 /D NDEBUG /D _WINDOWS /FR.\WinRel/ /Fp.\WinRel/subproc.pch /Fo.\WinRel/ /c w32err.c\r
lib.exe /NOLOGO /OUT:.\WinRel\subproc.lib .\WinRel/misc.obj .\WinRel/sub_proc.obj .\WinRel/w32err.obj\r
+GoTo BuildEnd\r
+:GCCBuild\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I.. -I. -I../include -I../.. -DWINDOWS32 -c misc.c -o ../../w32_misc.o\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I.. -I. -I../include -I../.. -DWINDOWS32 -c sub_proc.c -o ../../sub_proc.o\r
+gcc -mthreads -Wall -gstabs+ -ggdb3 -O2 -I.. -I. -I../include -I../.. -DWINDOWS32 -c w32err.c -o ../../w32err.o\r
+:BuildEnd\r
#include <stdlib.h>
#include <stdio.h>
#include <process.h> /* for msvc _beginthreadex, _endthreadex */
+#include <signal.h>
#include <windows.h>
#include "sub_proc.h"
pproc->last_err = GetLastError();
pproc->lerrno = E_FORK;
- fprintf(stderr, "process_begin: CreateProcess(%s, %s, ...) failed.\n", exec_path, command_line);
+ fprintf(stderr, "process_begin: CreateProcess(%s, %s, ...) failed.\n",
+ exec_path ? exec_path : "NULL", command_line);
if (envblk) free(envblk);
free( command_line );
return(-1);
} else if (ready_hand == childhand) {
- GetExitCodeResult = GetExitCodeProcess(childhand, (DWORD*)&pproc->exit_code);
+ DWORD ierr;
+ GetExitCodeResult = GetExitCodeProcess(childhand, &ierr);
+ if (ierr == CONTROL_C_EXIT) {
+ pproc->signal = SIGINT;
+ } else {
+ pproc->exit_code = ierr;
+ }
if (GetExitCodeResult == FALSE) {
pproc->last_err = GetLastError();
pproc->lerrno = E_SCALL;
HANDLE childhand;
DWORD wait_return;
BOOL GetExitCodeResult;
+ DWORD ierr;
if (proc == NULL)
pproc = process_wait_for_any_private();
goto done2;
}
- GetExitCodeResult = GetExitCodeProcess(childhand, (DWORD*)&pproc->exit_code);
+ GetExitCodeResult = GetExitCodeProcess(childhand, &ierr);
+ if (ierr == CONTROL_C_EXIT) {
+ pproc->signal = SIGINT;
+ } else {
+ pproc->exit_code = ierr;
+ }
if (GetExitCodeResult == FALSE) {
pproc->last_err = GetLastError();
pproc->lerrno = E_SCALL;
TRUE,
DUPLICATE_SAME_ACCESS) == FALSE) {
fprintf(stderr,
- "process_easy: DuplicateHandle(In) failed (e=%d)\n",
+ "process_easy: DuplicateHandle(In) failed (e=%ld)\n",
GetLastError());
return INVALID_HANDLE_VALUE;
}
TRUE,
DUPLICATE_SAME_ACCESS) == FALSE) {
fprintf(stderr,
- "process_easy: DuplicateHandle(Out) failed (e=%d)\n",
+ "process_easy: DuplicateHandle(Out) failed (e=%ld)\n",
GetLastError());
return INVALID_HANDLE_VALUE;
}
TRUE,
DUPLICATE_SAME_ACCESS) == FALSE) {
fprintf(stderr,
- "process_easy: DuplicateHandle(Err) failed (e=%d)\n",
+ "process_easy: DuplicateHandle(Err) failed (e=%ld)\n",
GetLastError());
return INVALID_HANDLE_VALUE;
}