Compare commits

..

50 Commits
3.71 ... 3.71.2

Author SHA1 Message Date
Roland McGrath
dc44a79020 Add HAVE_SYS_SIGLIST and HAVE__SYS_SIGLIST. 1994-09-09 07:16:54 +00:00
Roland McGrath
8ed6e13cfe (Archive Suffix Rules): Remove Next pointer. 1994-09-09 06:59:08 +00:00
Roland McGrath
b321e0f535 (decode_switches): The non-option return from getopt is 1, not 0.
(command_variables): New type and variable.
(decode_switches, decode_env_switches): After making a variable definition,
record the struct variable pointer in the command_variables chain.
(define_makeflags): If ALL, write variable definitions for
command_variables.
1994-09-09 06:45:51 +00:00
Roland McGrath
c1433e9495 (other_args): Variable removed.
(goals, lastgoal): New static variables (moved from auto in main).
(main): Don't process OTHER_ARGS at all.
Don't set variable MAKEOVERRIDES at all; define MAKE to just $(MAKE_COMMAND).
(init_switches): Prepend a - (return in order) instead of a + (require order).
(decode_switches): Don't set OTHER_ARGS at all.
Grok '\0' return from getopt_long as non-option argument; try variable
definition and (if !ENV) enter goal targets here.
(decode_env_switches): Use allocated_variable_expand to store value.
Use find_next_token to simplify word-splitting loop.
Don't prepend a dash to uninterpreted value.
Instead, if split into only one word, try variable definition and failing
that prepend a dash to the word and pass it to decode_switches as a single arg.
1994-09-09 05:37:40 +00:00
Roland McGrath
e4a94e0210 (notice_finished_file): Only recheck modtimes if FILE->command_state was
cs_running on entry (meaning the commands actually just ran).
(update_file_1): Whenever we set FILE->update_status, call
notice_finished_file instead of just set_command_state.
1994-09-07 07:06:46 +00:00
Roland McGrath
9e97330bcb (start_job_command): Whenever we set CHILD->file->update_status, call
notice_finished_file instead of just set_command_state.
1994-09-07 07:02:23 +00:00
Roland McGrath
4969b416b8 (set_command_state): Actually set FILE->command_state. 1994-09-07 00:31:13 +00:00
Roland McGrath
0bd0301ae3 (set_command_state): Fix typo. 1994-09-07 00:24:10 +00:00
Roland McGrath
ff6efbadf5 (set_command_state): Declare D. 1994-09-07 00:17:57 +00:00
Roland McGrath
0b3317d2e1 Add missing ". 1994-09-07 00:15:23 +00:00
Roland McGrath
ca5a872280 Changed all assignments of command_state members to calls to
set_command_state.
1994-09-07 00:04:49 +00:00
Roland McGrath
4244f182f2 (set_command_state): New function. 1994-09-07 00:02:25 +00:00
Roland McGrath
be6e6d74bb Declare set_command_state. 1994-09-06 23:48:36 +00:00
Roland McGrath
4c0fef3dd7 (init_switches): Put a + first in options. 1994-09-06 23:13:43 +00:00
Richard M. Stallman
d3b65c3cb7 entered into RCS 1994-08-21 17:29:57 +00:00
gnu
bc48185f8e Formerly make-stds.texi.~29~ 1994-08-10 05:41:00 +00:00
Roland McGrath
6fcf219fa7 Initial revision 1994-07-25 23:47:05 +00:00
Roland McGrath
d2e23eefd2 Added trailing CRs. 1994-07-25 23:46:16 +00:00
Roland McGrath
55162a6730 Changed all uses of ':' to PATH_SEPARATOR_CHAR. 1994-07-25 23:34:32 +00:00
Roland McGrath
021ea7e61c (directory_before_chdir): New variable, moved out of main (was local).
(main) [__MSDOS__]: Look for \ or : to delimit last component of PROGRAM.
Don't frob ARGV[0] before setting MAKE_COMMAND variable.
(die): Change back to `directory_before_chdir' before dying.

Part of MSDOS/GO32 port from DJ Delorie <dj@ctron.com>.
1994-07-25 23:33:26 +00:00
Roland McGrath
f663464925 (PATH_SEPARATOR_CHAR): Macro removed (now in make.h). 1994-07-25 23:28:08 +00:00
Roland McGrath
5d435e0859 (PATH_SEPARATOR_CHAR): New macro; differing defns for [__MSDOS__] and not. 1994-07-25 23:27:48 +00:00
Roland McGrath
a2ab31ba62 [__MSDOS__]: Include <process.h>.
(PATH_SEPARATOR_CHAR): New macro; differing defns for [__MSDOS__] and not.
[__MSDOS__] (dos_pid, dos_status, dos_bname, dos_bename, dos_batch_file):
New variables.
(reap_children) [__MSDOS__]: Don't call wait; just examine those vars.
(unblock_sigs) [__MSDOS__]: Do nothing.
(start_job_command) [__MSDOS__]: Use spawnvpe instead of vfork and exec.
(load_too_high) [__MSDOS__]: Always return true.
(search_path) [__MSDOS__]: Check for : or / in FILE to punt.
Use PATH_SEPARATOR_CHAR instead of ':'.
(construct_command_argv_internal) [__MSDOS__]: Wholly different values for
sh_chars and sh_cmds.  Wholly new code to handle shell scripts.

Part of MSDOS/GO32 port from DJ Delorie <dj@ctron.com>.
1994-07-25 23:23:03 +00:00
Roland McGrath
da2ea1ea7f (expand_function: `shell') [__MSDOS__]: Wholly new implementation. 1994-07-25 23:06:00 +00:00
Roland McGrath
21a1b3b255 [__MSDOS__] (dosify): New function.
(dir_contents_file_exists_p) [__MSDOS__]: Call it on FILENAME and process
the result instead of FILENAME itself.
(file_impossible_p) [__MSDOS__]: Likewise.
Part of MSDOS/GO32 port from DJ Delorie <dj@ctron.com>.
1994-07-25 23:01:19 +00:00
Roland McGrath
c8e76a708e [__MSDOS__]: Define GCC_IS_NATIVE.
(default_suffix_rules) [__MSDOS__]: Use `y_tab.c' instead of `y.tab.c'.
(default_variables) [GCC_IS_NATIVE]: Set CC and CXX to `gcc', YACC to
`bison -y', and LEX to `flex'.
Part of MSDOS/GO32 port from DJ Delorie <dj@ctron.com>.
1994-07-25 22:54:09 +00:00
Roland McGrath
461cffc4e9 Initial revision 1994-07-25 22:48:06 +00:00
Roland McGrath
cdd25d1fb3 (fatal_error_signal) [__MSDOS__]: Just remove intermediates and exit.
Part of MSDOS/GO32 port from DJ Delorie <dj@ctron.com>.
1994-07-25 22:47:14 +00:00
Roland McGrath
9a3666d550 (set_file_variables): Add parens in length computation in .SUFFIXES dep
loop to quiet compiler warning.  From Jim Meyering.
1994-07-25 22:09:25 +00:00
Roland McGrath
90dffad2cc (read_makefile): Free FILENAME if we allocated it. From Jim Meyering. 1994-07-25 22:07:41 +00:00
Roland McGrath
c1f2ef6d09 Update ISBN number to 1-882114-50-7 for edition 0.46.
Use new macro ISBN set at top of file.
1994-07-20 12:30:52 +00:00
Roland McGrath
51250a676d Split a shell command line in @example to avoid overfull hbox. 1994-07-08 18:33:15 +00:00
Roland McGrath
d2461a2409 (Goals): Say that only first target in first rule is default goal.
(Archive Pitfalls): New node.
1994-07-05 21:27:09 +00:00
Roland McGrath
fdea69c5fa (selective_vpath_search): Use safe_stat in place of stat. 1994-07-04 21:56:24 +00:00
Roland McGrath
7c7552336d (construct_include_path): Use safe_stat in place of stat. 1994-07-04 21:55:13 +00:00
Roland McGrath
535dcf6a22 (search_path): Use safe_stat in place of stat. 1994-07-04 21:54:18 +00:00
Roland McGrath
84091971f9 (find_directory): Use safe_stat in place of stat. 1994-07-04 21:53:25 +00:00
Roland McGrath
61da194af9 (delete_target): Use safe_stat in place of stat. 1994-07-04 21:52:28 +00:00
Roland McGrath
30c1465265 (ar_member_touch) [EINTR]: Do EINTR looping around fstat. 1994-07-04 21:51:49 +00:00
Roland McGrath
b574b8ea5a (name_mtime): Use safe_stat in place of stat.
(touch_file) [EINTR]: Do EINTR looping around fstat.
1994-07-04 21:50:03 +00:00
Roland McGrath
710e8e6f6f (safe_stat): New function, EINTR-safe wrapper around stat. 1994-07-04 21:46:58 +00:00
Roland McGrath
4a8a7637f3 (read_makefile): Check for a shell command first, and then strip leading
tabs before further checking if it's not a shell command line.
1994-06-24 10:34:03 +00:00
Roland McGrath
6348923799 Fix typo in last change. 1994-06-24 10:22:37 +00:00
Roland McGrath
660a23d649 [__arm]: Undefine POSIX.
[!__GNU_LIBRARY__ && !POSIX && !_POSIX_VERSION]: Don't declare system
functions that return int.
1994-06-24 09:45:35 +00:00
Roland McGrath
5bd9836fba (construct_command_argv_internal): After swallowing a backslash-newline
combination, if INSTRING is set goto string_char (new label) for normal
INSTRING handling code.
1994-06-24 09:40:13 +00:00
Roland McGrath
0cb47363e1 Put #include of errno.h and decl of errno before #ifndef HAVE_GETLOADAVG. 1994-06-04 05:24:48 +00:00
Roland McGrath
fff5a9ece0 Don't check for sys_siglist and _sys_siglist with AC_HAVE_FUNCS.
Instead use two AC_COMPILE_CHECKs.
1994-06-04 05:11:12 +00:00
Richard M. Stallman
e3a24fc596 [emacs]: Block input around the garbage reclamation.
Include blockinput.h.
1994-06-02 17:45:40 +00:00
Roland McGrath
bb38b0c253 [!__GNU_LIBRARY__ && !POSIX]: Also test #ifndef _POSIX_VERSION for these
declarations.
1994-05-23 22:25:30 +00:00
Roland McGrath
d2ed03e72a [GETLOADAVG_PRIVILEGED] [POSIX]: Remove bogus #ifndefs around #undefs of
HAVE_SETREUID and HAVE_SETREGID.
1994-05-23 22:20:30 +00:00
22 changed files with 1043 additions and 370 deletions

View File

@@ -3,3 +3,9 @@
/* Define this if the SCCS `get' command understands the `-G<file>' option. */ /* Define this if the SCCS `get' command understands the `-G<file>' option. */
#undef SCCS_GET_MINUS_G #undef SCCS_GET_MINUS_G
/* Define this if the C library defines the variable `sys_siglist'. */
#undef HAVE_SYS_SIGLIST
/* Define this if the C library defines the variable `_sys_siglist'. */
#undef HAVE__SYS_SIGLIST

View File

@@ -29,6 +29,10 @@
#endif #endif
#endif #endif
#ifdef emacs
#include "blockinput.h"
#endif
/* If compiling with GCC 2, this file's not needed. */ /* If compiling with GCC 2, this file's not needed. */
#if !defined (__GNUC__) || __GNUC__ < 2 #if !defined (__GNUC__) || __GNUC__ < 2
@@ -176,6 +180,10 @@ alloca (size)
{ {
register header *hp; /* Traverses linked list. */ register header *hp; /* Traverses linked list. */
#ifdef emacs
BLOCK_INPUT;
#endif
for (hp = last_alloca_header; hp != NULL;) for (hp = last_alloca_header; hp != NULL;)
if ((STACK_DIR > 0 && hp->h.deep > depth) if ((STACK_DIR > 0 && hp->h.deep > depth)
|| (STACK_DIR < 0 && hp->h.deep < depth)) || (STACK_DIR < 0 && hp->h.deep < depth))
@@ -190,6 +198,10 @@ alloca (size)
break; /* Rest are not deeper. */ break; /* Rest are not deeper. */
last_alloca_header = hp; /* -> last valid storage. */ last_alloca_header = hp; /* -> last valid storage. */
#ifdef emacs
UNBLOCK_INPUT;
#endif
} }
if (size == 0) if (size == 0)

View File

@@ -495,7 +495,11 @@ ar_member_touch (arname, memname)
if (AR_HDR_SIZE != write (fd, (char *) &ar_hdr, AR_HDR_SIZE)) if (AR_HDR_SIZE != write (fd, (char *) &ar_hdr, AR_HDR_SIZE))
goto lose; goto lose;
/* The file's mtime is the time we we want. */ /* The file's mtime is the time we we want. */
#ifdef EINTR
while (fstat (fd, &statbuf) < 0 && errno == EINTR);
#else
fstat (fd, &statbuf); fstat (fd, &statbuf);
#endif
#if defined(ARFMAG) || defined(AIAMAG) #if defined(ARFMAG) || defined(AIAMAG)
/* Advance member's time to that time */ /* Advance member's time to that time */
for (i = 0; i < sizeof ar_hdr.ar_date; i++) for (i = 0; i < sizeof ar_hdr.ar_date; i++)

