mirror of
https://github.com/mirror/make.git
synced 2026-08-20 00:43:29 +08:00
Compare commits
71 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dc44a79020 | ||
|
|
8ed6e13cfe | ||
|
|
b321e0f535 | ||
|
|
c1433e9495 | ||
|
|
e4a94e0210 | ||
|
|
9e97330bcb | ||
|
|
4969b416b8 | ||
|
|
0bd0301ae3 | ||
|
|
ff6efbadf5 | ||
|
|
0b3317d2e1 | ||
|
|
ca5a872280 | ||
|
|
4244f182f2 | ||
|
|
be6e6d74bb | ||
|
|
4c0fef3dd7 | ||
|
|
d3b65c3cb7 | ||
|
|
bc48185f8e | ||
|
|
6fcf219fa7 | ||
|
|
d2e23eefd2 | ||
|
|
55162a6730 | ||
|
|
021ea7e61c | ||
|
|
f663464925 | ||
|
|
5d435e0859 | ||
|
|
a2ab31ba62 | ||
|
|
da2ea1ea7f | ||
|
|
21a1b3b255 | ||
|
|
c8e76a708e | ||
|
|
461cffc4e9 | ||
|
|
cdd25d1fb3 | ||
|
|
9a3666d550 | ||
|
|
90dffad2cc | ||
|
|
c1f2ef6d09 | ||
|
|
51250a676d | ||
|
|
d2461a2409 | ||
|
|
fdea69c5fa | ||
|
|
7c7552336d | ||
|
|
535dcf6a22 | ||
|
|
84091971f9 | ||
|
|
61da194af9 | ||
|
|
30c1465265 | ||
|
|
b574b8ea5a | ||
|
|
710e8e6f6f | ||
|
|
4a8a7637f3 | ||
|
|
6348923799 | ||
|
|
660a23d649 | ||
|
|
5bd9836fba | ||
|
|
0cb47363e1 | ||
|
|
fff5a9ece0 | ||
|
|
e3a24fc596 | ||
|
|
bb38b0c253 | ||
|
|
d2ed03e72a | ||
|
|
e72213687f | ||
|
|
491d66a916 | ||
|
|
f4fb1be3d8 | ||
|
|
10abeb4a08 | ||
|
|
a369402d11 | ||
|
|
fe3962cf54 | ||
|
|
cf76b42f2b | ||
|
|
fb088e4526 | ||
|
|
f2804372bd | ||
|
|
c25db14264 | ||
|
|
e83c7d40cd | ||
|
|
65d0cd98a9 | ||
|
|
ec505152e0 | ||
|
|
0d2488a804 | ||
|
|
bc5f054132 | ||
|
|
e812d40f9f | ||
|
|
b12c639bb2 | ||
|
|
dd841ded6f | ||
|
|
3c9e8b266a | ||
|
|
e6bce5ef88 | ||
|
|
bdff21b09a |
11
GNUmakefile
11
GNUmakefile
@@ -31,7 +31,7 @@ override srcdir := .
|
||||
override CC := $(CC)
|
||||
|
||||
ifeq ($(ARCH),hp300)
|
||||
customs=yes
|
||||
#customs=yes
|
||||
endif
|
||||
ifdef customs
|
||||
override REMOTE := cstms
|
||||
@@ -49,11 +49,10 @@ extras := $(filter-out getloadavg.o @%@,$(extras)) getloadavg.o
|
||||
LOADLIBES := $(filter-out @%@,$(LOADLIBES))
|
||||
ALLOCA := $(filter-out @%@,$(ALLOCA))
|
||||
|
||||
# Tell autoconf/autoheader to use m4 files from the master source.
|
||||
ACFLAGS := -m /home/gd/gnu/autoconf
|
||||
configure config.h.in: $(patsubst %,/home/gd/gnu/autoconf/%.m4,\
|
||||
acspecific acgeneral)
|
||||
config.h.in: /home/gd/gnu/autoconf/acconfig.h
|
||||
ifdef AC_MACRODIR
|
||||
configure config.h.in: $(patsubst %,$(AC_MACRODIR)/%.m4,acspecific acgeneral)
|
||||
config.h.in: $(AC_MACRODIR)/acconfig.h
|
||||
endif
|
||||
configure: configure.in; autoconf $(ACFLAGS)
|
||||
config.h.in: configure.in; autoheader $(ACFLAGS)
|
||||
|
||||
|
||||
@@ -3,3 +3,9 @@
|
||||
|
||||
/* Define this if the SCCS `get' command understands the `-G<file>' option. */
|
||||
#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
|
||||
|
||||
12
alloca.c
12
alloca.c
@@ -29,6 +29,10 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef emacs
|
||||
#include "blockinput.h"
|
||||
#endif
|
||||
|
||||
/* If compiling with GCC 2, this file's not needed. */
|
||||
#if !defined (__GNUC__) || __GNUC__ < 2
|
||||
|
||||
@@ -176,6 +180,10 @@ alloca (size)
|
||||
{
|
||||
register header *hp; /* Traverses linked list. */
|
||||
|
||||
#ifdef emacs
|
||||
BLOCK_INPUT;
|
||||
#endif
|
||||
|
||||
for (hp = last_alloca_header; hp != NULL;)
|
||||
if ((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. */
|
||||
|
||||
last_alloca_header = hp; /* -> last valid storage. */
|
||||
|
||||
#ifdef emacs
|
||||
UNBLOCK_INPUT;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (size == 0)
|
||||
|
||||
4
arscan.c
4
arscan.c
@@ -495,7 +495,11 @@ ar_member_touch (arname, memname)
|
||||
if (AR_HDR_SIZE != write (fd, (char *) &ar_hdr, AR_HDR_SIZE))
|
||||
goto lose;
|
||||
/* The file's mtime is the time we we want. */
|
||||
#ifdef EINTR
|
||||
while (fstat (fd, &statbuf) < 0 && errno == EINTR);
|
||||
#else
|
||||
fstat (fd, &statbuf);
|
||||
#endif
|
||||
#if defined(ARFMAG) || defined(AIAMAG)
|
||||
/* Advance member's time to that time */
|
||||
for (i = 0; i < sizeof ar_hdr.ar_date; i++)
|
||||
|
||||
@@ -87,7 +87,7 @@ set_file_variables (file)
|
||||
for (d = enter_file (".SUFFIXES")->deps; d != 0; d = d->next)
|
||||
{
|
||||
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);
|
||||
break;
|
||||
@@ -329,6 +329,10 @@ RETSIGTYPE
|
||||
fatal_error_signal (sig)
|
||||
int sig;
|
||||
{
|
||||
#ifdef __MSDOS__
|
||||
remove_intermediates (1);
|
||||
exit (1);
|
||||
#else /* Not MSDOS. */
|
||||
handling_fatal_signal = 1;
|
||||
|
||||
/* 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. */
|
||||
if (kill (getpid (), sig) < 0)
|
||||
pfatal_with_name ("kill");
|
||||
#endif /* MSDOS. */
|
||||
}
|
||||
|
||||
/* Delete FILE unless it's precious or not actually a file (phony),
|
||||
@@ -416,7 +421,7 @@ delete_target (file, on_behalf_of)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (stat (file->name, &st) == 0
|
||||
if (safe_stat (file->name, &st) == 0
|
||||
&& S_ISREG (st.st_mode)
|
||||
&& (time_t) st.st_mtime != file->last_mtime)
|
||||
{
|
||||
|
||||
@@ -24,7 +24,8 @@
|
||||
|
||||
# Ultrix 2.2 make doesn't expand the value of VPATH.
|
||||
VPATH = @srcdir@
|
||||
srcdir = $(VPATH)
|
||||
# This must repeat the value, because configure will remove `VPATH = .'.
|
||||
srcdir = @srcdir@
|
||||
|
||||
CC = @CC@
|
||||
|
||||
@@ -228,9 +229,14 @@ $(mandir)/$(manprefix)make.$(manext): make.man
|
||||
$(INSTALL_DATA) $(srcdir)/make.man $@
|
||||
|
||||
|
||||
loadavg: getloadavg.c config.h
|
||||
loadavg: loadavg.c config.h
|
||||
$(CC) $(defines) -DTEST -I. -I$(srcdir) $(CFLAGS) $(LDFLAGS) \
|
||||
$(srcdir)/getloadavg.c $(LOADLIBES) -o $@
|
||||
loadavg.c $(LOADLIBES) -o $@
|
||||
# We copy getloadavg.c into a different file rather than compiling it
|
||||
# directly because some compilers clobber getloadavg.o in the process.
|
||||
loadavg.c: getloadavg.c
|
||||
ln $(srcdir)/getloadavg.c loadavg.c || \
|
||||
cp $(srcdir)/getloadavg.c loadavg.c
|
||||
check-loadavg: loadavg
|
||||
@echo The system uptime program believes the load average to be:
|
||||
-uptime
|
||||
@@ -246,6 +252,7 @@ distclean: clean glob-realclean
|
||||
-rm -f Makefile config.h config.status build.sh stamp-config
|
||||
-rm -f TAGS tags
|
||||
-rm -f make.?? make.??s make.log make.toc make.*aux
|
||||
-rm -f loadavg.c
|
||||
realclean: distclean
|
||||
mostlyclean: clean
|
||||
|
||||
@@ -255,6 +262,8 @@ glob-clean glob-realclean:
|
||||
|
||||
Makefile: config.status $(srcdir)/Makefile.in
|
||||
$(SHELL) config.status
|
||||
glob/Makefile: config.status $(srcdir)/glob/Makefile.in
|
||||
$(SHELL) config.status
|
||||
config.h: stamp-config ;
|
||||
stamp-config: config.status $(srcdir)/config.h.in
|
||||
$(SHELL) config.status
|
||||
|
||||
65
configh.dos.template
Normal file
65
configh.dos.template
Normal 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
43
configure.bat
Normal 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 ..
|
||||
10
configure.in
10
configure.in
@@ -29,9 +29,15 @@ AC_STAT_MACROS_BROKEN
|
||||
|
||||
AC_SUBST(LIBOBJS)
|
||||
|
||||
AC_HAVE_FUNCS(getdtablesize sys_siglist _sys_siglist psignal \
|
||||
AC_HAVE_FUNCS(getdtablesize psignal \
|
||||
dup2 getcwd sigsetmask getgroups setlinebuf \
|
||||
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_VFORK
|
||||
AC_SETVBUF_REVERSED
|
||||
@@ -81,7 +87,7 @@ if ( /usr/sccs/admin -n s.conftest || admin -n s.conftest ) >/dev/null 2>&1 &&
|
||||
test -f s.conftest; then
|
||||
# We successfully created an SCCS file.
|
||||
echo checking if SCCS get command understands -G
|
||||
if $SCCS_GET s.conftest -Gconftoast >/dev/null 2>&1 &&
|
||||
if $SCCS_GET -Gconftoast s.conftest >/dev/null 2>&1 &&
|
||||
test -f conftoast; then
|
||||
AC_DEFINE(SCCS_GET_MINUS_G)
|
||||
fi
|
||||
|
||||
31
default.c
31
default.c
@@ -23,6 +23,12 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#include "commands.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.
|
||||
`.s' must come last, so that a `.o' file will be made from
|
||||
@@ -63,9 +69,9 @@ static struct pspec default_terminal_rules[] =
|
||||
|
||||
/* SCCS. */
|
||||
{ "%", "s.%",
|
||||
"$(GET) $(GFLAGS) $< $(SCCS_OUTPUT_OPTION)" },
|
||||
"$(GET) $(GFLAGS) $(SCCS_OUTPUT_OPTION) $<" },
|
||||
{ "%", "SCCS/s.%",
|
||||
"$(GET) $(GFLAGS) $< $(SCCS_OUTPUT_OPTION)" },
|
||||
"$(GET) $(GFLAGS) $(SCCS_OUTPUT_OPTION) $<" },
|
||||
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
@@ -133,12 +139,20 @@ static char *default_suffix_rules[] =
|
||||
".c.ln",
|
||||
"$(LINT.c) -C$* $<",
|
||||
".y.ln",
|
||||
#ifndef __MSDOS__
|
||||
"$(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",
|
||||
"@$(RM) $*.c\n $(LEX.l) $< > $*.c\n$(LINT.c) -i $*.c -o $@\n $(RM) $*.c",
|
||||
|
||||
".y.c",
|
||||
#ifndef __MSDOS__
|
||||
"$(YACC.y) $< \n mv -f y.tab.c $@",
|
||||
#else
|
||||
"$(YACC.y) $< \n mv -f y_tab.c $@",
|
||||
#endif
|
||||
".l.c",
|
||||
"@$(RM) $@ \n $(LEX.l) $< > $@",
|
||||
|
||||
@@ -203,8 +217,13 @@ static char *default_variables[] =
|
||||
"ARFLAGS", "rfv",
|
||||
#endif
|
||||
"AS", "as",
|
||||
#ifdef GCC_IS_NATIVE
|
||||
"CC", "gcc",
|
||||
"CXX", "gcc",
|
||||
#else
|
||||
"CC", "cc",
|
||||
"CXX", "g++",
|
||||
#endif
|
||||
|
||||
/* This expands to $(CO) $(COFLAGS) $< $@ if $@ does not exist,
|
||||
and to the empty string if $@ does exist. */
|
||||
@@ -237,7 +256,11 @@ static char *default_variables[] =
|
||||
#endif /* Cray. */
|
||||
"GET", SCCS_GET,
|
||||
"LD", "ld",
|
||||
#ifdef GCC_IS_NATIVE
|
||||
"LEX", "flex",
|
||||
#else
|
||||
"LEX", "lex",
|
||||
#endif
|
||||
"LINT", "lint",
|
||||
"M2C", "m2c",
|
||||
#ifdef pyr
|
||||
@@ -250,7 +273,11 @@ static char *default_variables[] =
|
||||
"PC", "pc",
|
||||
#endif /* CRAY. */
|
||||
#endif /* pyr. */
|
||||
#ifdef GCC_IS_NATIVE
|
||||
"YACC", "bison -y",
|
||||
#else
|
||||
"YACC", "yacc", /* Or "bison -y" */
|
||||
#endif
|
||||
"MAKEINFO", "makeinfo",
|
||||
"TEX", "tex",
|
||||
"TEXI2DVI", "texi2dvi",
|
||||
|
||||
55
dir.c
55
dir.c
@@ -1,5 +1,5 @@
|
||||
/* 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.
|
||||
|
||||
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)
|
||||
#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. */
|
||||
|
||||
#ifndef DIRECTORY_BUCKETS
|
||||
@@ -136,7 +179,7 @@ find_directory (name)
|
||||
/* The directory is not in the name hash table.
|
||||
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
|
||||
setting the `contents' member to a nil pointer. */
|
||||
dir->contents = 0;
|
||||
@@ -213,6 +256,10 @@ dir_contents_file_exists_p (dir, filename)
|
||||
/* The directory could not be stat'd or opened. */
|
||||
return 0;
|
||||
|
||||
#ifdef __MSDOS__
|
||||
filename = dosify (filename);
|
||||
#endif
|
||||
|
||||
hash = 0;
|
||||
if (filename != 0)
|
||||
{
|
||||
@@ -404,6 +451,10 @@ file_impossible_p (filename)
|
||||
/* There are no files entered for this directory. */
|
||||
return 0;
|
||||
|
||||
#ifdef __MSDOS__
|
||||
p = filename = dosify (p);
|
||||
#endif
|
||||
|
||||
for (hash = 0; *p != '\0'; ++p)
|
||||
HASH (hash, *p);
|
||||
hash %= DIRFILE_BUCKETS;
|
||||
|
||||
15
file.c
15
file.c
@@ -385,6 +385,21 @@ snap_deps ()
|
||||
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. */
|
||||
|
||||
static void
|
||||
|
||||
1
file.h
1
file.h
@@ -85,6 +85,7 @@ extern struct file *default_goal_file, *suffix_file, *default_file;
|
||||
extern struct file *lookup_file (), *enter_file ();
|
||||
extern void remove_intermediates (), snap_deps ();
|
||||
extern void rename_file (), file_hash_enter ();
|
||||
extern void set_command_state ();
|
||||
|
||||
|
||||
extern time_t f_mtime ();
|
||||
|
||||
68
function.c
68
function.c
@@ -22,6 +22,10 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#include "commands.h"
|
||||
#include "job.h"
|
||||
|
||||
#ifdef __MSDOS__
|
||||
#include <process.h>
|
||||
#endif
|
||||
|
||||
static char *string_glob ();
|
||||
|
||||
/* Store into VARIABLE_BUFFER at O the result of scanning TEXT and replacing
|
||||
@@ -371,6 +375,7 @@ expand_function (o, function, text, end)
|
||||
else
|
||||
error_prefix = "";
|
||||
|
||||
#ifndef __MSDOS__
|
||||
if (pipe (pipedes) < 0)
|
||||
{
|
||||
perror_with_name (error_prefix, "pipe");
|
||||
@@ -475,6 +480,69 @@ expand_function (o, function, text, end)
|
||||
|
||||
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);
|
||||
break;
|
||||
|
||||
19
getloadavg.c
19
getloadavg.c
@@ -1,5 +1,5 @@
|
||||
/* 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.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
@@ -80,9 +80,17 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* 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
|
||||
|
||||
@@ -331,11 +339,6 @@
|
||||
#endif
|
||||
|
||||
#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
|
||||
nlist method. */
|
||||
|
||||
141
job.c
141
job.c
@@ -28,6 +28,16 @@ static char default_path[] = ":/bin:/usr/bin";
|
||||
/* Default shell to use. */
|
||||
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 defined (NGROUPS_MAX) && NGROUPS_MAX == 0
|
||||
#undef NGROUPS_MAX
|
||||
@@ -260,6 +270,7 @@ reap_children (block, err)
|
||||
}
|
||||
else if (pid == 0)
|
||||
{
|
||||
#ifndef __MSDOS__
|
||||
/* No remote children. Check for local children. */
|
||||
|
||||
if (any_local)
|
||||
@@ -308,6 +319,14 @@ reap_children (block, err)
|
||||
exit_sig = WIFSIGNALED (status) ? WTERMSIG (status) : 0;
|
||||
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
|
||||
/* We got a remote child. */
|
||||
@@ -419,7 +438,9 @@ reap_children (block, err)
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (debug_flag)
|
||||
@@ -475,6 +496,13 @@ free_child (child)
|
||||
}
|
||||
|
||||
#ifdef POSIX
|
||||
#ifdef __MSDOS__
|
||||
void
|
||||
unblock_sigs ()
|
||||
{
|
||||
return;
|
||||
}
|
||||
#else
|
||||
extern sigset_t fatal_signal_set;
|
||||
|
||||
void
|
||||
@@ -485,6 +513,7 @@ unblock_sigs ()
|
||||
sigprocmask (SIG_SETMASK, &empty, (sigset_t *) 0);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Start a job to run the commands specified in CHILD.
|
||||
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))
|
||||
{
|
||||
child->file->update_status = 1;
|
||||
child->file->command_state = cs_finished;
|
||||
notice_finished_file (child->file);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -618,6 +647,8 @@ start_job_command (child)
|
||||
if (child->environment == 0)
|
||||
child->environment = target_environment (child->file);
|
||||
|
||||
#ifndef __MSDOS__
|
||||
|
||||
/* start_waiting_job has set CHILD->remote if we can start a remote job. */
|
||||
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
|
||||
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. */
|
||||
|
||||
@@ -681,7 +728,7 @@ start_job_command (child)
|
||||
|
||||
error:
|
||||
child->file->update_status = 2;
|
||||
child->file->command_state = cs_finished;
|
||||
notice_finished_file (child->file);
|
||||
}
|
||||
|
||||
/* Try to start a child running.
|
||||
@@ -924,6 +971,9 @@ job_next_command (child)
|
||||
static int
|
||||
load_too_high ()
|
||||
{
|
||||
#ifdef __MSDOS__
|
||||
return 1;
|
||||
#else
|
||||
extern int getloadavg ();
|
||||
double load;
|
||||
|
||||
@@ -949,6 +999,7 @@ load_too_high ()
|
||||
user_access ();
|
||||
|
||||
return load >= max_load_average;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* 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')
|
||||
path = default_path;
|
||||
|
||||
if (index (file, '/') != 0)
|
||||
if (
|
||||
#ifdef __MSDOS__
|
||||
strpbrk (file, "/\\:")
|
||||
#else
|
||||
index (file, '/')
|
||||
#endif
|
||||
!= 0)
|
||||
{
|
||||
strcpy (program, file);
|
||||
return 1;
|
||||
@@ -1049,7 +1106,7 @@ search_path (file, path, program)
|
||||
int perm;
|
||||
char *p;
|
||||
|
||||
p = index (path, ':');
|
||||
p = index (path, PATH_SEPARATOR_CHAR);
|
||||
if (p == 0)
|
||||
p = path + strlen (path);
|
||||
|
||||
@@ -1062,7 +1119,7 @@ search_path (file, path, program)
|
||||
bcopy (file, program + (p - path) + 1, len);
|
||||
}
|
||||
|
||||
if (stat (program, &st) == 0
|
||||
if (safe_stat (program, &st) == 0
|
||||
&& S_ISREG (st.st_mode))
|
||||
{
|
||||
if (st.st_uid == geteuid ())
|
||||
@@ -1189,12 +1246,22 @@ construct_command_argv_internal (line, restp, shell, ifs)
|
||||
char *line, **restp;
|
||||
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_cmds[] = { "cd", "eval", "exec", "exit", "login",
|
||||
"logout", "set", "umask", "wait", "while", "for",
|
||||
"case", "if", ":", ".", "break", "continue",
|
||||
"export", "read", "readonly", "shift", "times",
|
||||
"trap", "switch", 0 };
|
||||
#endif
|
||||
register int i;
|
||||
register char *p;
|
||||
register char *ap;
|
||||
@@ -1241,9 +1308,19 @@ construct_command_argv_internal (line, restp, shell, ifs)
|
||||
|
||||
if (instring)
|
||||
{
|
||||
/* Inside a string, just copy any char except a closing quote. */
|
||||
string_char:
|
||||
/* Inside a string, just copy any char except a closing quote
|
||||
or a backslash-newline combination. */
|
||||
if (*p == '\'')
|
||||
instring = 0;
|
||||
else if (*p == '\\' && p[1] == '\n')
|
||||
goto swallow_escaped_newline;
|
||||
else if (*p == '\n' && restp != NULL)
|
||||
{
|
||||
/* End of the command line. */
|
||||
*restp = p;
|
||||
goto end_of_line;
|
||||
}
|
||||
else
|
||||
*ap++ = *p;
|
||||
}
|
||||
@@ -1269,6 +1346,8 @@ construct_command_argv_internal (line, restp, shell, ifs)
|
||||
/* Backslash-newline combinations are eaten. */
|
||||
if (p[1] == '\n')
|
||||
{
|
||||
swallow_escaped_newline:
|
||||
|
||||
/* Eat the backslash, the newline, and following whitespace,
|
||||
replacing it all with a single space. */
|
||||
p += 2;
|
||||
@@ -1280,13 +1359,18 @@ construct_command_argv_internal (line, restp, shell, ifs)
|
||||
if (*p == '\t')
|
||||
strcpy (p, p + 1);
|
||||
|
||||
if (ap != new_argv[i])
|
||||
/* Treat this as a space, ending the arg.
|
||||
But if it's at the beginning of the arg, it should
|
||||
just get eaten, rather than becoming an empty arg. */
|
||||
goto end_of_arg;
|
||||
if (instring)
|
||||
goto string_char;
|
||||
else
|
||||
p = next_token (p) - 1;
|
||||
{
|
||||
if (ap != new_argv[i])
|
||||
/* Treat this as a space, ending the arg.
|
||||
But if it's at the beginning of the arg, it should
|
||||
just get eaten, rather than becoming an empty arg. */
|
||||
goto end_of_arg;
|
||||
else
|
||||
p = next_token (p) - 1;
|
||||
}
|
||||
}
|
||||
else if (p[1] != '\0')
|
||||
/* Copy and skip the following char. */
|
||||
@@ -1385,6 +1469,34 @@ construct_command_argv_internal (line, restp, shell, ifs)
|
||||
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 -c LINE", with all special chars in LINE escaped.
|
||||
@@ -1442,6 +1554,7 @@ construct_command_argv_internal (line, restp, shell, ifs)
|
||||
new_argv = construct_command_argv_internal (new_line, (char **) NULL,
|
||||
(char *) 0, (char *) 0);
|
||||
}
|
||||
#endif /* MSDOS. */
|
||||
|
||||
return new_argv;
|
||||
}
|
||||
|
||||
412
main.c
412
main.c
@@ -304,14 +304,28 @@ static struct option long_option_aliases[] =
|
||||
|
||||
#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. */
|
||||
|
||||
char *program;
|
||||
|
||||
/* Our current directory before processing any -C options. */
|
||||
|
||||
char *directory_before_chdir;
|
||||
|
||||
/* Our current directory after processing all -C options. */
|
||||
|
||||
char *starting_directory;
|
||||
@@ -387,14 +401,9 @@ main (argc, argv, envp)
|
||||
extern RETSIGTYPE fatal_error_signal (), child_handler ();
|
||||
register struct file *f;
|
||||
register unsigned int i;
|
||||
register char *cmd_defs;
|
||||
register unsigned int cmd_defs_len, cmd_defs_idx;
|
||||
char **p;
|
||||
struct dep *goals = 0;
|
||||
register struct dep *lastgoal;
|
||||
struct dep *read_makefiles;
|
||||
PATH_VAR (current_directory);
|
||||
char *directory_before_chdir;
|
||||
|
||||
default_goal_file = 0;
|
||||
reading_filename = 0;
|
||||
@@ -464,6 +473,12 @@ main (argc, argv, envp)
|
||||
else
|
||||
{
|
||||
program = rindex (argv[0], '/');
|
||||
#ifdef __MSDOS__
|
||||
if (program == 0)
|
||||
program = rindex (argv[0], '\\');
|
||||
if (program == 0)
|
||||
program = rindex (argv[0], ':');
|
||||
#endif
|
||||
if (program == 0)
|
||||
program = argv[0];
|
||||
else
|
||||
@@ -490,8 +505,8 @@ main (argc, argv, envp)
|
||||
strlen (current_directory));
|
||||
|
||||
/* Read in variables from the environment. It is important that this be
|
||||
done before `MAKE' and `MAKEOVERRIDES' are figured out so their
|
||||
definitions will not be ones from the environment. */
|
||||
done before $(MAKE) is are figured out so its definitions will not be
|
||||
one from the environment. */
|
||||
|
||||
for (i = 0; envp[i] != 0; ++i)
|
||||
{
|
||||
@@ -531,76 +546,7 @@ main (argc, argv, envp)
|
||||
if (print_version_flag)
|
||||
die (0);
|
||||
|
||||
/* Search for command line arguments that define variables,
|
||||
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);
|
||||
|
||||
#ifndef __MSDOS__
|
||||
/* 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
|
||||
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'
|
||||
&& argv[0] != 0 && argv[0][0] != '/' && index (argv[0], '/') != 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", 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 (directories != 0)
|
||||
for (i = 0; directories->list[i] != 0; ++i)
|
||||
{
|
||||
@@ -1123,7 +1067,7 @@ main (argc, argv, envp)
|
||||
|
||||
/* 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])) +
|
||||
(sizeof (long_option_aliases) /
|
||||
sizeof (long_option_aliases[0]))];
|
||||
@@ -1141,6 +1085,11 @@ init_switches ()
|
||||
return;
|
||||
|
||||
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)
|
||||
{
|
||||
long_options[i].name = (switches[i].long_name == 0 ? "" :
|
||||
@@ -1195,15 +1144,6 @@ decode_switches (argc, argv, env)
|
||||
register struct stringlist *sl;
|
||||
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.
|
||||
First, get its vectors set up. */
|
||||
|
||||
@@ -1218,7 +1158,45 @@ decode_switches (argc, argv, env)
|
||||
while ((c = getopt_long (argc, argv,
|
||||
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.
|
||||
But continue to parse the other options so the user can
|
||||
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))
|
||||
{
|
||||
/* Print a nice usage message. */
|
||||
@@ -1437,7 +1402,7 @@ decode_env_switches (envar, len)
|
||||
unsigned int len;
|
||||
{
|
||||
char *varref = (char *) alloca (2 + len + 2);
|
||||
char *value, *args;
|
||||
char *value;
|
||||
int argc;
|
||||
char **argv;
|
||||
|
||||
@@ -1447,7 +1412,7 @@ decode_env_switches (envar, len)
|
||||
bcopy (envar, &varref[2], len);
|
||||
varref[2 + len] = ')';
|
||||
varref[2 + len + 1] = '\0';
|
||||
value = variable_expand (varref);
|
||||
value = allocated_variable_expand (varref);
|
||||
|
||||
/* Skip whitespace, and check for an empty value. */
|
||||
value = next_token (value);
|
||||
@@ -1455,18 +1420,6 @@ decode_env_switches (envar, len)
|
||||
if (len == 0)
|
||||
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. */
|
||||
argv = (char **) alloca ((1 + len + 1) * sizeof (char *));
|
||||
|
||||
@@ -1474,13 +1427,37 @@ decode_env_switches (envar, len)
|
||||
Prepend a spacer word. */
|
||||
argv[0] = 0;
|
||||
argc = 1;
|
||||
do
|
||||
while ((argv[argc] = find_next_token (&value, (unsigned int *) 0)) != 0)
|
||||
++argc;
|
||||
|
||||
if (argc == 2 && argv[1][0] != '-')
|
||||
{
|
||||
argv[argc++] = args;
|
||||
args = end_of_token (args);
|
||||
*args++ = '\0';
|
||||
} while (*args != '\0');
|
||||
argv[argc] = 0;
|
||||
/* There is just one word in the value, and it is not a switch.
|
||||
Either this is the single-word form and we should prepend a dash
|
||||
before calling decode_switches, or this is the multi-word form and
|
||||
there is no dash because it is a variable definition. */
|
||||
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. */
|
||||
decode_switches (argc, argv, 1);
|
||||
@@ -1496,7 +1473,10 @@ define_makeflags (all, makefile)
|
||||
{
|
||||
register const struct command_switch *cs;
|
||||
char *flagstring;
|
||||
register char *p;
|
||||
unsigned int words;
|
||||
struct variable *v;
|
||||
struct command_variable *cv;
|
||||
|
||||
/* We will construct a linked list of `struct flag's describing
|
||||
all the flags which need to go in MAKEFLAGS. Then, once we
|
||||
@@ -1609,70 +1589,119 @@ define_makeflags (all, makefile)
|
||||
|
||||
#undef ADD_FLAG
|
||||
|
||||
if (flags == 0)
|
||||
/* No flags. Use a string of two nulls so [1] works below. */
|
||||
flagstring = "\0";
|
||||
else
|
||||
if (all && command_variables != 0)
|
||||
{
|
||||
/* Construct the value in FLAGSTRING.
|
||||
We allocate enough space for a preceding dash and trailing null. */
|
||||
register char *p;
|
||||
flagstring = (char *) alloca (1 + flagslen + 1);
|
||||
p = flagstring;
|
||||
*p++ = '-';
|
||||
do
|
||||
/* Now figure out how much space will be taken up
|
||||
by the command-line variable definitions. */
|
||||
flagslen += 4; /* For the possible " -- ". */
|
||||
for (cv = command_variables; cv != 0; cv = cv->next)
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
/* 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';
|
||||
v = cv->variable;
|
||||
flagslen += strlen (v->name);
|
||||
if (! v->recursive)
|
||||
++flagslen;
|
||||
++flagslen;
|
||||
flagslen += strlen (v->value);
|
||||
}
|
||||
}
|
||||
|
||||
/* 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,
|
||||
/* On Sun, the value of MFLAGS starts with a `-' but
|
||||
the value of MAKEFLAGS lacks the `-'.
|
||||
Be compatible with this unless FLAGSTRING starts
|
||||
with a long option `--foo', since removing the
|
||||
first dash would result in the bogus `-foo'. */
|
||||
flagstring[1] == '-' ? flagstring : &flagstring[1],
|
||||
/* If there is just a single word of switches,
|
||||
omit the leading dash unless it is a single
|
||||
long option with two leading dashes. */
|
||||
&flagstring[(words == 1 && command_variables == 0
|
||||
&& flagstring[1] != '-')
|
||||
? 1 : 0],
|
||||
/* This used to use o_env, but that lost when a
|
||||
makefile defined MAKEFLAGS. Makefiles set
|
||||
MAKEFLAGS to add switches, but we still want
|
||||
@@ -1755,6 +1784,13 @@ die (status)
|
||||
|
||||
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)
|
||||
print_version ();
|
||||
|
||||
|
||||
322
make-stds.texi
322
make-stds.texi
@@ -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
|
||||
@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
|
||||
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
|
||||
@@ -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
|
||||
the form:
|
||||
|
||||
@example
|
||||
@smallexample
|
||||
foo.1 : foo.man sedscript
|
||||
sed -e sedscript foo.man > foo.1
|
||||
@end example
|
||||
@end smallexample
|
||||
|
||||
@noindent
|
||||
will fail when the current directory is not the source directory,
|
||||
because @file{foo.man} and @file{sedscript} are not in the current
|
||||
directory.
|
||||
|
||||
Relying on @samp{VPATH} to find the source file will work in the case
|
||||
where there is a single dependency file, since the @file{make} automatic
|
||||
variable @samp{$<} will represent the source file wherever it is. A
|
||||
makefile target like
|
||||
When using GNU @code{make}, relying on @samp{VPATH} to find the source
|
||||
file will work in the case where there is a single dependency file,
|
||||
since the @file{make} automatic variable @samp{$<} will represent the
|
||||
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
|
||||
$(CC) $(CFLAGS) -I. -I$(srcdir) -c bar.c -o foo.o
|
||||
@end example
|
||||
$(CC) -I. -I$(srcdir) $(CFLAGS) -c bar.c -o foo.o
|
||||
@end smallexample
|
||||
|
||||
@noindent
|
||||
should instead be written as
|
||||
|
||||
@example
|
||||
@smallexample
|
||||
foo.o : bar.c
|
||||
$(CC) $(CFLAGS) $< -o $@@
|
||||
@end example
|
||||
$(CC) -I. -I$(srcdir) $(CFLAGS) -c $< -o $@@
|
||||
@end smallexample
|
||||
|
||||
@noindent
|
||||
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
|
||||
@file{foo.1} is best written as:
|
||||
|
||||
@example
|
||||
@smallexample
|
||||
foo.1 : foo.man sedscript
|
||||
sed -s $(srcdir)/sedscript $(srcdir)/foo.man > foo.1
|
||||
@end example
|
||||
sed -e $(srcdir)/sedscript $(srcdir)/foo.man > $@@
|
||||
@end smallexample
|
||||
|
||||
@node Utilities in Makefiles
|
||||
@section Utilities in Makefiles
|
||||
@@ -107,12 +122,21 @@ user can substitute alternatives. Here are some of the programs we
|
||||
mean:
|
||||
|
||||
@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
|
||||
|
||||
When you use @code{ranlib}, you should test whether it exists, and run
|
||||
it only if it exists, so that the distribution will work on systems that
|
||||
don't have @code{ranlib}.
|
||||
Use the following @code{make} variables:
|
||||
|
||||
@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
|
||||
that don't have symbolic links.
|
||||
@@ -129,29 +153,62 @@ All GNU programs should have the following targets in their Makefiles:
|
||||
@table @samp
|
||||
@item all
|
||||
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
|
||||
only when explicitly asked for.
|
||||
|
||||
@item install
|
||||
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
|
||||
simple test to verify that a program is properly installed then run that
|
||||
test.
|
||||
simple test to verify that a program is properly installed, this target
|
||||
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
|
||||
@code{make} will ignore any errors. This is in case there are systems
|
||||
that don't have the Unix man page documentation system installed.
|
||||
|
||||
In the future, when we have a standard way of installing info files,
|
||||
@samp{install} targets will be the proper place to do so.
|
||||
The way to install Info files is to copy them into @file{$(infodir)}
|
||||
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
|
||||
Delete all the installed files that the @samp{install} target would
|
||||
create (but not the noninstalled files such as @samp{make all} would
|
||||
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
|
||||
|
||||
Delete all files from the current directory that are normally created by
|
||||
building the program. Don't delete the files that record the
|
||||
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
|
||||
Delete everything from the current directory that can be reconstructed
|
||||
with this Makefile. This typically includes everything deleted by
|
||||
distclean, plus more: C source files produced by Bison, tags tables,
|
||||
info files, and so on.
|
||||
@code{distclean}, plus more: C source files produced by Bison, tags tables,
|
||||
Info files, and so on.
|
||||
|
||||
One exception, however: @samp{make realclean} should not delete
|
||||
@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.
|
||||
|
||||
@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:
|
||||
|
||||
@example
|
||||
info: foo.info
|
||||
@smallexample
|
||||
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
|
||||
@end example
|
||||
@end smallexample
|
||||
|
||||
@noindent
|
||||
You must define the variable @code{MAKEINFO} in the Makefile.
|
||||
It should run the Makeinfo program, which is part of the Texinfo2 distribution.
|
||||
You must define the variable @code{MAKEINFO} in the Makefile. It should
|
||||
run the @code{makeinfo} program, which is part of the Texinfo
|
||||
distribution.
|
||||
|
||||
@item dvi
|
||||
Generate DVI files for all TeXinfo documentation.
|
||||
For example:
|
||||
|
||||
@example
|
||||
@smallexample
|
||||
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
|
||||
@end example
|
||||
@end smallexample
|
||||
|
||||
@noindent
|
||||
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
|
||||
Make to provide the command.
|
||||
|
||||
@@ -243,6 +301,34 @@ the self-tests so that they work when the program is built but not
|
||||
installed.
|
||||
@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
|
||||
@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
|
||||
compilation commands or by defining an implicit rule, like this:
|
||||
|
||||
@example
|
||||
@smallexample
|
||||
CFLAGS = -g
|
||||
ALL_CFLAGS = $(CFLAGS) -I.
|
||||
ALL_CFLAGS = -I. $(CFLAGS)
|
||||
.c.o:
|
||||
$(CC) -c $(ALL_CFLAGS) $(CPPFLAGS) $<
|
||||
@end example
|
||||
$(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) $<
|
||||
@end smallexample
|
||||
|
||||
Do include the @samp{-g} option in @code{CFLAGS}, because that is not
|
||||
@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}
|
||||
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
|
||||
basic command for installing a file into the system.
|
||||
|
||||
Every Makefile should also define variables @code{INSTALL_PROGRAM} and
|
||||
@code{INSTALL_DATA}. (The default for each of these should be
|
||||
Every Makefile should also define the variables @code{INSTALL_PROGRAM}
|
||||
and @code{INSTALL_DATA}. (The default for each of these should be
|
||||
@code{$(INSTALL)}.) Then it should use those variables as the commands
|
||||
for actual installation, for executables and nonexecutables
|
||||
respectively. Use these variables as follows:
|
||||
@@ -311,7 +401,11 @@ installed.
|
||||
|
||||
Installation directories should always be named by variables, so it is
|
||||
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
|
||||
@item prefix
|
||||
@@ -320,39 +414,107 @@ below. The default value of @code{prefix} should be @file{/usr/local}
|
||||
(at least for now).
|
||||
|
||||
@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
|
||||
be @code{$(prefix)}.
|
||||
|
||||
Generally, @code{$(exec_prefix)} is used for directories that contain
|
||||
machine-specific files (such as executables and subroutine libraries),
|
||||
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
|
||||
The directory for installing executable programs that users can run.
|
||||
This should normally be @file{/usr/local/bin}, but write it as
|
||||
@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
|
||||
The directory for installing executable files to be run by the program
|
||||
rather than by users. Object files and libraries of object code should
|
||||
also go in this directory. The idea is that this directory is used for
|
||||
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
|
||||
The directory for object files and libraries of object code. Do not
|
||||
install executables here, they probably belong in @file{$(libexecdir)}
|
||||
instead. The value of @code{libdir} should normally be
|
||||
@file{/usr/local/lib}, but write it as @file{$(exec_prefix)/lib}.
|
||||
|
||||
@item datadir
|
||||
The directory for installing read-only data files which the programs
|
||||
refer to while they run. This directory is used for files which are
|
||||
independent of the type of machine being used. This should normally be
|
||||
@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 infodir
|
||||
The directory for installing the Info files for this package. By
|
||||
default, it should be @file{/usr/local/info}, but it should be written
|
||||
as @file{$(prefix)/info}.
|
||||
|
||||
@item includedir
|
||||
@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
|
||||
package.
|
||||
|
||||
The way to tell whether @file{foo.h} came from the Foo package is to put
|
||||
a magic string in the file---part of a comment---and grep for that
|
||||
string.
|
||||
To tell whether @file{foo.h} came from the Foo package, put a magic
|
||||
string in the file---part of a comment---and grep for that string.
|
||||
@end table
|
||||
|
||||
Unix-style man pages are installed in one of the following:
|
||||
|
||||
@table @samp
|
||||
@item mandir
|
||||
The directory for installing the man pages (if any) for this package.
|
||||
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
|
||||
The directory for installing section 1 man pages.
|
||||
@@ -408,13 +575,20 @@ application only.}
|
||||
|
||||
@item manext
|
||||
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
|
||||
The directory for installing the info files for this package. By
|
||||
default, it should be @file{/usr/local/info}, but it should be written
|
||||
as @file{$(prefix)/info}.
|
||||
@item man1ext
|
||||
The file name extension for installed section 1 man pages.
|
||||
@item man2ext
|
||||
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
|
||||
The directory for the sources being compiled. The value of this
|
||||
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:
|
||||
|
||||
@example
|
||||
@smallexample
|
||||
@c I have changed some of the comments here slightly to fix an overfull
|
||||
@c hbox, so the make manual can format correctly. --roland
|
||||
# Common prefix for installation directories.
|
||||
@@ -432,10 +606,10 @@ exec_prefix = $(prefix)
|
||||
# Where to put the executable for the command `gcc'.
|
||||
bindir = $(exec_prefix)/bin
|
||||
# Where to put the directories used by the compiler.
|
||||
libdir = $(exec_prefix)/lib
|
||||
libexecdir = $(exec_prefix)/libexec
|
||||
# Where to put the Info files.
|
||||
infodir = $(prefix)/info
|
||||
@end example
|
||||
@end smallexample
|
||||
|
||||
If your program installs a large number of files into one of the
|
||||
standard user-specified directories, it might be useful to group them
|
||||
|
||||
25
make.h
25
make.h
@@ -59,13 +59,15 @@ extern int errno;
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#ifdef _POSIX_VERSION
|
||||
/* Ultrix's unistd.h always defines _POSIX_VERSION, but you only get
|
||||
POSIX.1 behavior with `cc -YPOSIX', which predefines POSIX itself! */
|
||||
#if defined (_POSIX_VERSION) && !defined (ultrix)
|
||||
#define POSIX
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* 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 (sequent) && defined (i386)))
|
||||
#undef POSIX
|
||||
@@ -250,6 +252,12 @@ extern char *alloca ();
|
||||
#define ENUM_BITFIELD(bits)
|
||||
#endif
|
||||
|
||||
#ifdef __MSDOS__
|
||||
#define PATH_SEPARATOR_CHAR ';'
|
||||
#else
|
||||
#define PATH_SEPARATOR_CHAR ':'
|
||||
#endif
|
||||
|
||||
extern void die ();
|
||||
extern void message (), fatal (), error ();
|
||||
extern void makefile_error (), makefile_fatal ();
|
||||
@@ -297,17 +305,12 @@ extern void user_access (), make_access (), child_access ();
|
||||
#include <vfork.h>
|
||||
#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 int unlink (), stat (), fstat ();
|
||||
extern int pipe (), close (), read (), write (), open ();
|
||||
extern long int lseek ();
|
||||
|
||||
#endif /* Not GNU C library or POSIX. */
|
||||
|
||||
78
make.texinfo
78
make.texinfo
@@ -8,10 +8,11 @@
|
||||
@c FSF publishers: format makebook.texi instead of using this file directly.
|
||||
|
||||
@set RCSID $Id$
|
||||
@set EDITION 0.45
|
||||
@set VERSION 3.71 Beta
|
||||
@set UPDATED 20 April 1994
|
||||
@set UPDATE-MONTH April 1994
|
||||
@set EDITION 0.46
|
||||
@set VERSION 3.72 Beta
|
||||
@set UPDATED 5 July 1994
|
||||
@set UPDATE-MONTH July 1994
|
||||
@set ISBN 1-882114-50-7
|
||||
|
||||
@c finalout
|
||||
|
||||
@@ -71,7 +72,7 @@ Published by the Free Software Foundation @*
|
||||
675 Massachusetts Avenue, @*
|
||||
Cambridge, MA 02139 USA @*
|
||||
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
|
||||
this manual provided the copyright notice and this permission notice
|
||||
@@ -1247,13 +1248,12 @@ include one in the other, and add more targets or variable definitions.
|
||||
However, if the two makefiles give different commands for the same
|
||||
target, @code{make} will not let you just do this. But there is another way.
|
||||
|
||||
@cindex @code{.DEFAULT}, used to override
|
||||
@cindex match-anything rule, used to override
|
||||
In the containing makefile (the one that wants to include the other),
|
||||
you can use the @code{.DEFAULT} special target to say that to remake
|
||||
any target that cannot be made from the information in the containing
|
||||
makefile, @code{make} should look in another makefile.
|
||||
@xref{Last Resort, , Defining Last-Resort Default Rules},
|
||||
for more information on @code{.DEFAULT}.
|
||||
you can use a match-anything pattern rule to say that to remake any
|
||||
target that cannot be made from the information in the containing
|
||||
makefile, @code{make} should look in another makefile.
|
||||
@xref{Pattern Rules}, for more information on pattern rules.
|
||||
|
||||
For example, if you have a makefile called @file{Makefile} that says how
|
||||
to make the target @samp{foo} (and other targets), you can write a
|
||||
@@ -1263,18 +1263,27 @@ makefile called @file{GNUmakefile} that contains:
|
||||
foo:
|
||||
frobnicate > foo
|
||||
|
||||
.DEFAULT:
|
||||
%: force
|
||||
@@$(MAKE) -f Makefile $@@
|
||||
force: ;
|
||||
@end example
|
||||
|
||||
If you say @samp{make foo}, @code{make} will find @file{GNUmakefile},
|
||||
read it, and see that to make @file{foo}, it needs to run the command
|
||||
@samp{frobnicate > foo}. If you say @samp{make bar}, @code{make} will
|
||||
find no way to make @file{bar} in @file{GNUmakefile}, so it will use the
|
||||
commands from @code{.DEFAULT}: @samp{make -f Makefile bar}. If
|
||||
commands from the pattern rule: @samp{make -f Makefile bar}. If
|
||||
@file{Makefile} provides a rule for updating @file{bar}, @code{make}
|
||||
will apply the rule. And likewise for any other target that
|
||||
@file{GNUmakefile} does not say how to make.@refill
|
||||
@file{GNUmakefile} does not say how to make.
|
||||
|
||||
The way this works is that the pattern rule has a pattern of just
|
||||
@samp{%}, so it matches any target whatever. The rule specifies a
|
||||
dependency @file{force}, to guarantee that the commands will be run even
|
||||
if the target file already exists. We give @file{force} target empty
|
||||
commands to prevent @code{make} from searching for an implicit rule to
|
||||
build it---otherwise it would apply the same match-anything rule to
|
||||
@file{force} itself and create a dependency loop!
|
||||
|
||||
@node Rules, Commands, Makefiles, Top
|
||||
@chapter Writing Rules
|
||||
@@ -1666,9 +1675,9 @@ names of source files in the dependencies as if they all existed in the
|
||||
current directory. @xref{Commands/Search, ,Writing Shell Commands with
|
||||
Directory Search}.
|
||||
|
||||
In the @code{VPATH} variable, directory names are separated by colons.
|
||||
The order in which directories are listed is the order followed by
|
||||
@code{make} in its search.
|
||||
In the @code{VPATH} variable, directory names are separated by colons or
|
||||
blanks. The order in which directories are listed is the order followed
|
||||
by @code{make} in its search.
|
||||
|
||||
For example,
|
||||
|
||||
@@ -1714,9 +1723,9 @@ There are three forms of the @code{vpath} directive:
|
||||
Specify the search path @var{directories} for file names that match
|
||||
@var{pattern}.
|
||||
|
||||
The search path, @var{directories}, is a colon-separated list of
|
||||
directories to be searched, just like the search path used in the
|
||||
@code{VPATH} variable.
|
||||
The search path, @var{directories}, is a list of directories to be
|
||||
searched, separated by colons or blanks, just like the search path used
|
||||
in the @code{VPATH} variable.
|
||||
|
||||
@item vpath @var{pattern}
|
||||
Clear out the search path associated with @var{pattern}.
|
||||
@@ -2573,7 +2582,8 @@ called @file{@var{name}.d} from a C source file called @file{@var{name}.c}:
|
||||
@example
|
||||
@group
|
||||
%.d: %.c
|
||||
$(SHELL) -ec '$(CC) -M $(CPPFLAGS) $< | sed '\''s/$*.o/& $@@/g'\'' > $@@'
|
||||
$(SHELL) -ec '$(CC) -M $(CPPFLAGS) $< \
|
||||
| sed '\''s/$*.o/& $@@/g'\'' > $@@'
|
||||
@end group
|
||||
@end example
|
||||
|
||||
@@ -5573,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
|
||||
targets that start with a period). Therefore, makefiles are usually
|
||||
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}.
|
||||
Use the name of the goal as an argument. If you specify several goals,
|
||||
@@ -7612,6 +7624,7 @@ main use is as subroutine libraries for linking.
|
||||
@menu
|
||||
* Archive Members:: Archive members as 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
|
||||
for updating archives.
|
||||
@end menu
|
||||
@@ -7668,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
|
||||
@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
|
||||
|
||||
Recall that a target that looks like @file{@var{a}(@var{m})} stands for the
|
||||
@@ -7758,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
|
||||
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
|
||||
@cindex suffix rule, for archive
|
||||
@cindex archive, suffix rule for
|
||||
|
||||
38
misc.c
38
misc.c
@@ -454,19 +454,27 @@ dep_name (dep)
|
||||
#ifdef GETLOADAVG_PRIVILEGED
|
||||
|
||||
#ifdef POSIX
|
||||
|
||||
/* Hopefully if a system says it's POSIX.1 and has the setuid and setgid
|
||||
functions, they work as POSIX.1 says. Some systems (Alpha OSF/1 1.2,
|
||||
for example) which claim to be POSIX.1 also have the BSD setreuid and
|
||||
setregid functions, but they don't work as in BSD and only the POSIX.1
|
||||
way works. */
|
||||
|
||||
#if defined (HAVE_SETREUID) && defined (HAVE_SETUID)
|
||||
#undef HAVE_SETREUID
|
||||
#endif
|
||||
#if defined (HAVE_SETREGID) && defined (HAVE_SETGID)
|
||||
#undef HAVE_SETREGID
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#else /* Not POSIX. */
|
||||
|
||||
/* Some POSIX.1 systems have the seteuid and setegid functions. In a
|
||||
POSIX-like system, they are the best thing to use. However, some
|
||||
non-POSIX systems have them too but they do not work in the POSIX style
|
||||
and we must use setreuid and setregid instead. */
|
||||
|
||||
#undef HAVE_SETEUID
|
||||
#undef HAVE_SETEGID
|
||||
|
||||
#endif /* POSIX. */
|
||||
|
||||
#ifndef HAVE_UNISTD_H
|
||||
extern int getuid (), getgid (), geteuid (), getegid ();
|
||||
@@ -708,3 +716,23 @@ get_path_max ()
|
||||
return value;
|
||||
}
|
||||
#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;
|
||||
}
|
||||
|
||||
114
read.c
114
read.c
@@ -240,6 +240,7 @@ read_makefile (filename, flags)
|
||||
char *p2;
|
||||
int ignoring = 0, in_ignored_define = 0;
|
||||
int no_targets = 0; /* Set when reading a rule without targets. */
|
||||
char *passed_filename = filename;
|
||||
|
||||
struct nameseq *filenames = 0;
|
||||
struct dep *deps;
|
||||
@@ -288,7 +289,6 @@ read_makefile (filename, flags)
|
||||
if (!(flags & RM_NO_TILDE) && filename[0] == '~')
|
||||
{
|
||||
char *expanded = tilde_expand (filename);
|
||||
/* This is a possible memory leak, but I don't care. */
|
||||
if (expanded != 0)
|
||||
filename = expanded;
|
||||
}
|
||||
@@ -330,6 +330,8 @@ read_makefile (filename, flags)
|
||||
if (flags & RM_DONTCARE)
|
||||
deps->file->dontcare = 1;
|
||||
}
|
||||
if (filename != passed_filename)
|
||||
free (filename);
|
||||
filename = deps->file->name;
|
||||
deps->changed = flags;
|
||||
deps = 0;
|
||||
@@ -360,6 +362,47 @@ read_makefile (filename, flags)
|
||||
lineno += nlines;
|
||||
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)
|
||||
{
|
||||
collapsed_length = lb.size;
|
||||
@@ -372,17 +415,20 @@ read_makefile (filename, flags)
|
||||
collapse_continuations (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. */
|
||||
#define word1eq(s, l) (!strncmp (s, 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
|
||||
&& (word1eq ("ifdef", 5) || word1eq ("ifndef", 6)
|
||||
|| word1eq ("ifeq", 4) || word1eq ("ifneq", 5)
|
||||
@@ -434,7 +480,7 @@ read_makefile (filename, flags)
|
||||
in_ignored_define = 1;
|
||||
else
|
||||
{
|
||||
p2 = end_of_token (p2);
|
||||
p2 = next_token (p2 + 6);
|
||||
/* Let the variable name be the whole rest of the line,
|
||||
with trailing blanks stripped (comments have already been
|
||||
removed), so it could be a complex variable/function
|
||||
@@ -458,40 +504,7 @@ read_makefile (filename, flags)
|
||||
/* Ignore the line. We continue here so conditionals
|
||||
can appear in the middle of a rule. */
|
||||
continue;
|
||||
else if (lb.buffer[0] == '\t')
|
||||
{
|
||||
/* 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))
|
||||
else if (word1eq ("export", 6))
|
||||
{
|
||||
struct variable *v;
|
||||
p2 = next_token (p + 6);
|
||||
@@ -811,12 +824,13 @@ do_define (name, namelen, origin, lineno, infile, filename)
|
||||
{
|
||||
lineno += nlines;
|
||||
nlines = readline (&lb, infile, filename, lineno);
|
||||
p = next_token (lb.buffer);
|
||||
|
||||
collapse_continuations (lb.buffer);
|
||||
|
||||
p = next_token (lb.buffer);
|
||||
if ((p[5] == '\0' || isblank (p[5])) && !strncmp (p, "endef", 5))
|
||||
{
|
||||
p += 5;
|
||||
collapse_continuations (p);
|
||||
remove_comments (p);
|
||||
if (*next_token (p) != '\0')
|
||||
makefile_error (filename, lineno,
|
||||
@@ -833,7 +847,7 @@ do_define (name, namelen, origin, lineno, infile, filename)
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int len = strlen (p);
|
||||
unsigned int len = strlen (lb.buffer);
|
||||
|
||||
/* Increase the buffer size if necessary. */
|
||||
if (idx + len + 1 > length)
|
||||
@@ -842,7 +856,7 @@ do_define (name, namelen, origin, lineno, infile, filename)
|
||||
definition = (char *) xrealloc (definition, length + 1);
|
||||
}
|
||||
|
||||
bcopy (p, &definition[idx], len);
|
||||
bcopy (lb.buffer, &definition[idx], len);
|
||||
idx += len;
|
||||
/* Separate lines with a newline. */
|
||||
definition[idx++] = '\n';
|
||||
@@ -1787,7 +1801,7 @@ construct_include_path (arg_dirs)
|
||||
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)
|
||||
{
|
||||
@@ -1804,7 +1818,7 @@ construct_include_path (arg_dirs)
|
||||
/* Now add at the end the standard default dirs. */
|
||||
|
||||
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))
|
||||
dirs[idx++] = default_include_directories[i];
|
||||
|
||||
|
||||
32
remake.c
32
remake.c
@@ -179,6 +179,9 @@ update_goal_chain (goals, makefiles)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Reset FILE since it is null at the end of the loop. */
|
||||
file = g->file;
|
||||
|
||||
if (stop || !any_not_updated)
|
||||
{
|
||||
/* If we have found nothing whatever to do for the goal,
|
||||
@@ -465,7 +468,7 @@ update_file_1 (file, depth)
|
||||
|
||||
if (running)
|
||||
{
|
||||
file->command_state = cs_deps_running;
|
||||
set_command_state (file, cs_deps_running);
|
||||
--depth;
|
||||
DEBUGPR ("The dependencies of `%s' are being made.\n");
|
||||
return 0;
|
||||
@@ -475,9 +478,8 @@ update_file_1 (file, depth)
|
||||
|
||||
if (dep_status != 0)
|
||||
{
|
||||
file->command_state = cs_finished;
|
||||
file->update_status = dep_status;
|
||||
file->updated = 1;
|
||||
notice_finished_file (file);
|
||||
|
||||
depth--;
|
||||
|
||||
@@ -490,7 +492,7 @@ update_file_1 (file, depth)
|
||||
return dep_status;
|
||||
}
|
||||
|
||||
file->command_state = cs_not_started;
|
||||
set_command_state (file, cs_not_started);
|
||||
|
||||
/* Now record which dependencies are more
|
||||
recent than this file, so we can define $?. */
|
||||
@@ -546,9 +548,8 @@ update_file_1 (file, depth)
|
||||
if (!must_make)
|
||||
{
|
||||
DEBUGPR ("No need to remake target `%s'.\n");
|
||||
file->command_state = cs_finished;
|
||||
file->update_status = 0;
|
||||
file->updated = 1;
|
||||
notice_finished_file (file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -593,6 +594,7 @@ notice_finished_file (file)
|
||||
register struct file *file;
|
||||
{
|
||||
struct dep *d;
|
||||
int ran = file->command_state == cs_running;
|
||||
|
||||
file->command_state = cs_finished;
|
||||
file->updated = 1;
|
||||
@@ -626,7 +628,7 @@ notice_finished_file (file)
|
||||
}
|
||||
}
|
||||
|
||||
if (!file->phony)
|
||||
if (ran && !file->phony)
|
||||
{
|
||||
struct file *f;
|
||||
|
||||
@@ -653,7 +655,7 @@ notice_finished_file (file)
|
||||
d->file->updated = 1;
|
||||
d->file->update_status = file->update_status;
|
||||
|
||||
if (!d->file->phony)
|
||||
if (ran && !d->file->phony)
|
||||
/* Fetch the new modification time.
|
||||
We do this instead of just invalidating the cached time
|
||||
so that a vpath_search can happen. Otherwise, it would
|
||||
@@ -735,7 +737,7 @@ check_dep (file, depth, this_mtime, must_make_ptr)
|
||||
/* Record that some of FILE's dependencies are still being made.
|
||||
This tells the upper levels to wait on processing it until
|
||||
the commands are finished. */
|
||||
file->command_state = cs_deps_running;
|
||||
set_command_state (file, cs_deps_running);
|
||||
|
||||
lastd = d;
|
||||
d = d->next;
|
||||
@@ -774,8 +776,16 @@ touch_file (file)
|
||||
{
|
||||
struct stat statbuf;
|
||||
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: ");
|
||||
/* Rewrite character 0 same as it already is. */
|
||||
if (read (fd, &buf, 1) < 0)
|
||||
@@ -968,7 +978,7 @@ name_mtime (name)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if (stat (name, &st) < 0)
|
||||
if (safe_stat (name, &st) < 0)
|
||||
return (time_t) -1;
|
||||
|
||||
return (time_t) st.st_mtime;
|
||||
|
||||
17
vpath.c
17
vpath.c
@@ -1,5 +1,5 @@
|
||||
/* 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.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify
|
||||
@@ -177,7 +177,7 @@ construct_vpath_list (pattern, dirpath)
|
||||
maxelem = 2;
|
||||
p = dirpath;
|
||||
while (*p != '\0')
|
||||
if (*p++ == ':' || isblank (*p))
|
||||
if (*p++ == PATH_SEPARATOR_CHAR || isblank (*p))
|
||||
++maxelem;
|
||||
|
||||
vpath = (char **) xmalloc (maxelem * sizeof (char *));
|
||||
@@ -185,7 +185,7 @@ construct_vpath_list (pattern, dirpath)
|
||||
|
||||
/* Skip over any initial colons and blanks. */
|
||||
p = dirpath;
|
||||
while (*p == ':' || isblank (*p))
|
||||
while (*p == PATH_SEPARATOR_CHAR || isblank (*p))
|
||||
++p;
|
||||
|
||||
elem = 0;
|
||||
@@ -196,7 +196,7 @@ construct_vpath_list (pattern, dirpath)
|
||||
|
||||
/* Find the end of this entry. */
|
||||
v = p;
|
||||
while (*p != '\0' && *p != ':' && !isblank (*p))
|
||||
while (*p != '\0' && *p != PATH_SEPARATOR_CHAR && !isblank (*p))
|
||||
++p;
|
||||
|
||||
len = p - v;
|
||||
@@ -225,7 +225,7 @@ construct_vpath_list (pattern, dirpath)
|
||||
}
|
||||
|
||||
/* Skip over colons and blanks between entries. */
|
||||
while (*p == ':' || isblank (*p))
|
||||
while (*p == PATH_SEPARATOR_CHAR || isblank (*p))
|
||||
++p;
|
||||
}
|
||||
|
||||
@@ -419,7 +419,7 @@ selective_vpath_search (path, file, mtime_ptr)
|
||||
*n = '/';
|
||||
|
||||
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.
|
||||
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)
|
||||
printf ("%s%c", v->searchpath[i],
|
||||
v->searchpath[i + 1] == 0 ? '\n' : ':');
|
||||
v->searchpath[i + 1] == 0 ? '\n' : PATH_SEPARATOR_CHAR);
|
||||
}
|
||||
|
||||
if (vpaths == 0)
|
||||
@@ -479,6 +479,7 @@ print_vpath_data_base ()
|
||||
fputs ("\n# General (`VPATH' variable) search path:\n# ", stdout);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user