View File

@@ -87,7 +87,7 @@ set_file_variables (file)
for (d = enter_file (".SUFFIXES")->deps; d != 0; d = d->next) for (d = enter_file (".SUFFIXES")->deps; d != 0; d = d->next)
{ {
unsigned int slen = strlen (dep_name (d)); unsigned int slen = strlen (dep_name (d));
if (len > slen && !strncmp (dep_name (d), name + len - slen, slen)) if (len > slen && !strncmp (dep_name (d), name + (len - slen), slen))
{ {
file->stem = savestring (name, len - slen); file->stem = savestring (name, len - slen);
break; break;
@@ -329,6 +329,10 @@ RETSIGTYPE
fatal_error_signal (sig) fatal_error_signal (sig)
int sig; int sig;
{ {
#ifdef __MSDOS__
remove_intermediates (1);
exit (1);
#else /* Not MSDOS. */
handling_fatal_signal = 1; handling_fatal_signal = 1;
/* Set the handling for this signal to the default. /* Set the handling for this signal to the default.
@@ -385,6 +389,7 @@ fatal_error_signal (sig)
will be unblocked when we return and arrive then to kill us. */ will be unblocked when we return and arrive then to kill us. */
if (kill (getpid (), sig) < 0) if (kill (getpid (), sig) < 0)
pfatal_with_name ("kill"); pfatal_with_name ("kill");
#endif /* MSDOS. */
} }
/* Delete FILE unless it's precious or not actually a file (phony), /* Delete FILE unless it's precious or not actually a file (phony),
@@ -416,7 +421,7 @@ delete_target (file, on_behalf_of)
} }
#endif #endif
if (stat (file->name, &st) == 0 if (safe_stat (file->name, &st) == 0
&& S_ISREG (st.st_mode) && S_ISREG (st.st_mode)
&& (time_t) st.st_mtime != file->last_mtime) && (time_t) st.st_mtime != file->last_mtime)
{ {

65
configh.dos.template Normal file
View File

@@ -0,0 +1,65 @@
/* Generated automatically from configure.in by autoheader. DO NOT EDIT! */
#define INCLUDEDIR "c:/djgpp/include"
#define LIBDIR "c:/djgpp/lib"
/* Define if you have dirent.h. */
#define DIRENT
/* Define if you have the strcoll function and it is properly defined. */
#define HAVE_STRCOLL
/* Define if you have unistd.h. */
#define HAVE_UNISTD_H
/* Define as the return type of signal handlers (int or void). */
#define RETSIGTYPE void
/* Define if you have the ANSI C header files. */
#define STDC_HEADERS
/* Define if `sys_siglist' is declared by <signal.h>. */
#define SYS_SIGLIST_DECLARED
/* Define if you have getdtablesize. */
#define HAVE_GETDTABLESIZE
/* Define if you have dup2. */
#define HAVE_DUP2
/* Define if you have sys_siglist. */
#undef HAVE_SYS_SIGLIST
/* Define if you have _sys_siglist. */
#undef HAVE__SYS_SIGLIST
/* Define if you have psignal. */
#define HAVE_PSIGNAL
/* Define if you have getcwd. */
#define HAVE_GETCWD
/* Define if you have sigsetmask. */
#define HAVE_SIGSETMASK
/* Define if you have setlinebuf. */
#define HAVE_SETLINEBUF
/* Define if you have the <limits.h> header file. */
#define HAVE_LIMITS_H
/* Define if you have the <sys/param.h> header file. */
#define HAVE_SYS_PARAM_H
/* Define if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H
/* Define if you have the <string.h> header file. */
#define HAVE_STRING_H
/* Define if you have the <memory.h> header file. */
#define HAVE_MEMORY_H
#define INCLUDEDIR "c:/djgpp/include"
#define LIBDIR "c:/djgpp/lib"
#define SCCS_GET "get"

43
configure.bat Normal file
View File

@@ -0,0 +1,43 @@
@echo off
echo Configuring MAKE for go32
rem This batch file assumes a unix-type "sed" program
update configh.dos config.h
echo # Makefile generated by "configure.bat"> Makefile
if exist config.sed del config.sed
echo ": try_sl ">> config.sed
echo "/\\$/ { ">> config.sed
echo " N ">> config.sed
echo " s/[ ]*\\\n[ ]*/ / ">> config.sed
echo " b try_sl ">> config.sed
echo "} ">> config.sed
echo "s/@srcdir@/./ ">> config.sed
echo "s/@CC@/gcc/ ">> config.sed
echo "s/@CFLAGS@/-O2 -g -DHAVE_CONFIG_H/ ">> config.sed
echo "s/@LDFLAGS@// ">> config.sed
echo "s/@RANLIB@/ranlib/ ">> config.sed
echo "s/@DEFS@// ">> config.sed
echo "s/@REMOTE@/stub/ ">> config.sed
echo "s/@ALLOCA@// ">> config.sed
echo "s/@LIBS@// ">> config.sed
echo "s/@LIBOBJS@// ">> config.sed
echo "s/@SET_MAKE@// ">> config.sed
echo "s/^Makefile *:/_Makefile:/ ">> config.sed
echo "s/^config.h *:/_config.h:/ ">> config.sed
echo "s/^defines *=.*$/defines =/ ">> config.sed
echo "/mv -f make.new make/d ">> config.sed
echo "s/cd glob; $(MAKE)/$(MAKE) -C glob/ ">> config.sed
sed -e "s/^\"//" -e "s/\"$//" -e "s/[ ]*$//" config.sed > config2.sed
sed -f config2.sed Makefile.in >> Makefile
del config.sed
del config2.sed
cd glob
call configure
cd ..

View File

@@ -29,9 +29,15 @@ AC_STAT_MACROS_BROKEN
AC_SUBST(LIBOBJS) AC_SUBST(LIBOBJS)
AC_HAVE_FUNCS(getdtablesize sys_siglist _sys_siglist psignal \ AC_HAVE_FUNCS(getdtablesize psignal \
dup2 getcwd sigsetmask getgroups setlinebuf \ dup2 getcwd sigsetmask getgroups setlinebuf \
seteuid setegid setreuid setregid strerror) seteuid setegid setreuid setregid strerror)
AC_COMPILE_CHECK(sys_siglist, ,
[extern char *sys_siglist[]; puts(*sys_siglist);],
AC_DEFINE(HAVE_SYS_SIGLIST))
AC_COMPILE_CHECK(_sys_siglist, ,
[extern char *_sys_siglist[]; puts(*_sys_siglist);],
AC_DEFINE(HAVE__SYS_SIGLIST))
AC_ALLOCA AC_ALLOCA
AC_VFORK AC_VFORK
AC_SETVBUF_REVERSED AC_SETVBUF_REVERSED

View File

@@ -23,6 +23,12 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "commands.h" #include "commands.h"
#include "variable.h" #include "variable.h"
/* Define GCC_IS_NATIVE if gcc is the native development environment on
your system (gcc/bison/flex vs cc/yacc/lex). */
#ifdef __MSDOS__
#define GCC_IS_NATIVE
#endif
/* This is the default list of suffixes for suffix rules. /* This is the default list of suffixes for suffix rules.
`.s' must come last, so that a `.o' file will be made from `.s' must come last, so that a `.o' file will be made from
@@ -133,12 +139,20 @@ static char *default_suffix_rules[] =
".c.ln", ".c.ln",
"$(LINT.c) -C$* $<", "$(LINT.c) -C$* $<",
".y.ln", ".y.ln",
#ifndef __MSDOS__
"$(YACC.y) $< \n $(LINT.c) -C$* y.tab.c \n $(RM) y.tab.c", "$(YACC.y) $< \n $(LINT.c) -C$* y.tab.c \n $(RM) y.tab.c",
#else
"$(YACC.y) $< \n $(LINT.c) -C$* y_tab.c \n $(RM) y_tab.c",
#endif
".l.ln", ".l.ln",
"@$(RM) $*.c\n $(LEX.l) $< > $*.c\n$(LINT.c) -i $*.c -o $@\n $(RM) $*.c", "@$(RM) $*.c\n $(LEX.l) $< > $*.c\n$(LINT.c) -i $*.c -o $@\n $(RM) $*.c",
".y.c", ".y.c",
#ifndef __MSDOS__
"$(YACC.y) $< \n mv -f y.tab.c $@", "$(YACC.y) $< \n mv -f y.tab.c $@",
#else
"$(YACC.y) $< \n mv -f y_tab.c $@",
#endif
".l.c", ".l.c",
"@$(RM) $@ \n $(LEX.l) $< > $@", "@$(RM) $@ \n $(LEX.l) $< > $@",
@@ -203,8 +217,13 @@ static char *default_variables[] =
"ARFLAGS", "rfv", "ARFLAGS", "rfv",
#endif #endif
"AS", "as", "AS", "as",
#ifdef GCC_IS_NATIVE
"CC", "gcc",
"CXX", "gcc",
#else
"CC", "cc", "CC", "cc",
"CXX", "g++", "CXX", "g++",
#endif
/* This expands to $(CO) $(COFLAGS) $< $@ if $@ does not exist, /* This expands to $(CO) $(COFLAGS) $< $@ if $@ does not exist,
and to the empty string if $@ does exist. */ and to the empty string if $@ does exist. */
@@ -237,7 +256,11 @@ static char *default_variables[] =
#endif /* Cray. */ #endif /* Cray. */
"GET", SCCS_GET, "GET", SCCS_GET,
"LD", "ld", "LD", "ld",
#ifdef GCC_IS_NATIVE
"LEX", "flex",
#else
"LEX", "lex", "LEX", "lex",
#endif
"LINT", "lint", "LINT", "lint",
"M2C", "m2c", "M2C", "m2c",
#ifdef pyr #ifdef pyr
@@ -250,7 +273,11 @@ static char *default_variables[] =
"PC", "pc", "PC", "pc",
#endif /* CRAY. */ #endif /* CRAY. */
#endif /* pyr. */ #endif /* pyr. */
#ifdef GCC_IS_NATIVE
"YACC", "bison -y",
#else
"YACC", "yacc", /* Or "bison -y" */ "YACC", "yacc", /* Or "bison -y" */
#endif
"MAKEINFO", "makeinfo", "MAKEINFO", "makeinfo",
"TEX", "tex", "TEX", "tex",
"TEXI2DVI", "texi2dvi", "TEXI2DVI", "texi2dvi",

55
dir.c
View File

@@ -1,5 +1,5 @@
/* Directory hashing for GNU Make. /* Directory hashing for GNU Make.
Copyright (C) 1988, 1989, 1991, 1992, 1993 Free Software Foundation, Inc. Copyright (C) 1988, 1989, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify GNU Make is free software; you can redistribute it and/or modify
@@ -47,6 +47,49 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#define REAL_DIR_ENTRY(dp) (dp->d_ino != 0) #define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
#endif /* POSIX */ #endif /* POSIX */
#ifdef __MSDOS__
#inlcude <ctype.h>
static char *
dosify (filename)
char *filename;
{
static char dos_filename[14];
char *df;
int i;
if (filename == 0)
return 0;
if (strpbrk (filename, "\"*+,;<=>?[\\]|") != 0)
return filename;
df = dos_filename;
/* First, transform the name part. */
for (i = 0; *filename != '\0' && i < 8 && *filename != '.'; ++i)
*df++ = tolower (*filename++);
/* Now skip to the next dot. */
while (*filename != '\0' && *filename != '.')
++filename;
if (*filename != '\0')
{
*df++ = *filename++;
for (i = 0; *filename != '\0' && i < 3 && *filename != '.'; ++i)
*df++ = tolower (*filename++);
}
/* Look for more dots. */
while (*filename != '\0' && *filename != '.')
++filename;
if (*filename == '.')
return filename;
*df = 0;
return dos_filename;
}
#endif
/* Hash table of directories. */ /* Hash table of directories. */
#ifndef DIRECTORY_BUCKETS #ifndef DIRECTORY_BUCKETS
@@ -136,7 +179,7 @@ find_directory (name)
/* The directory is not in the name hash table. /* The directory is not in the name hash table.
Find its device and inode numbers, and look it up by them. */ Find its device and inode numbers, and look it up by them. */
if (stat (name, &st) < 0) if (safe_stat (name, &st) < 0)
/* Couldn't stat the directory. Mark this by /* Couldn't stat the directory. Mark this by
setting the `contents' member to a nil pointer. */ setting the `contents' member to a nil pointer. */
dir->contents = 0; dir->contents = 0;
@@ -213,6 +256,10 @@ dir_contents_file_exists_p (dir, filename)
/* The directory could not be stat'd or opened. */ /* The directory could not be stat'd or opened. */
return 0; return 0;
#ifdef __MSDOS__
filename = dosify (filename);
#endif
hash = 0; hash = 0;
if (filename != 0) if (filename != 0)
{ {
@@ -404,6 +451,10 @@ file_impossible_p (filename)
/* There are no files entered for this directory. */ /* There are no files entered for this directory. */
return 0; return 0;
#ifdef __MSDOS__
p = filename = dosify (p);
#endif
for (hash = 0; *p != '\0'; ++p) for (hash = 0; *p != '\0'; ++p)
HASH (hash, *p); HASH (hash, *p);
hash %= DIRFILE_BUCKETS; hash %= DIRFILE_BUCKETS;

15
file.c
View File

@@ -385,6 +385,21 @@ snap_deps ()
export_all_variables = 1; export_all_variables = 1;
} }
/* Set the `command_state' member of FILE and all its `also_make's. */
void
set_command_state (file, state)
struct file *file;
int state;
{
struct dep *d;
file->command_state = state;
for (d = file->also_make; d != 0; d = d->next)
d->file->command_state = state;
}
/* Print the data base of files. */ /* Print the data base of files. */
static void static void

1
file.h
View File

@@ -85,6 +85,7 @@ extern struct file *default_goal_file, *suffix_file, *default_file;
extern struct file *lookup_file (), *enter_file (); extern struct file *lookup_file (), *enter_file ();
extern void remove_intermediates (), snap_deps (); extern void remove_intermediates (), snap_deps ();
extern void rename_file (), file_hash_enter (); extern void rename_file (), file_hash_enter ();
extern void set_command_state ();
extern time_t f_mtime (); extern time_t f_mtime ();

View File

@@ -22,6 +22,10 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "commands.h" #include "commands.h"
#include "job.h" #include "job.h"
#ifdef __MSDOS__
#include <process.h>
#endif
static char *string_glob (); static char *string_glob ();
/* Store into VARIABLE_BUFFER at O the result of scanning TEXT and replacing /* Store into VARIABLE_BUFFER at O the result of scanning TEXT and replacing
@@ -371,6 +375,7 @@ expand_function (o, function, text, end)
else else
error_prefix = ""; error_prefix = "";
#ifndef __MSDOS__
if (pipe (pipedes) < 0) if (pipe (pipedes) < 0)
{ {
perror_with_name (error_prefix, "pipe"); perror_with_name (error_prefix, "pipe");
@@ -475,6 +480,69 @@ expand_function (o, function, text, end)
free (buffer); free (buffer);
} }
#else /* MSDOS. */
{
/* MS-DOS can't do fork, but it can do spawn. However, this
means that we don't have an opportunity to reopen stdout to
trap it. Thus, we save our own stdout onto a new descriptor
and dup a temp file's descriptor onto our stdout temporarily.
After we spawn the shell program, we dup our own stdout back
to the stdout descriptor. The buffer reading is the same as
above, except that we're now reading from a file. */
int save_stdout;
int child_stdout;
char tmp_output[FILENAME_MAX];
FILE *child_stream;
unsigned int maxlen = 200;
int cc;
char *buffer;
strcpy (tmp_output, "shXXXXXX");
mktemp (tmp_output);
child_stdout = open (tmp_output,
O_WRONLY|O_CREAT|O_TRUNC|O_TEXT, 0644);
save_stdout = dup (1);
dup2 (child_stdout, 1);
spawnvp (P_WAIT, argv[0], argv);
dup2 (save_stdout, 1);
close (child_stdout);
close (save_stdout);
child_stdout = open (tmp_output, O_RDONLY|O_TEXT, 0644);
buffer = xmalloc (maxlen);
i = 0;
do
{
if (i == maxlen)
{
maxlen += 512;
buffer = (char *) xrealloc (buffer, maxlen + 1);
}
cc = read (child_stdout, &buffer[i], maxlen - i);
if (cc > 0)
i += cc;
} while (cc > 0);
close (child_stdout);
unlink (tmp_output);
if (i > 0)
{
if (buffer[i - 1] == '\n')
buffer[--i] = '\0';
else
buffer[i] = '\0';
p = buffer;
while ((p = index (p, '\n')) != 0)
*p++ = ' ';
o = variable_buffer_output (o, buffer, i);
}
free (buffer);
}
#endif /* Not MSDOS. */
free (text); free (text);
break; break;

View File

@@ -1,5 +1,5 @@
/* Get the system load averages. /* Get the system load averages.
Copyright (C) 1985, 86, 87, 88, 89, 91, 92, 93 Copyright (C) 1985, 86, 87, 88, 89, 91, 92, 93, 1994
Free Software Foundation, Inc. Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
@@ -80,9 +80,17 @@
#endif #endif
#endif #endif
/* Exclude all the code except the test program at the end /* Exclude all the code except the test program at the end
if the system has its own `getloadavg' function. */ if the system has its own `getloadavg' function.
The declaration of `errno' is needed by the test program
as well as the function itself, so it comes first. */
#include <errno.h>
#ifndef errno
extern int errno;
#endif
#ifndef HAVE_GETLOADAVG #ifndef HAVE_GETLOADAVG
@@ -331,11 +339,6 @@
#endif #endif
#include <stdio.h> #include <stdio.h>
#include <errno.h>
#ifndef errno
extern int errno;
#endif
/* LOAD_AVE_TYPE should only get defined if we're going to use the /* LOAD_AVE_TYPE should only get defined if we're going to use the
nlist method. */ nlist method. */

113
job.c
View File

@@ -28,6 +28,16 @@ static char default_path[] = ":/bin:/usr/bin";
/* Default shell to use. */ /* Default shell to use. */
char default_shell[] = "/bin/sh"; char default_shell[] = "/bin/sh";
#ifdef __MSDOS__
#include <process.h>
static int dos_pid = 123;
static int dos_status;
static char *dos_bname;
static char *dos_bename;
static int dos_batch_file;
#endif /* MSDOS. */
/* If NGROUPS_MAX == 0 then try other methods for finding a real value. */ /* If NGROUPS_MAX == 0 then try other methods for finding a real value. */
#if defined (NGROUPS_MAX) && NGROUPS_MAX == 0 #if defined (NGROUPS_MAX) && NGROUPS_MAX == 0
#undef NGROUPS_MAX #undef NGROUPS_MAX
@@ -260,6 +270,7 @@ reap_children (block, err)
} }
else if (pid == 0) else if (pid == 0)
{ {
#ifndef __MSDOS__
/* No remote children. Check for local children. */ /* No remote children. Check for local children. */
if (any_local) if (any_local)
@@ -308,6 +319,14 @@ reap_children (block, err)
exit_sig = WIFSIGNALED (status) ? WTERMSIG (status) : 0; exit_sig = WIFSIGNALED (status) ? WTERMSIG (status) : 0;
coredump = WCOREDUMP (status); coredump = WCOREDUMP (status);
} }
#else /* MSDOS. */
/* Life is very different on MSDOS. */
pid = dos_pid - 1;
status = dos_status;
exit_code = dos_status;
exit_sig = 0;
coredump = 0;
#endif /* Not MSDOS. */
} }
else else
/* We got a remote child. */ /* We got a remote child. */
@@ -419,7 +438,9 @@ reap_children (block, err)
} }
if (! handling_fatal_signal) if (! handling_fatal_signal)
/* Notice if the target of the commands has been changed. */ /* Notice if the target of the commands has been changed.
This also propagates its values for command_state and
update_status to its also_make files. */
notice_finished_file (c->file); notice_finished_file (c->file);
if (debug_flag) if (debug_flag)
@@ -475,6 +496,13 @@ free_child (child)
} }
#ifdef POSIX #ifdef POSIX
#ifdef __MSDOS__
void
unblock_sigs ()
{
return;
}
#else
extern sigset_t fatal_signal_set; extern sigset_t fatal_signal_set;
void void
@@ -485,6 +513,7 @@ unblock_sigs ()
sigprocmask (SIG_SETMASK, &empty, (sigset_t *) 0); sigprocmask (SIG_SETMASK, &empty, (sigset_t *) 0);
} }
#endif #endif
#endif
/* Start a job to run the commands specified in CHILD. /* Start a job to run the commands specified in CHILD.
CHILD is updated to reflect the commands and ID of the child process. */ CHILD is updated to reflect the commands and ID of the child process. */
@@ -519,7 +548,7 @@ start_job_command (child)
if (question_flag && !(flags & COMMANDS_RECURSE)) if (question_flag && !(flags & COMMANDS_RECURSE))
{ {
child->file->update_status = 1; child->file->update_status = 1;
child->file->command_state = cs_finished; notice_finished_file (child->file);
return; return;
} }
@@ -618,6 +647,8 @@ start_job_command (child)
if (child->environment == 0) if (child->environment == 0)
child->environment = target_environment (child->file); child->environment = target_environment (child->file);
#ifndef __MSDOS__
/* start_waiting_job has set CHILD->remote if we can start a remote job. */ /* start_waiting_job has set CHILD->remote if we can start a remote job. */
if (child->remote) if (child->remote)
{ {
@@ -667,10 +698,26 @@ start_job_command (child)
} }
} }
#else /* MSDOS. */
dos_status = spawnvpe (P_WAIT, argv[0], argv, child->environment);
++dead_children;
child->pid = dos_pid++;
if (dos_batch_file)
{
dos_batch_file = 0;
remove (dos_bname); /* Ignore errors. */
if (access (dos_bename, 0))
dos_status = 1;
else
dos_status = 0;
remove (dos_bename);
}
#endif /* Not MSDOS. */
/* We are the parent side. Set the state to /* We are the parent side. Set the state to
say the commands are running and return. */ say the commands are running and return. */
child->file->command_state = cs_running; set_command_state (child->file, cs_running);
/* Free the storage used by the child's argument list. */ /* Free the storage used by the child's argument list. */
@@ -681,7 +728,7 @@ start_job_command (child)
error: error:
child->file->update_status = 2; child->file->update_status = 2;
child->file->command_state = cs_finished; notice_finished_file (child->file);
} }
/* Try to start a child running. /* Try to start a child running.
@@ -924,6 +971,9 @@ job_next_command (child)
static int static int
load_too_high () load_too_high ()
{ {
#ifdef __MSDOS__
return 1;
#else
extern int getloadavg (); extern int getloadavg ();
double load; double load;
@@ -949,6 +999,7 @@ load_too_high ()
user_access (); user_access ();
return load >= max_load_average; return load >= max_load_average;
#endif
} }
/* Start jobs that are waiting for the load to be lower. */ /* Start jobs that are waiting for the load to be lower. */
@@ -1012,7 +1063,13 @@ search_path (file, path, program)
if (path == 0 || path[0] == '\0') if (path == 0 || path[0] == '\0')
path = default_path; path = default_path;
if (index (file, '/') != 0) if (
#ifdef __MSDOS__
strpbrk (file, "/\\:")
#else
index (file, '/')
#endif
!= 0)
{ {
strcpy (program, file); strcpy (program, file);
return 1; return 1;
@@ -1049,7 +1106,7 @@ search_path (file, path, program)
int perm; int perm;
char *p; char *p;
p = index (path, ':'); p = index (path, PATH_SEPARATOR_CHAR);
if (p == 0) if (p == 0)
p = path + strlen (path); p = path + strlen (path);
@@ -1062,7 +1119,7 @@ search_path (file, path, program)
bcopy (file, program + (p - path) + 1, len); bcopy (file, program + (p - path) + 1, len);
} }
if (stat (program, &st) == 0 if (safe_stat (program, &st) == 0
&& S_ISREG (st.st_mode)) && S_ISREG (st.st_mode))
{ {
if (st.st_uid == geteuid ()) if (st.st_uid == geteuid ())
@@ -1189,12 +1246,22 @@ construct_command_argv_internal (line, restp, shell, ifs)
char *line, **restp; char *line, **restp;
char *shell, *ifs; char *shell, *ifs;
{ {
#ifdef __MSDOS__
static char sh_chars[] = "\"|<>";
static char *sh_cmds[] = { "break", "call", "cd", "chcp", "chdir", "cls",
"copy", "ctty", "date", "del", "dir", "echo",
"erase", "exit", "for", "goto", "if", "if", "md",
"mkdir", "path", "pause", "prompt", "rem", "ren",
"rename", "set", "shift", "time", "type",
"ver", "verify", "vol", ":", 0 };
#else
static char sh_chars[] = "#;\"*?[]&|<>(){}$`^"; static char sh_chars[] = "#;\"*?[]&|<>(){}$`^";
static char *sh_cmds[] = { "cd", "eval", "exec", "exit", "login", static char *sh_cmds[] = { "cd", "eval", "exec", "exit", "login",
"logout", "set", "umask", "wait", "while", "for", "logout", "set", "umask", "wait", "while", "for",
"case", "if", ":", ".", "break", "continue", "case", "if", ":", ".", "break", "continue",
"export", "read", "readonly", "shift", "times", "export", "read", "readonly", "shift", "times",
"trap", "switch", 0 }; "trap", "switch", 0 };
#endif
register int i; register int i;
register char *p; register char *p;
register char *ap; register char *ap;
@@ -1241,6 +1308,7 @@ construct_command_argv_internal (line, restp, shell, ifs)
if (instring) if (instring)
{ {
string_char:
/* Inside a string, just copy any char except a closing quote /* Inside a string, just copy any char except a closing quote
or a backslash-newline combination. */ or a backslash-newline combination. */
if (*p == '\'') if (*p == '\'')
@@ -1292,7 +1360,7 @@ construct_command_argv_internal (line, restp, shell, ifs)
strcpy (p, p + 1); strcpy (p, p + 1);
if (instring) if (instring)
*ap++ = *p; goto string_char;
else else
{ {
if (ap != new_argv[i]) if (ap != new_argv[i])
@@ -1401,6 +1469,34 @@ construct_command_argv_internal (line, restp, shell, ifs)
free (new_argv); free (new_argv);
} }
#ifdef __MSDOS__
{
FILE *batch;
dos_batch_file = 1;
if (dos_bname == 0)
{
dos_bname = tempnam (".", "mk");
for (i = 0; dos_bname[i] != '\0'; ++i)
if (dos_bname[i] == '/')
dos_bname[i] = '\\';
dos_bename = (char *) xmalloc (strlen (dos_bname) + 5);
strcpy (dos_bename, dos_bname);
strcat (dos_bname, ".bat");
strcat (dos_bename, ".err");
}
batch = fopen(bename, "w"); /* Create a file. */
if (batch != NULL)
fclose (batch);
batch = fopen (dos_bname, "w");
fputs ("@echo off\n", batch);
fputs (line, batch);
fprintf (batch, "\nif errorlevel 1 del %s\n", dos_bename);
fclose (batch);
new_argv = (char **) xmalloc(2 * sizeof(char *));
new_argv[0] = strdup (bname);
new_argv[1] = 0;
}
#else /* Not MSDOS. */
{ {
/* SHELL may be a multi-word command. Construct a command line /* SHELL may be a multi-word command. Construct a command line
"SHELL -c LINE", with all special chars in LINE escaped. "SHELL -c LINE", with all special chars in LINE escaped.
@@ -1458,6 +1554,7 @@ construct_command_argv_internal (line, restp, shell, ifs)
new_argv = construct_command_argv_internal (new_line, (char **) NULL, new_argv = construct_command_argv_internal (new_line, (char **) NULL,
(char *) 0, (char *) 0); (char *) 0, (char *) 0);
} }
#endif /* MSDOS. */
return new_argv; return new_argv;
} }

412
main.c
View File

@@ -304,14 +304,28 @@ static struct option long_option_aliases[] =
#define DESCRIPTION_COLUMN 30 #define DESCRIPTION_COLUMN 30
/* List of non-switch arguments. */ /* List of goal targets. */
struct stringlist *other_args = 0; static struct dep *goals, *lastgoal;
/* List of variables which were defined on the command line
(or, equivalently, in MAKEFLAGS). */
struct command_variable
{
struct command_variable *next;
struct variable *variable;
};
static struct command_variable *command_variables;
/* The name we were invoked with. */ /* The name we were invoked with. */
char *program; char *program;
/* Our current directory before processing any -C options. */
char *directory_before_chdir;
/* Our current directory after processing all -C options. */ /* Our current directory after processing all -C options. */
char *starting_directory; char *starting_directory;
@@ -387,14 +401,9 @@ main (argc, argv, envp)
extern RETSIGTYPE fatal_error_signal (), child_handler (); extern RETSIGTYPE fatal_error_signal (), child_handler ();
register struct file *f; register struct file *f;
register unsigned int i; register unsigned int i;
register char *cmd_defs;
register unsigned int cmd_defs_len, cmd_defs_idx;
char **p; char **p;
struct dep *goals = 0;
register struct dep *lastgoal;
struct dep *read_makefiles; struct dep *read_makefiles;
PATH_VAR (current_directory); PATH_VAR (current_directory);
char *directory_before_chdir;
default_goal_file = 0; default_goal_file = 0;
reading_filename = 0; reading_filename = 0;
@@ -464,6 +473,12 @@ main (argc, argv, envp)
else else
{ {
program = rindex (argv[0], '/'); program = rindex (argv[0], '/');
#ifdef __MSDOS__
if (program == 0)
program = rindex (argv[0], '\\');
if (program == 0)
program = rindex (argv[0], ':');
#endif
if (program == 0) if (program == 0)
program = argv[0]; program = argv[0];
else else
@@ -490,8 +505,8 @@ main (argc, argv, envp)
strlen (current_directory)); strlen (current_directory));
/* Read in variables from the environment. It is important that this be /* Read in variables from the environment. It is important that this be
done before `MAKE' and `MAKEOVERRIDES' are figured out so their done before $(MAKE) is are figured out so its definitions will not be
definitions will not be ones from the environment. */ one from the environment. */
for (i = 0; envp[i] != 0; ++i) for (i = 0; envp[i] != 0; ++i)
{ {
@@ -531,76 +546,7 @@ main (argc, argv, envp)
if (print_version_flag) if (print_version_flag)
die (0); die (0);
/* Search for command line arguments that define variables, #ifndef __MSDOS__
and do the definitions. Also save up the text of these
arguments in CMD_DEFS so we can put them into the values
of $(MAKEOVERRIDES) and $(MAKE). */
cmd_defs_len = 200;
cmd_defs = (char *) xmalloc (cmd_defs_len);
cmd_defs_idx = 0;
for (i = 1; other_args->list[i] != 0; ++i)
{
if (other_args->list[i][0] == '\0')
/* Ignore empty arguments, so they can't kill enter_file. */
continue;
/* Try a variable definition. */
if (try_variable_definition ((char *) 0, 0,
other_args->list[i], o_command))
{
/* It succeeded. The variable is already defined.
Backslash-quotify it and append it to CMD_DEFS, then clobber it
to 0 in the list so that it won't be taken for a goal target. */
register char *p = other_args->list[i];
unsigned int l = strlen (p);
if (cmd_defs_idx + (l * 2) + 1 > cmd_defs_len)
{
if (l * 2 > cmd_defs_len)
cmd_defs_len += l * 2;
else
cmd_defs_len *= 2;
cmd_defs = (char *) xrealloc (cmd_defs, cmd_defs_len);
}
while (*p != '\0')
{
if (index ("^;'\"*?[]$<>(){}|&~`\\ \t\r\n\f\v", *p) != 0)
cmd_defs[cmd_defs_idx++] = '\\';
cmd_defs[cmd_defs_idx++] = *p++;
}
cmd_defs[cmd_defs_idx++] = ' ';
}
else
{
/* It was not a variable definition, so it is a target to be made.
Enter it as a file and add it to the dep chain of goals. */
f = enter_command_line_file (other_args->list[i]);
f->cmd_target = 1;
if (goals == 0)
{
goals = (struct dep *) xmalloc (sizeof (struct dep));
lastgoal = goals;
}
else
{
lastgoal->next = (struct dep *) xmalloc (sizeof (struct dep));
lastgoal = lastgoal->next;
}
lastgoal->name = 0;
lastgoal->file = f;
}
}
if (cmd_defs_idx > 0)
{
cmd_defs[cmd_defs_idx - 1] = '\0';
(void) define_variable ("MAKEOVERRIDES", 13, cmd_defs, o_default, 0);
}
free (cmd_defs);
/* Set the "MAKE_COMMAND" variable to the name we were invoked with. /* Set the "MAKE_COMMAND" variable to the name we were invoked with.
(If it is a relative pathname with a slash, prepend our directory name (If it is a relative pathname with a slash, prepend our directory name
so the result will run the same program regardless of the current dir. so the result will run the same program regardless of the current dir.
@@ -610,17 +556,15 @@ main (argc, argv, envp)
if (current_directory[0] != '\0' if (current_directory[0] != '\0'
&& argv[0] != 0 && argv[0][0] != '/' && index (argv[0], '/') != 0) && argv[0] != 0 && argv[0][0] != '/' && index (argv[0], '/') != 0)
argv[0] = concat (current_directory, "/", argv[0]); argv[0] = concat (current_directory, "/", argv[0]);
#endif
/* The extra indirection through $(MAKE_COMMAND) is done
for hysterical raisins. */
(void) define_variable ("MAKE_COMMAND", 12, argv[0], o_default, 0); (void) define_variable ("MAKE_COMMAND", 12, argv[0], o_default, 0);
(void) define_variable ("MAKE", 4, "$(MAKE_COMMAND)", o_default, 1);
/* Append the command-line variable definitions gathered above
so sub-makes will get them as command-line definitions. */
(void) define_variable ("MAKE", 4,
"$(MAKE_COMMAND) $(MAKEOVERRIDES)", o_default, 1);
/* If there were -C flags, move ourselves about. */ /* If there were -C flags, move ourselves about. */
if (directories != 0) if (directories != 0)
for (i = 0; directories->list[i] != 0; ++i) for (i = 0; directories->list[i] != 0; ++i)
{ {
@@ -1123,7 +1067,7 @@ main (argc, argv, envp)
/* Parsing of arguments, decoding of switches. */ /* Parsing of arguments, decoding of switches. */
static char options[sizeof (switches) / sizeof (switches[0]) * 3]; static char options[1 + sizeof (switches) / sizeof (switches[0]) * 3];
static struct option long_options[(sizeof (switches) / sizeof (switches[0])) + static struct option long_options[(sizeof (switches) / sizeof (switches[0])) +
(sizeof (long_option_aliases) / (sizeof (long_option_aliases) /
sizeof (long_option_aliases[0]))]; sizeof (long_option_aliases[0]))];
@@ -1141,6 +1085,11 @@ init_switches ()
return; return;
p = options; p = options;
/* Return switch and non-switch args in order, regardless of
POSIXLY_CORRECT. Non-switch args are returned as option 1. */
*p++ = '-';
for (i = 0; switches[i].c != '\0'; ++i) for (i = 0; switches[i].c != '\0'; ++i)
{ {
long_options[i].name = (switches[i].long_name == 0 ? "" : long_options[i].name = (switches[i].long_name == 0 ? "" :
@@ -1195,15 +1144,6 @@ decode_switches (argc, argv, env)
register struct stringlist *sl; register struct stringlist *sl;
register int c; register int c;
if (!env)
{
other_args = (struct stringlist *) xmalloc (sizeof (struct stringlist));
other_args->max = argc + 1;
other_args->list = (char **) xmalloc ((argc + 1) * sizeof (char *));
other_args->idx = 1;
other_args->list[0] = argv[0];
}
/* getopt does most of the parsing for us. /* getopt does most of the parsing for us.
First, get its vectors set up. */ First, get its vectors set up. */
@@ -1218,7 +1158,45 @@ decode_switches (argc, argv, env)
while ((c = getopt_long (argc, argv, while ((c = getopt_long (argc, argv,
options, long_options, (int *) 0)) != EOF) options, long_options, (int *) 0)) != EOF)
{ {
if (c == '?') if (c == 1)
{
/* Non-option argument. It might be a variable definition. */
struct variable *v;
v = try_variable_definition ((char *) 0, 0, optarg, o_command);
if (v != 0)
{
/* It is indeed a variable definition. Record a pointer to
the variable for later use in define_makeflags. */
struct command_variable *cv
= (struct command_variable *) xmalloc (sizeof (*cv));
cv->variable = v;
cv->next = command_variables;
command_variables = cv;
}
else if (! env)
{
/* Not an option or variable definition; it must be a goal
target! Enter it as a file and add it to the dep chain of
goals. */
struct file *f = enter_command_line_file (optarg);
f->cmd_target = 1;
if (goals == 0)
{
goals = (struct dep *) xmalloc (sizeof (struct dep));
lastgoal = goals;
}
else
{
lastgoal->next
= (struct dep *) xmalloc (sizeof (struct dep));
lastgoal = lastgoal->next;
}
lastgoal->name = 0;
lastgoal->file = f;
}
}
else if (c == '?')
/* Bad option. We will print a usage message and die later. /* Bad option. We will print a usage message and die later.
But continue to parse the other options so the user can But continue to parse the other options so the user can
see all he did wrong. */ see all he did wrong. */
@@ -1320,19 +1298,6 @@ positive integral argument",
} }
} }
if (!env)
{
/* Collect the remaining args in the `other_args' string list. */
while (optind < argc)
{
char *arg = argv[optind++];
if (arg[0] != '-' || arg[1] != '\0')
other_args->list[other_args->idx++] = arg;
}
other_args->list[other_args->idx] = 0;
}
if (!env && (bad || print_usage_flag)) if (!env && (bad || print_usage_flag))
{ {
/* Print a nice usage message. */ /* Print a nice usage message. */
@@ -1437,7 +1402,7 @@ decode_env_switches (envar, len)
unsigned int len; unsigned int len;
{ {
char *varref = (char *) alloca (2 + len + 2); char *varref = (char *) alloca (2 + len + 2);
char *value, *args; char *value;
int argc; int argc;
char **argv; char **argv;
@@ -1447,7 +1412,7 @@ decode_env_switches (envar, len)
bcopy (envar, &varref[2], len); bcopy (envar, &varref[2], len);
varref[2 + len] = ')'; varref[2 + len] = ')';
varref[2 + len + 1] = '\0'; varref[2 + len + 1] = '\0';
value = variable_expand (varref); value = allocated_variable_expand (varref);
/* Skip whitespace, and check for an empty value. */ /* Skip whitespace, and check for an empty value. */
value = next_token (value); value = next_token (value);
@@ -1455,18 +1420,6 @@ decode_env_switches (envar, len)
if (len == 0) if (len == 0)
return; return;
/* Make a copy of the value in ARGS, where we will munge it.
If it does not begin with a dash, prepend one.
We must allocate lasting storage for this (and we never free it) because
decode_switches may save pointers into it for string-valued switches. */
args = (char *) xmalloc (1 + len + 2);
if (value[0] != '-')
args[0] = '-';
bcopy (value, value[0] == '-' ? args : &args[1], len + 1);
/* Write an extra null terminator so our loop below will
never be in danger of looking past the end of the string. */
args[(value[0] == '-' ? 0 : 1) + len + 1] = '\0';
/* Allocate a vector that is definitely big enough. */ /* Allocate a vector that is definitely big enough. */
argv = (char **) alloca ((1 + len + 1) * sizeof (char *)); argv = (char **) alloca ((1 + len + 1) * sizeof (char *));
@@ -1474,13 +1427,37 @@ decode_env_switches (envar, len)
Prepend a spacer word. */ Prepend a spacer word. */
argv[0] = 0; argv[0] = 0;
argc = 1; argc = 1;
do while ((argv[argc] = find_next_token (&value, (unsigned int *) 0)) != 0)
++argc;
if (argc == 2 && argv[1][0] != '-')
{ {
argv[argc++] = args; /* There is just one word in the value, and it is not a switch.
args = end_of_token (args); Either this is the single-word form and we should prepend a dash
*args++ = '\0'; before calling decode_switches, or this is the multi-word form and
} while (*args != '\0'); there is no dash because it is a variable definition. */
argv[argc] = 0; struct variable *v;
v = try_variable_definition ((char *) 0, 0, argv[1], o_command);
if (v != 0)
{
/* It was indeed a variable definition, and now it has been
processed. There is nothing for decode_switches to do.
Record a pointer to the variable for later use in
define_makeflags. */
struct command_variable *cv
= (struct command_variable *) xmalloc (sizeof (*cv));
cv->variable = v;
cv->next = command_variables;
command_variables = cv;
return;
}
/* It wasn't a variable definition, so it's some switches without a
leading dash. Add one and pass it along to decode_switches. We
need permanent storage for this in case decode_switches saves
pointers into the value. */
argv[1] = concat ("-", argv[1], "");
}
/* Parse those words. */ /* Parse those words. */
decode_switches (argc, argv, 1); decode_switches (argc, argv, 1);
@@ -1496,7 +1473,10 @@ define_makeflags (all, makefile)
{ {
register const struct command_switch *cs; register const struct command_switch *cs;
char *flagstring; char *flagstring;
register char *p;
unsigned int words;
struct variable *v; struct variable *v;
struct command_variable *cv;
/* We will construct a linked list of `struct flag's describing /* We will construct a linked list of `struct flag's describing
all the flags which need to go in MAKEFLAGS. Then, once we all the flags which need to go in MAKEFLAGS. Then, once we
@@ -1609,70 +1589,119 @@ define_makeflags (all, makefile)
#undef ADD_FLAG #undef ADD_FLAG
if (flags == 0) if (all && command_variables != 0)
/* No flags. Use a string of two nulls so [1] works below. */
flagstring = "\0";
else
{ {
/* Construct the value in FLAGSTRING. /* Now figure out how much space will be taken up
We allocate enough space for a preceding dash and trailing null. */ by the command-line variable definitions. */
register char *p; flagslen += 4; /* For the possible " -- ". */
flagstring = (char *) alloca (1 + flagslen + 1); for (cv = command_variables; cv != 0; cv = cv->next)
p = flagstring;
*p++ = '-';
do
{ {
/* Add the flag letter or name to the string. */ v = cv->variable;
if (!isalnum (flags->cs->c)) flagslen += strlen (v->name);
{ if (! v->recursive)
*p++ = '-'; ++flagslen;
strcpy (p, flags->cs->long_name); ++flagslen;
p += strlen (p); flagslen += strlen (v->value);
} }
else
*p++ = flags->cs->c;
if (flags->arg != 0)
{
/* A flag that takes an optional argument which in this case
is omitted is specified by ARG being "" and ARGLEN being 0.
We must distinguish because a following flag appended without
an intervening " -" is considered the arg for the first. */
if (flags->arglen > 0)
{
/* Add its argument too. */
*p++ = !isalnum (flags->cs->c) ? '=' : ' ';
bcopy (flags->arg, p, flags->arglen);
p += flags->arglen;
}
/* Write a following space and dash, for the next flag. */
*p++ = ' ';
*p++ = '-';
}
else if (!isalnum (flags->cs->c))
{
/* Long options must each go in their own word,
so we write the following space and dash. */
*p++ = ' ';
*p++ = '-';
}
flags = flags->next;
} while (flags != 0);
if (p[-1] == '-')
/* Kill the final space and dash. */
p -= 2;
/* Terminate the string. */
*p = '\0';
} }
/* Construct the value in FLAGSTRING.
We allocate enough space for a preceding dash and trailing null. */
flagstring = (char *) alloca (1 + flagslen + 1);
p = flagstring;
words = 1;
*p++ = '-';
while (flags != 0)
{
/* Add the flag letter or name to the string. */
if (!isalnum (flags->cs->c))
{
*p++ = '-';
strcpy (p, flags->cs->long_name);
p += strlen (p);
}
else
*p++ = flags->cs->c;
if (flags->arg != 0)
{
/* A flag that takes an optional argument which in this case
is omitted is specified by ARG being "" and ARGLEN being 0.
We must distinguish because a following flag appended without
an intervening " -" is considered the arg for the first. */
if (flags->arglen > 0)
{
/* Add its argument too. */
*p++ = !isalnum (flags->cs->c) ? '=' : ' ';
bcopy (flags->arg, p, flags->arglen);
p += flags->arglen;
}
++words;
/* Write a following space and dash, for the next flag. */
*p++ = ' ';
*p++ = '-';
}
else if (!isalnum (flags->cs->c))
{
++words;
/* Long options must each go in their own word,
so we write the following space and dash. */
*p++ = ' ';
*p++ = '-';
}
flags = flags->next;
}
if (all && command_variables != 0)
{
/* Now write all the command-line variable definitions. */
if (p == &flagstring[1])
/* No flags written, so elide the leading dash already written. */
p = flagstring;
else
{
/* Separate the variables from the switches with a "--" arg. */
if (p[-1] != '-')
{
/* We did not already write a trailing " -". */
*p++ = ' ';
*p++ = '-';
}
/* There is a trailing " -"; fill it out to " -- ". */
*p++ = '-';
*p++ = ' ';
}
for (cv = command_variables; cv != 0; cv = cv->next)
{
/* XXX Quoting? */
unsigned int len;
v = cv->variable;
len = strlen (v->name);
bcopy (v->name, p, len);
p += len;
if (! v->recursive)
*p++ = ':';
len = strlen (v->value);
bcopy (v->value, p, len);
p += len;
*p++ = ' ';
++words;
}
--p; /* Kill the final space. */
}
else if (p[-1] == '-')
/* Kill the final space and dash. */
p -= 2;
/* Terminate the string. */
*p = '\0';
v = define_variable ("MAKEFLAGS", 9, v = define_variable ("MAKEFLAGS", 9,
/* On Sun, the value of MFLAGS starts with a `-' but /* If there is just a single word of switches,
the value of MAKEFLAGS lacks the `-'. omit the leading dash unless it is a single
Be compatible with this unless FLAGSTRING starts long option with two leading dashes. */
with a long option `--foo', since removing the &flagstring[(words == 1 && command_variables == 0
first dash would result in the bogus `-foo'. */ && flagstring[1] != '-')
flagstring[1] == '-' ? flagstring : &flagstring[1], ? 1 : 0],
/* This used to use o_env, but that lost when a /* This used to use o_env, but that lost when a
makefile defined MAKEFLAGS. Makefiles set makefile defined MAKEFLAGS. Makefiles set
MAKEFLAGS to add switches, but we still want MAKEFLAGS to add switches, but we still want
@@ -1755,6 +1784,13 @@ die (status)
dying = 1; dying = 1;
/* Try to move back to the original directory. This is essential on
MS-DOS (where there is really only one process), and on Unix it
puts core files in the original directory instead of the -C
directory. */
if (directory_before_chdir != 0)
chdir (directory_before_chdir);
if (print_version_flag) if (print_version_flag)
print_version (); print_version ();

View File

@@ -32,6 +32,20 @@ to avoid trouble on systems where the @code{SHELL} variable might be
inherited from the environment. (This is never a problem with GNU inherited from the environment. (This is never a problem with GNU
@code{make}.) @code{make}.)
Different @code{make} programs have incompatible suffix lists and
implicit rules, and this sometimes creates confusion or misbehavior. So
it is a good idea to set the suffix list explicitly using only the
suffixes you need in the particular Makefile, like this:
@example
.SUFFIXES:
.SUFFIXES: .c .o
@end example
@noindent
The first line clears out the suffix list, the second introduces all
suffixes which may be subject to implicit rules in this Makefile.
Don't assume that @file{.} is in the path for command execution. When Don't assume that @file{.} is in the path for command execution. When
you need to run programs that are a part of your package during the you need to run programs that are a part of your package during the
make, please make sure that it uses @file{./} if the program is built as make, please make sure that it uses @file{./} if the program is built as
@@ -43,33 +57,34 @@ The distinction between @file{./} and @file{$(srcdir)/} is important
when using the @samp{--srcdir} option to @file{configure}. A rule of when using the @samp{--srcdir} option to @file{configure}. A rule of
the form: the form:
@example @smallexample
foo.1 : foo.man sedscript foo.1 : foo.man sedscript
sed -e sedscript foo.man > foo.1 sed -e sedscript foo.man > foo.1
@end example @end smallexample
@noindent @noindent
will fail when the current directory is not the source directory, will fail when the current directory is not the source directory,
because @file{foo.man} and @file{sedscript} are not in the current because @file{foo.man} and @file{sedscript} are not in the current
directory. directory.
Relying on @samp{VPATH} to find the source file will work in the case When using GNU @code{make}, relying on @samp{VPATH} to find the source
where there is a single dependency file, since the @file{make} automatic file will work in the case where there is a single dependency file,
variable @samp{$<} will represent the source file wherever it is. A since the @file{make} automatic variable @samp{$<} will represent the
makefile target like source file wherever it is. (Many versions of @code{make} set @samp{$<}
only in implicit rules.) A makefile target like
@example @smallexample
foo.o : bar.c foo.o : bar.c
$(CC) $(CFLAGS) -I. -I$(srcdir) -c bar.c -o foo.o $(CC) -I. -I$(srcdir) $(CFLAGS) -c bar.c -o foo.o
@end example @end smallexample
@noindent @noindent
should instead be written as should instead be written as
@example @smallexample
foo.o : bar.c foo.o : bar.c
$(CC) $(CFLAGS) $< -o $@@ $(CC) -I. -I$(srcdir) $(CFLAGS) -c $< -o $@@
@end example @end smallexample
@noindent @noindent
in order to allow @samp{VPATH} to work correctly. When the target has in order to allow @samp{VPATH} to work correctly. When the target has
@@ -77,10 +92,10 @@ multiple dependencies, using an explicit @samp{$(srcdir)} is the easiest
way to make the rule work well. For example, the target above for way to make the rule work well. For example, the target above for
@file{foo.1} is best written as: @file{foo.1} is best written as:
@example @smallexample
foo.1 : foo.man sedscript foo.1 : foo.man sedscript
sed -s $(srcdir)/sedscript $(srcdir)/foo.man > foo.1 sed -e $(srcdir)/sedscript $(srcdir)/foo.man > $@@
@end example @end smallexample
@node Utilities in Makefiles @node Utilities in Makefiles
@section Utilities in Makefiles @section Utilities in Makefiles
@@ -107,12 +122,21 @@ user can substitute alternatives. Here are some of the programs we
mean: mean:
@example @example
ar bison cc flex install ld lex make ranlib yacc ar bison cc flex install ld lex
make makeinfo ranlib texi2dvi yacc
@end example @end example
When you use @code{ranlib}, you should test whether it exists, and run Use the following @code{make} variables:
it only if it exists, so that the distribution will work on systems that
don't have @code{ranlib}. @example
$(AR) $(BISON) $(CC) $(FLEX) $(INSTALL) $(LD) $(LEX)
$(MAKE) $(MAKEINFO) $(RANLIB) $(TEXI2DVI) $(YACC)
@end example
When you use @code{ranlib}, you should make sure nothing bad happens if
the system does not have @code{ranlib}. Arrange to ignore an error
from that command, and print a message before the command to tell the
user that failure of the @code{ranlib} command does not mean a problem.
If you use symbolic links, you should implement a fallback for systems If you use symbolic links, you should implement a fallback for systems
that don't have symbolic links. that don't have symbolic links.
@@ -129,29 +153,62 @@ All GNU programs should have the following targets in their Makefiles:
@table @samp @table @samp
@item all @item all
Compile the entire program. This should be the default target. This Compile the entire program. This should be the default target. This
target need not rebuild any documentation files; info files should target need not rebuild any documentation files; Info files should
normally be included in the distribution, and DVI files should be made normally be included in the distribution, and DVI files should be made
only when explicitly asked for. only when explicitly asked for.
@item install @item install
Compile the program and copy the executables, libraries, and so on to Compile the program and copy the executables, libraries, and so on to
the file names where they should reside for actual use. If there is a the file names where they should reside for actual use. If there is a
simple test to verify that a program is properly installed then run that simple test to verify that a program is properly installed, this target
test. should run that test.
The commands should create all the directories in which files are to be
installed, if they don't already exist. This includes the directories
specified as the values of the variables @code{prefix} and
@code{exec_prefix}, as well as all subdirectories that are needed.
One way to do this is by means of an @code{installdirs} target
as described below.
Use @samp{-} before any command for installing a man page, so that Use @samp{-} before any command for installing a man page, so that
@code{make} will ignore any errors. This is in case there are systems @code{make} will ignore any errors. This is in case there are systems
that don't have the Unix man page documentation system installed. that don't have the Unix man page documentation system installed.
In the future, when we have a standard way of installing info files, The way to install Info files is to copy them into @file{$(infodir)}
@samp{install} targets will be the proper place to do so. with @code{$(INSTALL_DATA)} (@pxref{Command Variables}), and then run
the @code{install-info} program if it is present. @code{install-info}
is a script that edits the Info @file{dir} file to add or update the
menu entry for the given Info file; it will be part of the Texinfo package.
Here is a sample rule to install an Info file:
@comment This example has been carefully formatted for the Make manual.
@comment Please do not reformat it without talking to roland@gnu.ai.mit.edu.
@smallexample
$(infodir)/foo.info: foo.info
# There may be a newer info file in . than in srcdir.
-if test -f foo.info; then d=.; \
else d=$(srcdir); fi; \
$(INSTALL_DATA) $$d/foo.info $@@; \
# Run install-info only if it exists.
# Use `if' instead of just prepending `-' to the
# line so we notice real errors from install-info.
# We use `$(SHELL) -c' because some shells do not
# fail gracefully when there is an unknown command.
if $(SHELL) -c 'install-info --version' \
>/dev/null 2>&1; then \
install-info --infodir=$(infodir) $$d/foo.info; \
else true; fi
@end smallexample
@item uninstall @item uninstall
Delete all the installed files that the @samp{install} target would Delete all the installed files that the @samp{install} target would
create (but not the noninstalled files such as @samp{make all} would create (but not the noninstalled files such as @samp{make all} would
create). create).
@comment The gratuitous blank line here is to make the table look better
@comment in the printed Make manual. Please leave it in.
@item clean @item clean
Delete all files from the current directory that are normally created by Delete all files from the current directory that are normally created by
building the program. Don't delete the files that record the building the program. Don't delete the files that record the
configuration. Also preserve files that could be made by building, but configuration. Also preserve files that could be made by building, but
@@ -174,8 +231,8 @@ is rarely necessary and takes a lot of time.
@item realclean @item realclean
Delete everything from the current directory that can be reconstructed Delete everything from the current directory that can be reconstructed
with this Makefile. This typically includes everything deleted by with this Makefile. This typically includes everything deleted by
distclean, plus more: C source files produced by Bison, tags tables, @code{distclean}, plus more: C source files produced by Bison, tags tables,
info files, and so on. Info files, and so on.
One exception, however: @samp{make realclean} should not delete One exception, however: @samp{make realclean} should not delete
@file{configure} even if @file{configure} can be remade using a rule in @file{configure} even if @file{configure} can be remade using a rule in
@@ -187,34 +244,35 @@ and then begin to build the program.
Update a tags table for this program. Update a tags table for this program.
@item info @item info
Generate any info files needed. The best way to write the rules is as Generate any Info files needed. The best way to write the rules is as
follows: follows:
@example @smallexample
info: foo.info info: foo.info
foo.info: $(srcdir)/foo.texi $(srcdir)/chap1.texi $(srcdir)/chap2.texi foo.info: foo.texi chap1.texi chap2.texi
$(MAKEINFO) $(srcdir)/foo.texi $(MAKEINFO) $(srcdir)/foo.texi
@end example @end smallexample
@noindent @noindent
You must define the variable @code{MAKEINFO} in the Makefile. You must define the variable @code{MAKEINFO} in the Makefile. It should
It should run the Makeinfo program, which is part of the Texinfo2 distribution. run the @code{makeinfo} program, which is part of the Texinfo
distribution.
@item dvi @item dvi
Generate DVI files for all TeXinfo documentation. Generate DVI files for all TeXinfo documentation.
For example: For example:
@example @smallexample
dvi: foo.dvi dvi: foo.dvi
foo.dvi: $(srcdir)/foo.texi $(srcdir)/chap1.texi $(srcdir)/chap2.texi foo.dvi: foo.texi chap1.texi chap2.texi
$(TEXI2DVI) $(srcdir)/foo.texi $(TEXI2DVI) $(srcdir)/foo.texi
@end example @end smallexample
@noindent @noindent
You must define the variable @code{TEXI2DVI} in the Makefile. It should You must define the variable @code{TEXI2DVI} in the Makefile. It should
run the program @code{texi2dvi}, which is part of the Texinfo2 run the program @code{texi2dvi}, which is part of the Texinfo
distribution. Alternatively, write just the dependencies, and allow GNU distribution. Alternatively, write just the dependencies, and allow GNU
Make to provide the command. Make to provide the command.
@@ -243,6 +301,34 @@ the self-tests so that they work when the program is built but not
installed. installed.
@end table @end table
The following targets are suggested as conventional names, for programs
in which they are useful.
@table @code
@item installcheck
Perform installation tests (if any). The user must build and install
the program before running the tests. You should not assume that
@file{$(bindir)} is in the search path.
@item installdirs
It's useful to add a target named @samp{installdirs} to create the
directories where files are installed, and their parent directories.
There is a script called @file{mkinstalldirs} which is convenient for
this; find it in the Texinfo package.@c It's in /gd/gnu/lib/mkinstalldirs.
You can use a rule like this:
@comment This has been carefully formatted to look decent in the Make manual.
@comment Please be sure not to make it extend any further to the right.--roland
@smallexample
# Make sure all installation directories (e.g. $(bindir))
# actually exist by making them if necessary.
installdirs: mkinstalldirs
$(srcdir)/mkinstalldirs $(bindir) $(datadir) \
$(libdir) $(infodir) \
$(mandir)
@end smallexample
@end table
@node Command Variables @node Command Variables
@section Variables for Specifying Commands @section Variables for Specifying Commands
@@ -274,12 +360,12 @@ Instead, arrange to pass the necessary options to the C compiler
independently of @code{CFLAGS}, by writing them explicitly in the independently of @code{CFLAGS}, by writing them explicitly in the
compilation commands or by defining an implicit rule, like this: compilation commands or by defining an implicit rule, like this:
@example @smallexample
CFLAGS = -g CFLAGS = -g
ALL_CFLAGS = $(CFLAGS) -I. ALL_CFLAGS = -I. $(CFLAGS)
.c.o: .c.o:
$(CC) -c $(ALL_CFLAGS) $(CPPFLAGS) $< $(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) $<
@end example @end smallexample
Do include the @samp{-g} option in @code{CFLAGS}, because that is not Do include the @samp{-g} option in @code{CFLAGS}, because that is not
@emph{required} for proper compilation. You can consider it a default @emph{required} for proper compilation. You can consider it a default
@@ -287,11 +373,15 @@ that is only recommended. If the package is set up so that it is
compiled with GCC by default, then you might as well include @samp{-O} compiled with GCC by default, then you might as well include @samp{-O}
in the default value of @code{CFLAGS} as well. in the default value of @code{CFLAGS} as well.
Put @code{CFLAGS} last in the compilation command, after other variables
containing compiler options, so the user can use @code{CFLAGS} to
override the others.
Every Makefile should define the variable @code{INSTALL}, which is the Every Makefile should define the variable @code{INSTALL}, which is the
basic command for installing a file into the system. basic command for installing a file into the system.
Every Makefile should also define variables @code{INSTALL_PROGRAM} and Every Makefile should also define the variables @code{INSTALL_PROGRAM}
@code{INSTALL_DATA}. (The default for each of these should be and @code{INSTALL_DATA}. (The default for each of these should be
@code{$(INSTALL)}.) Then it should use those variables as the commands @code{$(INSTALL)}.) Then it should use those variables as the commands
for actual installation, for executables and nonexecutables for actual installation, for executables and nonexecutables
respectively. Use these variables as follows: respectively. Use these variables as follows:
@@ -311,7 +401,11 @@ installed.
Installation directories should always be named by variables, so it is Installation directories should always be named by variables, so it is
easy to install in a nonstandard place. The standard names for these easy to install in a nonstandard place. The standard names for these
variables are: variables are as follows.
These two variables set the root for the installation. All the other
installation directories should be subdirectories of one of these two,
and nothing should be directly installed into these two directories.
@table @samp @table @samp
@item prefix @item prefix
@@ -320,39 +414,107 @@ below. The default value of @code{prefix} should be @file{/usr/local}
(at least for now). (at least for now).
@item exec_prefix @item exec_prefix
A prefix used in constructing the default values of the some of the A prefix used in constructing the default values of some of the
variables listed below. The default value of @code{exec_prefix} should variables listed below. The default value of @code{exec_prefix} should
be @code{$(prefix)}. be @code{$(prefix)}.
Generally, @code{$(exec_prefix)} is used for directories that contain Generally, @code{$(exec_prefix)} is used for directories that contain
machine-specific files (such as executables and subroutine libraries), machine-specific files (such as executables and subroutine libraries),
while @code{$(prefix)} is used directly for other directories. while @code{$(prefix)} is used directly for other directories.
@end table
Executable programs are installed in one of the following directories.
@table @samp
@item bindir @item bindir
The directory for installing executable programs that users can run. The directory for installing executable programs that users can run.
This should normally be @file{/usr/local/bin}, but write it as This should normally be @file{/usr/local/bin}, but write it as
@file{$(exec_prefix)/bin}. @file{$(exec_prefix)/bin}.
@item sbindir
The directory for installing executable programs that can be run from
the shell, but are only generally useful to system administrators. This
should normally be @file{/usr/local/sbin}, but write it as
@file{$(exec_prefix)/sbin}.
@item libexecdir
@comment This paragraph adjusted to avoid overfull hbox --roland 5jul94
The directory for installing executable programs to be run by other
programs rather than by users. This directory should normally be
@file{/usr/local/libexec}, but write it as @file{$(exec_prefix)/libexec}.
@end table
Data files used by the program during its execution are divided into
categories in two ways.
@itemize @bullet
@item
Some files are normally modified by programs; others are never normally
modified (though users may edit some of these).
@item
Some files are architecture-independent and can be shared by all
machines at a site; some are architecture-dependent and can be shared
only by machines of the same kind and operating system; others may never
be shared between two machines.
@end itemize
This makes for six different possibilities. However, we want to
discourage the use of architecture-dependent files, aside from of object
files and libraries. It is much cleaner to make other data files
architecture-independent, and it is generally not hard.
Therefore, here are the variables makefiles should use to specify
directories:
@table @samp
@item datadir
The directory for installing read-only architecture independent data
files. This should normally be @file{/usr/local/share}, but write it as
@file{$(prefix)/share}. As a special exception, see @file{$(infodir)}
and @file{$(includedir)} below.
@item sysconfdir
The directory for installing read-only data files that pertain to a
single machine--that is to say, files for configuring a host. Mailer
and network configuration files, @file{/etc/passwd}, and so forth belong
here. All the files in this directory should be ordinary ASCII text
files. This directory should normally be @file{/usr/local/etc}, but
write it as @file{$(prefix)/etc}.
@c rewritten to avoid overfull hbox --tower
Do not install executables
@c here
in this directory (they probably
belong in @file{$(libexecdir)} or @file{$(sbindir))}. Also do not
install files that are modified in the normal course of their use
(programs whose purpose is to change the configuration of the system
excluded). Those probably belong in @file{$(localstatedir)}.
@item sharedstatedir
The directory for installing architecture-independent data files which
the programs modify while they run. This should normally be
@file{/usr/local/com}, but write it as @file{$(prefix)/com}.
@item localstatedir
The directory for installing data files which the programs modify while
they run, and that pertain to one specific machine. Users should never
need to modify files in this directory to configure the package's
operation; put such configuration information in separate files that go
in @file{datadir} or @file{$(sysconfdir)}. @file{$(localstatedir)}
should normally be @file{/usr/local/var}, but write it as
@file{$(prefix)/var}.
@item libdir @item libdir
The directory for installing executable files to be run by the program The directory for object files and libraries of object code. Do not
rather than by users. Object files and libraries of object code should install executables here, they probably belong in @file{$(libexecdir)}
also go in this directory. The idea is that this directory is used for instead. The value of @code{libdir} should normally be
files that pertain to a specific machine architecture, but need not be
in the path for commands. The value of @code{libdir} should normally be
@file{/usr/local/lib}, but write it as @file{$(exec_prefix)/lib}. @file{/usr/local/lib}, but write it as @file{$(exec_prefix)/lib}.
@item datadir @item infodir
The directory for installing read-only data files which the programs The directory for installing the Info files for this package. By
refer to while they run. This directory is used for files which are default, it should be @file{/usr/local/info}, but it should be written
independent of the type of machine being used. This should normally be as @file{$(prefix)/info}.
@file{/usr/local/lib}, but write it as @file{$(prefix)/lib}.
@item statedir
The directory for installing data files which the programs modify while
they run. These files should be independent of the type of machine
being used, and it should be possible to share them among machines at a
network installation. This should normally be @file{/usr/local/lib},
but write it as @file{$(prefix)/lib}.
@item includedir @item includedir
@c rewritten to avoid overfull hbox --roland @c rewritten to avoid overfull hbox --roland
@@ -384,14 +546,19 @@ file in the @code{oldincludedir} directory if either (1) there is no
@file{foo.h} there or (2) the @file{foo.h} that exists came from the Foo @file{foo.h} there or (2) the @file{foo.h} that exists came from the Foo
package. package.
The way to tell whether @file{foo.h} came from the Foo package is to put To tell whether @file{foo.h} came from the Foo package, put a magic
a magic string in the file---part of a comment---and grep for that string in the file---part of a comment---and grep for that string.
string. @end table
Unix-style man pages are installed in one of the following:
@table @samp
@item mandir @item mandir
The directory for installing the man pages (if any) for this package. The directory for installing the man pages (if any) for this package.
It should include the suffix for the proper section of the It should include the suffix for the proper section of the
manual---usually @samp{1} for a utility. manual---usually @samp{1} for a utility. It will normally be
@file{/usr/local/man/man1}, but you should write it as
@file{$(prefix)/man/man1}.
@item man1dir @item man1dir
The directory for installing section 1 man pages. The directory for installing section 1 man pages.
@@ -408,13 +575,20 @@ application only.}
@item manext @item manext
The file name extension for the installed man page. This should contain The file name extension for the installed man page. This should contain
a period followed by the appropriate digit. a period followed by the appropriate digit; it should normally be @samp{.1}.
@item infodir @item man1ext
The directory for installing the info files for this package. By The file name extension for installed section 1 man pages.
default, it should be @file{/usr/local/info}, but it should be written @item man2ext
as @file{$(prefix)/info}. The file name extension for installed section 2 man pages.
@item @dots{}
Use these names instead of @samp{manext} if the package needs to install man
pages in more than one section of the manual.
@end table
And finally, you should set the following variable:
@table @samp
@item srcdir @item srcdir
The directory for the sources being compiled. The value of this The directory for the sources being compiled. The value of this
variable is normally inserted by the @code{configure} shell script. variable is normally inserted by the @code{configure} shell script.
@@ -422,7 +596,7 @@ variable is normally inserted by the @code{configure} shell script.
For example: For example:
@example @smallexample
@c I have changed some of the comments here slightly to fix an overfull @c I have changed some of the comments here slightly to fix an overfull
@c hbox, so the make manual can format correctly. --roland @c hbox, so the make manual can format correctly. --roland
# Common prefix for installation directories. # Common prefix for installation directories.
@@ -432,10 +606,10 @@ exec_prefix = $(prefix)
# Where to put the executable for the command `gcc'. # Where to put the executable for the command `gcc'.
bindir = $(exec_prefix)/bin bindir = $(exec_prefix)/bin
# Where to put the directories used by the compiler. # Where to put the directories used by the compiler.
libdir = $(exec_prefix)/lib libexecdir = $(exec_prefix)/libexec
# Where to put the Info files. # Where to put the Info files.
infodir = $(prefix)/info infodir = $(prefix)/info
@end example @end smallexample
If your program installs a large number of files into one of the If your program installs a large number of files into one of the
standard user-specified directories, it might be useful to group them standard user-specified directories, it might be useful to group them

21
make.h
View File

@@ -67,7 +67,7 @@ extern int errno;
#endif #endif
/* Some systems define _POSIX_VERSION but are not really POSIX.1. */ /* Some systems define _POSIX_VERSION but are not really POSIX.1. */
#if (defined (butterfly) || \ #if (defined (butterfly) || defined (__arm) || \
(defined (__mips) && defined (_SYSTYPE_SVR3)) || \ (defined (__mips) && defined (_SYSTYPE_SVR3)) || \
(defined (sequent) && defined (i386))) (defined (sequent) && defined (i386)))
#undef POSIX #undef POSIX
@@ -252,6 +252,12 @@ extern char *alloca ();
#define ENUM_BITFIELD(bits) #define ENUM_BITFIELD(bits)
#endif #endif
#ifdef __MSDOS__
#define PATH_SEPARATOR_CHAR ';'
#else
#define PATH_SEPARATOR_CHAR ':'
#endif
extern void die (); extern void die ();
extern void message (), fatal (), error (); extern void message (), fatal (), error ();
extern void makefile_error (), makefile_fatal (); extern void makefile_error (), makefile_fatal ();
@@ -299,17 +305,12 @@ extern void user_access (), make_access (), child_access ();
#include <vfork.h> #include <vfork.h>
#endif #endif
#if !defined (__GNU_LIBRARY__) && !defined (POSIX) /* We omit these declarations on non-POSIX systems which define _POSIX_VERSION,
because such systems often declare the in header files anyway. */
#if !defined (__GNU_LIBRARY__) && !defined (POSIX) && !defined (_POSIX_VERSION)
#ifdef HAVE_SIGSETMASK
extern int sigsetmask ();
extern int sigblock ();
#endif
extern int kill ();
extern int atoi ();
extern long int atol (); extern long int atol ();
extern int unlink (), stat (), fstat ();
extern int pipe (), close (), read (), write (), open ();
extern long int lseek (); extern long int lseek ();
#endif /* Not GNU C library or POSIX. */ #endif /* Not GNU C library or POSIX. */

View File

@@ -8,10 +8,11 @@
@c FSF publishers: format makebook.texi instead of using this file directly. @c FSF publishers: format makebook.texi instead of using this file directly.
@set RCSID $Id$ @set RCSID $Id$
@set EDITION 0.45 @set EDITION 0.46
@set VERSION 3.71 Beta @set VERSION 3.72 Beta
@set UPDATED 11 May 1994 @set UPDATED 5 July 1994
@set UPDATE-MONTH May 1994 @set UPDATE-MONTH July 1994
@set ISBN 1-882114-50-7
@c finalout @c finalout
@@ -71,7 +72,7 @@ Published by the Free Software Foundation @*
675 Massachusetts Avenue, @* 675 Massachusetts Avenue, @*
Cambridge, MA 02139 USA @* Cambridge, MA 02139 USA @*
Printed copies are available for $20 each. @* Printed copies are available for $20 each. @*
ISBN 1-882114-16-7 @* ISBN @value{ISBN} @*
Permission is granted to make and distribute verbatim copies of Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice this manual provided the copyright notice and this permission notice
@@ -2581,7 +2582,8 @@ called @file{@var{name}.d} from a C source file called @file{@var{name}.c}:
@example @example
@group @group
%.d: %.c %.d: %.c
$(SHELL) -ec '$(CC) -M $(CPPFLAGS) $< | sed '\''s/$*.o/& $@@/g'\'' > $@@' $(SHELL) -ec '$(CC) -M $(CPPFLAGS) $< \
| sed '\''s/$*.o/& $@@/g'\'' > $@@'
@end group @end group
@end example @end example
@@ -5581,7 +5583,9 @@ dependencies of goals, or dependencies of dependencies of goals, etc.
By default, the goal is the first target in the makefile (not counting By default, the goal is the first target in the makefile (not counting
targets that start with a period). Therefore, makefiles are usually targets that start with a period). Therefore, makefiles are usually
written so that the first target is for compiling the entire program or written so that the first target is for compiling the entire program or
programs they describe. programs they describe. If the first rule in the makefile has several
targets, only the first target in the rule becomes the default goal, not
the whole list.
You can specify a different goal or goals with arguments to @code{make}. You can specify a different goal or goals with arguments to @code{make}.
Use the name of the goal as an argument. If you specify several goals, Use the name of the goal as an argument. If you specify several goals,
@@ -7620,6 +7624,7 @@ main use is as subroutine libraries for linking.
@menu @menu
* Archive Members:: Archive members as targets. * Archive Members:: Archive members as targets.
* Archive Update:: The implicit rule for archive member targets. * Archive Update:: The implicit rule for archive member targets.
* Archive Pitfalls:: Dangers to watch out for when using archives.
* Archive Suffix Rules:: You can write a special kind of suffix rule * Archive Suffix Rules:: You can write a special kind of suffix rule
for updating archives. for updating archives.
@end menu @end menu
@@ -7676,7 +7681,7 @@ example, @w{@samp{foolib(*.o)}} expands to all existing members of the
@file{foolib} archive whose names end in @samp{.o}; perhaps @file{foolib} archive whose names end in @samp{.o}; perhaps
@samp{@w{foolib(hack.o)} @w{foolib(kludge.o)}}. @samp{@w{foolib(hack.o)} @w{foolib(kludge.o)}}.
@node Archive Update, Archive Suffix Rules, Archive Members, Archives @node Archive Update
@section Implicit Rule for Archive Member Targets @section Implicit Rule for Archive Member Targets
Recall that a target that looks like @file{@var{a}(@var{m})} stands for the Recall that a target that looks like @file{@var{a}(@var{m})} stands for the
@@ -7766,7 +7771,24 @@ files into the archive, as described in the preceding section.
This is not necessary when using the GNU @code{ar} program, which This is not necessary when using the GNU @code{ar} program, which
updates the @file{__.SYMDEF} member automatically. updates the @file{__.SYMDEF} member automatically.
@node Archive Suffix Rules, , Archive Update, Archives @node Archive Pitfalls
@section Dangers When Using Archives
@cindex archive, and parallel execution
@cindex parallel execution, and archive update
@cindex archive, and @code{-j}
@cindex @code{-j}, and archive update
It is important to be careful when using parallel execution (the
@code{-j} switch; @pxref{Parallel, ,Parallel Execution}) and archives.
If multiple @code{ar} commands run at the same time on the same archive
file, they will not know about each other and can corrupt the file.
Possibly a future version of @code{make} will provide a mechanism to
circumvent this problem by serializing all commands that operate on the
same archive file. But for the time being, you must either write your
makefiles to avoid this problem in some other way, or not use @code{-j}.
@node Archive Suffix Rules, , Archive Pitfalls, Archives
@section Suffix Rules for Archive Files @section Suffix Rules for Archive Files
@cindex suffix rule, for archive @cindex suffix rule, for archive
@cindex archive, suffix rule for @cindex archive, suffix rule for

24
misc.c
View File

@@ -461,12 +461,8 @@ dep_name (dep)
setregid functions, but they don't work as in BSD and only the POSIX.1 setregid functions, but they don't work as in BSD and only the POSIX.1
way works. */ way works. */
#ifndef HAVE_SETREUID
#undef HAVE_SETREUID #undef HAVE_SETREUID
#endif
#ifndef HAVE_SETREGID
#undef HAVE_SETREGID #undef HAVE_SETREGID
#endif
#else /* Not POSIX. */ #else /* Not POSIX. */
@@ -720,3 +716,23 @@ get_path_max ()
return value; return value;
} }
#endif #endif
/* On some systems, stat can return EINTR. */
int
safe_stat (name, buf)
char *name;
struct stat *buf;
{
int ret;
#ifdef EINTR
do
#endif
ret = stat (name, buf);
#ifdef EINTR
while (ret < 0 && errno == EINTR);
#endif
return ret;
}

103
read.c
View File

@@ -240,6 +240,7 @@ read_makefile (filename, flags)
char *p2; char *p2;
int ignoring = 0, in_ignored_define = 0; int ignoring = 0, in_ignored_define = 0;
int no_targets = 0; /* Set when reading a rule without targets. */ int no_targets = 0; /* Set when reading a rule without targets. */
char *passed_filename = filename;
struct nameseq *filenames = 0; struct nameseq *filenames = 0;
struct dep *deps; struct dep *deps;
@@ -288,7 +289,6 @@ read_makefile (filename, flags)
if (!(flags & RM_NO_TILDE) && filename[0] == '~') if (!(flags & RM_NO_TILDE) && filename[0] == '~')
{ {
char *expanded = tilde_expand (filename); char *expanded = tilde_expand (filename);
/* This is a possible memory leak, but I don't care. */
if (expanded != 0) if (expanded != 0)
filename = expanded; filename = expanded;
} }
@@ -330,6 +330,8 @@ read_makefile (filename, flags)
if (flags & RM_DONTCARE) if (flags & RM_DONTCARE)
deps->file->dontcare = 1; deps->file->dontcare = 1;
} }
if (filename != passed_filename)
free (filename);
filename = deps->file->name; filename = deps->file->name;
deps->changed = flags; deps->changed = flags;
deps = 0; deps = 0;
@@ -360,6 +362,47 @@ read_makefile (filename, flags)
lineno += nlines; lineno += nlines;
nlines = readline (&lb, infile, filename, lineno); nlines = readline (&lb, infile, filename, lineno);
/* Check for a shell command line first.
If it is not one, we can stop treating tab specially. */
if (lb.buffer[0] == '\t')
{
/* This line is a probably shell command. */
unsigned int len;
if (no_targets)
/* Ignore the commands in a rule with no targets. */
continue;
/* If there is no preceding rule line, don't treat this line
as a command, even though it begins with a tab character.
SunOS 4 make appears to behave this way. */
if (filenames != 0)
{
if (ignoring)
/* Yep, this is a shell command, and we don't care. */
continue;
/* Append this command line to the line being accumulated. */
p = lb.buffer;
if (commands_idx == 0)
commands_started = lineno;
len = strlen (p);
if (len + 1 + commands_idx > commands_len)
{
commands_len = (len + 1 + commands_idx) * 2;
commands = (char *) xrealloc (commands, commands_len);
}
bcopy (p, &commands[commands_idx], len);
commands_idx += len;
commands[commands_idx++] = '\n';
continue;
}
}
/* This line is not a shell command line. Don't worry about tabs. */
if (collapsed_length < lb.size) if (collapsed_length < lb.size)
{ {
collapsed_length = lb.size; collapsed_length = lb.size;
@@ -372,17 +415,20 @@ read_makefile (filename, flags)
collapse_continuations (collapsed); collapse_continuations (collapsed);
remove_comments (collapsed); remove_comments (collapsed);
p = collapsed;
while (isspace (*p) && *p != '\t')
++p;
/* We cannot consider a line containing just a tab to be empty
because it might constitute an empty command for a target. */
if (*p == '\0' && lb.buffer[0] != '\t')
continue;
/* strncmp is first to avoid dereferencing out into space. */ /* strncmp is first to avoid dereferencing out into space. */
#define word1eq(s, l) (!strncmp (s, p, l) \ #define word1eq(s, l) (!strncmp (s, p, l) \
&& (p[l] == '\0' || isblank (p[l]))) && (p[l] == '\0' || isblank (p[l])))
p = collapsed;
while (isspace (*p))
++p;
if (*p == '\0')
/* This line is completely empty. */
continue;
/* We must first check for conditional and `define' directives before
ignoring anything, since they control what we will do with
following lines. */
if (!in_ignored_define if (!in_ignored_define
&& (word1eq ("ifdef", 5) || word1eq ("ifndef", 6) && (word1eq ("ifdef", 5) || word1eq ("ifndef", 6)
|| word1eq ("ifeq", 4) || word1eq ("ifneq", 5) || word1eq ("ifeq", 4) || word1eq ("ifneq", 5)
@@ -458,40 +504,7 @@ read_makefile (filename, flags)
/* Ignore the line. We continue here so conditionals /* Ignore the line. We continue here so conditionals
can appear in the middle of a rule. */ can appear in the middle of a rule. */
continue; continue;
else if (lb.buffer[0] == '\t') else if (word1eq ("export", 6))
{
/* This line is a shell command. */
unsigned int len;
if (no_targets)
/* Ignore the commands in a rule with no targets. */
continue;
/* If there is no preceding rule line, don't treat this line
as a command, even though it begins with a tab character.
SunOS 4 make appears to behave this way. */
if (filenames != 0)
{
/* Append this command line to the line being accumulated. */
p = lb.buffer;
if (commands_idx == 0)
commands_started = lineno;
len = strlen (p);
if (len + 1 + commands_idx > commands_len)
{
commands_len = (len + 1 + commands_idx) * 2;
commands = (char *) xrealloc (commands, commands_len);
}
bcopy (p, &commands[commands_idx], len);
commands_idx += len;
commands[commands_idx++] = '\n';
continue;
}
}
if (word1eq ("export", 6))
{ {
struct variable *v; struct variable *v;
p2 = next_token (p + 6); p2 = next_token (p + 6);
@@ -1788,7 +1801,7 @@ construct_include_path (arg_dirs)
dir = expanded; dir = expanded;
} }
if (stat (dir, &stbuf) == 0 && S_ISDIR (stbuf.st_mode)) if (safe_stat (dir, &stbuf) == 0 && S_ISDIR (stbuf.st_mode))
{ {
if (idx == max - 1) if (idx == max - 1)
{ {
@@ -1805,7 +1818,7 @@ construct_include_path (arg_dirs)
/* Now add at the end the standard default dirs. */ /* Now add at the end the standard default dirs. */
for (i = 0; default_include_directories[i] != 0; ++i) for (i = 0; default_include_directories[i] != 0; ++i)
if (stat (default_include_directories[i], &stbuf) == 0 if (safe_stat (default_include_directories[i], &stbuf) == 0
&& S_ISDIR (stbuf.st_mode)) && S_ISDIR (stbuf.st_mode))
dirs[idx++] = default_include_directories[i]; dirs[idx++] = default_include_directories[i];

View File

@@ -468,7 +468,7 @@ update_file_1 (file, depth)
if (running) if (running)
{ {
file->command_state = cs_deps_running; set_command_state (file, cs_deps_running);
--depth; --depth;
DEBUGPR ("The dependencies of `%s' are being made.\n"); DEBUGPR ("The dependencies of `%s' are being made.\n");
return 0; return 0;
@@ -478,9 +478,8 @@ update_file_1 (file, depth)
if (dep_status != 0) if (dep_status != 0)
{ {
file->command_state = cs_finished;
file->update_status = dep_status; file->update_status = dep_status;
file->updated = 1; notice_finished_file (file);
depth--; depth--;
@@ -493,7 +492,7 @@ update_file_1 (file, depth)
return dep_status; return dep_status;
} }
file->command_state = cs_not_started; set_command_state (file, cs_not_started);
/* Now record which dependencies are more /* Now record which dependencies are more
recent than this file, so we can define $?. */ recent than this file, so we can define $?. */
@@ -549,9 +548,8 @@ update_file_1 (file, depth)
if (!must_make) if (!must_make)
{ {
DEBUGPR ("No need to remake target `%s'.\n"); DEBUGPR ("No need to remake target `%s'.\n");
file->command_state = cs_finished;
file->update_status = 0; file->update_status = 0;
file->updated = 1; notice_finished_file (file);
return 0; return 0;
} }
@@ -596,6 +594,7 @@ notice_finished_file (file)
register struct file *file; register struct file *file;
{ {
struct dep *d; struct dep *d;
int ran = file->command_state == cs_running;
file->command_state = cs_finished; file->command_state = cs_finished;
file->updated = 1; file->updated = 1;
@@ -629,7 +628,7 @@ notice_finished_file (file)
} }
} }
if (!file->phony) if (ran && !file->phony)
{ {
struct file *f; struct file *f;
@@ -656,7 +655,7 @@ notice_finished_file (file)
d->file->updated = 1; d->file->updated = 1;
d->file->update_status = file->update_status; d->file->update_status = file->update_status;
if (!d->file->phony) if (ran && !d->file->phony)
/* Fetch the new modification time. /* Fetch the new modification time.
We do this instead of just invalidating the cached time We do this instead of just invalidating the cached time
so that a vpath_search can happen. Otherwise, it would so that a vpath_search can happen. Otherwise, it would
@@ -738,7 +737,7 @@ check_dep (file, depth, this_mtime, must_make_ptr)
/* Record that some of FILE's dependencies are still being made. /* Record that some of FILE's dependencies are still being made.
This tells the upper levels to wait on processing it until This tells the upper levels to wait on processing it until
the commands are finished. */ the commands are finished. */
file->command_state = cs_deps_running; set_command_state (file, cs_deps_running);
lastd = d; lastd = d;
d = d->next; d = d->next;
@@ -777,8 +776,16 @@ touch_file (file)
{ {
struct stat statbuf; struct stat statbuf;
char buf; char buf;
int status;
if (fstat (fd, &statbuf) < 0) #ifdef EINTR
do
#endif
status = fstat (fd, &statbuf);
#ifdef EINTR
while (status < 0 && errno == EINTR);
#endif
if (status < 0)
TOUCH_ERROR ("touch: fstat: "); TOUCH_ERROR ("touch: fstat: ");
/* Rewrite character 0 same as it already is. */ /* Rewrite character 0 same as it already is. */
if (read (fd, &buf, 1) < 0) if (read (fd, &buf, 1) < 0)
@@ -971,7 +978,7 @@ name_mtime (name)
{ {
struct stat st; struct stat st;
if (stat (name, &st) < 0) if (safe_stat (name, &st) < 0)
return (time_t) -1; return (time_t) -1;
return (time_t) st.st_mtime; return (time_t) st.st_mtime;

17
vpath.c
View File

@@ -1,5 +1,5 @@
/* Implementation of pattern-matching file search paths for GNU Make. /* Implementation of pattern-matching file search paths for GNU Make.
Copyright (C) 1988, 1989, 1991, 1992, 1993 Free Software Foundation, Inc. Copyright (C) 1988, 1989, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify GNU Make is free software; you can redistribute it and/or modify
@@ -177,7 +177,7 @@ construct_vpath_list (pattern, dirpath)
maxelem = 2; maxelem = 2;
p = dirpath; p = dirpath;
while (*p != '\0') while (*p != '\0')
if (*p++ == ':' || isblank (*p)) if (*p++ == PATH_SEPARATOR_CHAR || isblank (*p))
++maxelem; ++maxelem;
vpath = (char **) xmalloc (maxelem * sizeof (char *)); vpath = (char **) xmalloc (maxelem * sizeof (char *));
@@ -185,7 +185,7 @@ construct_vpath_list (pattern, dirpath)
/* Skip over any initial colons and blanks. */ /* Skip over any initial colons and blanks. */
p = dirpath; p = dirpath;
while (*p == ':' || isblank (*p)) while (*p == PATH_SEPARATOR_CHAR || isblank (*p))
++p; ++p;
elem = 0; elem = 0;
@@ -196,7 +196,7 @@ construct_vpath_list (pattern, dirpath)
/* Find the end of this entry. */ /* Find the end of this entry. */
v = p; v = p;
while (*p != '\0' && *p != ':' && !isblank (*p)) while (*p != '\0' && *p != PATH_SEPARATOR_CHAR && !isblank (*p))
++p; ++p;
len = p - v; len = p - v;
@@ -225,7 +225,7 @@ construct_vpath_list (pattern, dirpath)
} }
/* Skip over colons and blanks between entries. */ /* Skip over colons and blanks between entries. */
while (*p == ':' || isblank (*p)) while (*p == PATH_SEPARATOR_CHAR || isblank (*p))
++p; ++p;
} }
@@ -419,7 +419,7 @@ selective_vpath_search (path, file, mtime_ptr)
*n = '/'; *n = '/';
if (!exists_in_cache /* Makefile-mentioned file need not exist. */ if (!exists_in_cache /* Makefile-mentioned file need not exist. */
|| stat (name, &st) == 0) /* Does it really exist? */ || safe_stat (name, &st) == 0) /* Does it really exist? */
{ {
/* We have found a file. /* We have found a file.
Store the name we found into *FILE for the caller. */ Store the name we found into *FILE for the caller. */
@@ -461,7 +461,7 @@ print_vpath_data_base ()
for (i = 0; v->searchpath[i] != 0; ++i) for (i = 0; v->searchpath[i] != 0; ++i)
printf ("%s%c", v->searchpath[i], printf ("%s%c", v->searchpath[i],
v->searchpath[i + 1] == 0 ? '\n' : ':'); v->searchpath[i + 1] == 0 ? '\n' : PATH_SEPARATOR_CHAR);
} }
if (vpaths == 0) if (vpaths == 0)
@@ -479,6 +479,7 @@ print_vpath_data_base ()
fputs ("\n# General (`VPATH' variable) search path:\n# ", stdout); fputs ("\n# General (`VPATH' variable) search path:\n# ", stdout);
for (i = 0; path[i] != 0; ++i) for (i = 0; path[i] != 0; ++i)
printf ("%s%c", path[i], path[i + 1] == 0 ? '\n' : ':'); printf ("%s%c", path[i],
path[i + 1] == 0 ? '\n' : PATH_SEPARATOR_CHAR);
} }
} }