Import bmake-20130330

This commit is contained in:
Simon J. Gerraty 2013-04-01 21:12:55 +00:00
parent 70bd6b310d
commit 3784f43e18
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/NetBSD/bmake/dist/; revision=248989
svn path=/vendor/NetBSD/bmake/20130330/; revision=248990; tag=vendor/NetBSD/bmake/20130330
29 changed files with 769 additions and 328 deletions

View File

@ -1,3 +1,47 @@
2013-03-30 Simon J. Gerraty <sjg@bad.crufty.net>
* Makefile (MAKE_VERSION): 20130330
Merge with NetBSD make, pick up
o meta.c: refine the handling of .OODATE in commands.
Rather than suppress command comparison for the entire script
as though .NOMETA_CMP had been used, only suppress it for the
one command line.
This allows something like ${.OODATE:M.NOMETA_CMP} to be used to
suppress comparison of a command without otherwise affecting it.
o make.1: document that
2013-03-22 Simon J. Gerraty <sjg@bad.crufty.net>
* Makefile (MAKE_VERSION): 20130321
yes, not quite right but its a cooler number.
Merge with NetBSD make, pick up
o parse.c: fix ParseGmakeExport to be portable
and add a unit-test.
* meta.c: call meta_init() before makefiles are read and if built
with filemon support set .MAKE.PATH_FILEMON to _PATH_FILEMON
this let's makefiles test for support.
Call meta_mode_init() to process .MAKE.MODE.
2013-03-13 Simon J. Gerraty <sjg@bad.crufty.net>
* Makefile (MAKE_VERSION): 20130305
Merge with NetBSD make, pick up
o run .STALE: target when a dependency from .depend is missing.
o job.c: add Job_RunTarget() for the above and .BEGIN
2013-03-03 Simon J. Gerraty <sjg@bad.crufty.net>
* Makefile (MAKE_VERSION): 20130303
Merge with NetBSD make, pick up
o main.c: set .MAKE.OS to utsname.sysname
o job.c: more checks for read and poll errors
o var.c: lose VarChangeCase() saves 4% time
2013-03-02 Simon J. Gerraty <sjg@bad.crufty.net>
* boot-strap: remove MAKEOBJDIRPREFIX from environment since we
want to use MAKEOBJDIR
2013-01-27 Simon J. Gerraty <sjg@bad.crufty.net> 2013-01-27 Simon J. Gerraty <sjg@bad.crufty.net>
* Merge with NetBSD make, pick up * Merge with NetBSD make, pick up

1
FILES
View File

@ -102,6 +102,7 @@ unit-tests/dotwait
unit-tests/error unit-tests/error
unit-tests/export unit-tests/export
unit-tests/export-all unit-tests/export-all
unit-tests/export-env
unit-tests/forloop unit-tests/forloop
unit-tests/forsubst unit-tests/forsubst
unit-tests/hash unit-tests/hash

View File

@ -1,7 +1,7 @@
# $Id: Makefile,v 1.5 2013/01/28 19:31:58 sjg Exp $ # $Id: Makefile,v 1.10 2013/03/31 05:57:19 sjg Exp $
# Base version on src date # Base version on src date
MAKE_VERSION= 20130123 MAKE_VERSION= 20130330
PROG= bmake PROG= bmake
@ -187,14 +187,14 @@ MANDIR= ${SHAREDIR}/man
.if !exists(.depend) .if !exists(.depend)
${OBJS}: config.h ${OBJS}: config.h
.endif .endif
.if ${MK_AUTOCONF_MK} == "yes"
.include <autoconf.mk>
.endif
# make sure that MAKE_VERSION gets updated. # make sure that MAKE_VERSION gets updated.
main.o: ${SRCS} ${MAKEFILE} main.o: ${SRCS} ${MAKEFILE}
# start-delete2 for bsd.after-import.mk # start-delete2 for bsd.after-import.mk
.if ${MK_AUTOCONF_MK} == "yes"
.include <autoconf.mk>
.endif
SHARE_MK?=${SHAREDIR}/mk SHARE_MK?=${SHAREDIR}/mk
MKSRC=${srcdir}/mk MKSRC=${srcdir}/mk
INSTALL?=${srcdir}/install-sh INSTALL?=${srcdir}/install-sh

29
bmake.1
View File

@ -1,4 +1,4 @@
.\" $NetBSD: make.1,v 1.210 2013/01/27 18:52:01 sjg Exp $ .\" $NetBSD: make.1,v 1.213 2013/03/31 05:49:51 sjg Exp $
.\" .\"
.\" Copyright (c) 1990, 1993 .\" Copyright (c) 1990, 1993
.\" The Regents of the University of California. All rights reserved. .\" The Regents of the University of California. All rights reserved.
@ -29,7 +29,7 @@
.\" .\"
.\" from: @(#)make.1 8.4 (Berkeley) 3/19/94 .\" from: @(#)make.1 8.4 (Berkeley) 3/19/94
.\" .\"
.Dd January 23, 2013 .Dd March 30, 2013
.Dt MAKE 1 .Dt MAKE 1
.Os .Os
.Sh NAME .Sh NAME
@ -874,6 +874,13 @@ by appending their names to
is re-exported whenever is re-exported whenever
.Ql Va .MAKEOVERRIDES .Ql Va .MAKEOVERRIDES
is modified. is modified.
.It Va .MAKE.PATH_FILEMON
If
.Nm
was built with
.Xr filemon 4
support, this is set to the path of the device node.
This allows makefiles to test for this support.
.It Va .MAKE.PID .It Va .MAKE.PID
The process-id of The process-id of
.Nm . .Nm .
@ -1757,6 +1764,20 @@ targets.
Ignore differences in commands when deciding if target is out of date. Ignore differences in commands when deciding if target is out of date.
This is useful if the command contains a value which always changes. This is useful if the command contains a value which always changes.
If the number of commands change, though, the target will still be out of date. If the number of commands change, though, the target will still be out of date.
The same effect applies to any command line that uses the variable
.Va .OODATE ,
which can be used for that purpose even when not otherwise needed or desired:
.Bd -literal -offset indent
skip-compare-for-some:
@echo this will be compared
@echo this will not ${.OODATE:M.NOMETA_CMP}
@echo this will also be compared
.Ed
The
.Cm \&:M
pattern suppresses any expansion of the unwanted variable.
.It Ic .NOPATH .It Ic .NOPATH
Do not search for the target in the directories specified by Do not search for the target in the directories specified by
.Ic .PATH . .Ic .PATH .
@ -2008,6 +2029,10 @@ If no sources are specified, the
.Ic .SILENT .Ic .SILENT
attribute is applied to every attribute is applied to every
command in the file. command in the file.
.It Ic .STALE
This target gets run when a dependency file contains stale entries, having
.Va .ALLSRC
set to the name of that dependency file.
.It Ic .SUFFIXES .It Ic .SUFFIXES
Each source specifies a suffix to Each source specifies a suffix to
.Nm . .Nm .

View File

@ -565,6 +565,11 @@ VVAARRIIAABBLLEE AASSSSIIGGNNMMEENNTTSS
`MAKEFLAGS' is re-exported whenever `_._M_A_K_E_O_V_E_R_R_I_D_E_S' is `MAKEFLAGS' is re-exported whenever `_._M_A_K_E_O_V_E_R_R_I_D_E_S' is
modified. modified.
_._M_A_K_E_._P_A_T_H___F_I_L_E_M_O_N
If bbmmaakkee was built with filemon(4) support, this is set
to the path of the device node. This allows makefiles to
test for this support.
_._M_A_K_E_._P_I_D The process-id of bbmmaakkee. _._M_A_K_E_._P_I_D The process-id of bbmmaakkee.
_._M_A_K_E_._P_P_I_D The parent process-id of bbmmaakkee. _._M_A_K_E_._P_P_I_D The parent process-id of bbmmaakkee.
@ -1106,7 +1111,19 @@ SSPPEECCIIAALL SSOOUURRCCEESS ((AATTTTRRIIBBUUTTEESS))
Ignore differences in commands when deciding if target is out Ignore differences in commands when deciding if target is out
of date. This is useful if the command contains a value which of date. This is useful if the command contains a value which
always changes. If the number of commands change, though, the always changes. If the number of commands change, though, the
target will still be out of date. target will still be out of date. The same effect applies to
any command line that uses the variable _._O_O_D_A_T_E, which can be
used for that purpose even when not otherwise needed or
desired:
skip-compare-for-some:
@echo this will be compared
@echo this will not ${.OODATE:M.NOMETA_CMP}
@echo this will also be compared
The ::MM pattern suppresses any expansion of the unwanted vari-
able.
..NNOOPPAATTHH Do not search for the target in the directories specified by ..NNOOPPAATTHH Do not search for the target in the directories specified by
..PPAATTHH. ..PPAATTHH.
@ -1278,6 +1295,9 @@ SSPPEECCIIAALL TTAARRGGEETTSS
sources are specified, the ..SSIILLEENNTT attribute is applied to every sources are specified, the ..SSIILLEENNTT attribute is applied to every
command in the file. command in the file.
..SSTTAALLEE This target gets run when a dependency file contains stale
entries, having _._A_L_L_S_R_C set to the name of that dependency file.
..SSUUFFFFIIXXEESS ..SSUUFFFFIIXXEESS
Each source specifies a suffix to bbmmaakkee. If no sources are Each source specifies a suffix to bbmmaakkee. If no sources are
specified, any previously specified suffixes are deleted. It specified, any previously specified suffixes are deleted. It
@ -1340,4 +1360,4 @@ BBUUGGSS
There is no way of escaping a space character in a filename. There is no way of escaping a space character in a filename.
NetBSD 5.1 January 23, 2013 NetBSD 5.1 NetBSD 5.1 March 30, 2013 NetBSD 5.1

View File

@ -111,7 +111,7 @@
# Simon J. Gerraty <sjg@crufty.net> # Simon J. Gerraty <sjg@crufty.net>
# RCSid: # RCSid:
# $Id: boot-strap,v 1.42 2013/01/25 20:20:33 sjg Exp $ # $Id: boot-strap,v 1.43 2013/03/02 18:55:23 sjg Exp $
# #
# @(#) Copyright (c) 2001 Simon J. Gerraty # @(#) Copyright (c) 2001 Simon J. Gerraty
# #
@ -159,6 +159,9 @@ source_rc() {
cmd_args="$@" cmd_args="$@"
# clear some things from the environment that we care about
unset MAKEOBJDIR MAKEOBJDIRPREFIX
# --install[-host-target] will set this # --install[-host-target] will set this
INSTALL_PREFIX= INSTALL_PREFIX=
# other things we pass to install step # other things we pass to install step

18
configure vendored
View File

@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.64 for bmake 20121212. # Generated by GNU Autoconf 2.64 for bmake 20130303.
# #
# Report bugs to <sjg@NetBSD.org>. # Report bugs to <sjg@NetBSD.org>.
# #
@ -549,8 +549,8 @@ MAKEFLAGS=
# Identity of this package. # Identity of this package.
PACKAGE_NAME='bmake' PACKAGE_NAME='bmake'
PACKAGE_TARNAME='bmake' PACKAGE_TARNAME='bmake'
PACKAGE_VERSION='20121212' PACKAGE_VERSION='20130303'
PACKAGE_STRING='bmake 20121212' PACKAGE_STRING='bmake 20130303'
PACKAGE_BUGREPORT='sjg@NetBSD.org' PACKAGE_BUGREPORT='sjg@NetBSD.org'
PACKAGE_URL='' PACKAGE_URL=''
@ -1220,7 +1220,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing. # Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh. # This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF cat <<_ACEOF
\`configure' configures bmake 20121212 to adapt to many kinds of systems. \`configure' configures bmake 20130303 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]... Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1281,7 +1281,7 @@ fi
if test -n "$ac_init_help"; then if test -n "$ac_init_help"; then
case $ac_init_help in case $ac_init_help in
short | recursive ) echo "Configuration of bmake 20121212:";; short | recursive ) echo "Configuration of bmake 20130303:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@ -1386,7 +1386,7 @@ fi
test -n "$ac_init_help" && exit $ac_status test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then if $ac_init_version; then
cat <<\_ACEOF cat <<\_ACEOF
bmake configure 20121212 bmake configure 20130303
generated by GNU Autoconf 2.64 generated by GNU Autoconf 2.64
Copyright (C) 2009 Free Software Foundation, Inc. Copyright (C) 2009 Free Software Foundation, Inc.
@ -1907,7 +1907,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake. running configure, to aid debugging if configure makes a mistake.
It was created by bmake $as_me 20121212, which was It was created by bmake $as_me 20130303, which was
generated by GNU Autoconf 2.64. Invocation command line was generated by GNU Autoconf 2.64. Invocation command line was
$ $0 $@ $ $0 $@
@ -6374,7 +6374,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their # report actual input values of CONFIG_FILES etc. instead of their
# values after options handling. # values after options handling.
ac_log=" ac_log="
This file was extended by bmake $as_me 20121212, which was This file was extended by bmake $as_me 20130303, which was
generated by GNU Autoconf 2.64. Invocation command line was generated by GNU Autoconf 2.64. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
@ -6434,7 +6434,7 @@ Report bugs to <sjg@NetBSD.org>."
_ACEOF _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_version="\\ ac_cs_version="\\
bmake config.status 20121212 bmake config.status 20130303
configured by $0, generated by GNU Autoconf 2.64, configured by $0, generated by GNU Autoconf 2.64,
with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"

View File

@ -1,10 +1,10 @@
dnl dnl
dnl RCSid: dnl RCSid:
dnl $Id: configure.in,v 1.46 2012/12/28 21:28:18 sjg Exp $ dnl $Id: configure.in,v 1.48 2013/03/04 21:25:57 sjg Exp $
dnl dnl
dnl Process this file with autoconf to produce a configure script dnl Process this file with autoconf to produce a configure script
dnl dnl
AC_INIT([bmake], [20121212], [sjg@NetBSD.org]) AC_INIT([bmake], [20130303], [sjg@NetBSD.org])
AC_CONFIG_HEADER(config.h) AC_CONFIG_HEADER(config.h)
dnl make srcdir absolute dnl make srcdir absolute

15
dir.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: dir.c,v 1.65 2012/06/12 19:21:50 joerg Exp $ */ /* $NetBSD: dir.c,v 1.67 2013/03/05 22:01:43 christos Exp $ */
/* /*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California. * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@ -70,14 +70,14 @@
*/ */
#ifndef MAKE_NATIVE #ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: dir.c,v 1.65 2012/06/12 19:21:50 joerg Exp $"; static char rcsid[] = "$NetBSD: dir.c,v 1.67 2013/03/05 22:01:43 christos Exp $";
#else #else
#include <sys/cdefs.h> #include <sys/cdefs.h>
#ifndef lint #ifndef lint
#if 0 #if 0
static char sccsid[] = "@(#)dir.c 8.2 (Berkeley) 1/2/94"; static char sccsid[] = "@(#)dir.c 8.2 (Berkeley) 1/2/94";
#else #else
__RCSID("$NetBSD: dir.c,v 1.65 2012/06/12 19:21:50 joerg Exp $"); __RCSID("$NetBSD: dir.c,v 1.67 2013/03/05 22:01:43 christos Exp $");
#endif #endif
#endif /* not lint */ #endif /* not lint */
#endif #endif
@ -145,6 +145,7 @@ __RCSID("$NetBSD: dir.c,v 1.65 2012/06/12 19:21:50 joerg Exp $");
#include "make.h" #include "make.h"
#include "hash.h" #include "hash.h"
#include "dir.h" #include "dir.h"
#include "job.h"
/* /*
* A search path consists of a Lst of Path structures. A Path structure * A search path consists of a Lst of Path structures. A Path structure
@ -1463,9 +1464,11 @@ Dir_MTime(GNode *gn, Boolean recheck)
* so that we give that to the compiler. * so that we give that to the compiler.
*/ */
gn->path = bmake_strdup(fullName); gn->path = bmake_strdup(fullName);
fprintf(stdout, if (!Job_RunTarget(".STALE", gn->fname))
"%s: ignoring stale %s for %s, found %s\n", fprintf(stdout,
progname, makeDependfile, gn->name, fullName); "%s: %s, %d: ignoring stale %s for %s, "
"found %s\n", progname, gn->fname, gn->lineno,
makeDependfile, gn->name, fullName);
} }
} }
} }

104
job.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: job.c,v 1.165 2013/01/26 15:52:59 christos Exp $ */ /* $NetBSD: job.c,v 1.172 2013/03/05 22:01:43 christos Exp $ */
/* /*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California. * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@ -70,14 +70,14 @@
*/ */
#ifndef MAKE_NATIVE #ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: job.c,v 1.165 2013/01/26 15:52:59 christos Exp $"; static char rcsid[] = "$NetBSD: job.c,v 1.172 2013/03/05 22:01:43 christos Exp $";
#else #else
#include <sys/cdefs.h> #include <sys/cdefs.h>
#ifndef lint #ifndef lint
#if 0 #if 0
static char sccsid[] = "@(#)job.c 8.2 (Berkeley) 3/19/94"; static char sccsid[] = "@(#)job.c 8.2 (Berkeley) 3/19/94";
#else #else
__RCSID("$NetBSD: job.c,v 1.165 2013/01/26 15:52:59 christos Exp $"); __RCSID("$NetBSD: job.c,v 1.172 2013/03/05 22:01:43 christos Exp $");
#endif #endif
#endif /* not lint */ #endif /* not lint */
#endif #endif
@ -142,6 +142,7 @@ __RCSID("$NetBSD: job.c,v 1.165 2013/01/26 15:52:59 christos Exp $");
#include <sys/time.h> #include <sys/time.h>
#include "wait.h" #include "wait.h"
#include <assert.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#if !defined(USE_SELECT) && defined(HAVE_POLL_H) #if !defined(USE_SELECT) && defined(HAVE_POLL_H)
@ -1245,8 +1246,10 @@ Job_CheckCommands(GNode *gn, void (*abortProc)(const char *, ...))
static const char msg[] = ": don't know how to make"; static const char msg[] = ": don't know how to make";
if (gn->flags & FROM_DEPEND) { if (gn->flags & FROM_DEPEND) {
fprintf(stdout, "%s: ignoring stale %s for %s\n", if (!Job_RunTarget(".STALE", gn->fname))
progname, makeDependfile, gn->name); fprintf(stdout, "%s: %s, %d: ignoring stale %s for %s\n",
progname, gn->fname, gn->lineno, makeDependfile,
gn->name);
return TRUE; return TRUE;
} }
@ -2063,32 +2066,45 @@ Job_CatchOutput(void)
(void)fflush(stdout); (void)fflush(stdout);
/* The first fd in the list is the job token pipe */ /* The first fd in the list is the job token pipe */
nready = poll(fds + 1 - wantToken, nfds - 1 + wantToken, POLL_MSEC); do {
nready = poll(fds + 1 - wantToken, nfds - 1 + wantToken, POLL_MSEC);
} while (nready < 0 && errno == EINTR);
if (nready < 0 || readyfd(&childExitJob)) { if (nready < 0)
Punt("poll: %s", strerror(errno));
if (nready > 0 && readyfd(&childExitJob)) {
char token = 0; char token = 0;
nready -= 1; ssize_t count;
while (read(childExitJob.inPipe, &token, 1) == -1 && errno == EAGAIN) count = read(childExitJob.inPipe, &token, 1);
continue; switch (count) {
if (token == DO_JOB_RESUME[0]) case 0:
/* Complete relay requested from our SIGCONT handler */ Punt("unexpected eof on token pipe");
JobRestartJobs(); case -1:
Job_CatchChildren(); Punt("token pipe read: %s", strerror(errno));
case 1:
if (token == DO_JOB_RESUME[0])
/* Complete relay requested from our SIGCONT handler */
JobRestartJobs();
break;
default:
abort();
}
--nready;
} }
if (nready <= 0) Job_CatchChildren();
return; if (nready == 0)
return;
if (wantToken && readyfd(&tokenWaitJob))
nready--;
for (i = 2; i < nfds; i++) { for (i = 2; i < nfds; i++) {
if (!fds[i].revents) if (!fds[i].revents)
continue; continue;
job = jobfds[i]; job = jobfds[i];
if (job->job_state != JOB_ST_RUNNING) if (job->job_state == JOB_ST_RUNNING)
continue; JobDoOutput(job, FALSE);
JobDoOutput(job, FALSE); if (--nready == 0)
return;
} }
} }
@ -2179,8 +2195,6 @@ Job_SetPrefix(void)
void void
Job_Init(void) Job_Init(void)
{ {
GNode *begin; /* node for commands to do at the very start */
/* Allocate space for all the job info */ /* Allocate space for all the job info */
job_table = bmake_malloc(maxJobs * sizeof *job_table); job_table = bmake_malloc(maxJobs * sizeof *job_table);
memset(job_table, 0, maxJobs * sizeof *job_table); memset(job_table, 0, maxJobs * sizeof *job_table);
@ -2256,15 +2270,7 @@ Job_Init(void)
ADDSIG(SIGCONT, JobContinueSig) ADDSIG(SIGCONT, JobContinueSig)
#undef ADDSIG #undef ADDSIG
begin = Targ_FindNode(".BEGIN", TARG_NOCREATE); (void)Job_RunTarget(".BEGIN", NULL);
if (begin != NULL) {
JobRun(begin);
if (begin->made == ERROR) {
PrintOnError(begin, "\n\nStop.");
exit(1);
}
}
postCommands = Targ_FindNode(".END", TARG_CREATE); postCommands = Targ_FindNode(".END", TARG_CREATE);
} }
@ -2930,6 +2936,38 @@ Job_TokenWithdraw(void)
return TRUE; return TRUE;
} }
/*-
*-----------------------------------------------------------------------
* Job_RunTarget --
* Run the named target if found. If a filename is specified, then
* set that to the sources.
*
* Results:
* None
*
* Side Effects:
* exits if the target fails.
*
*-----------------------------------------------------------------------
*/
Boolean
Job_RunTarget(const char *target, const char *fname) {
GNode *gn = Targ_FindNode(target, TARG_NOCREATE);
if (gn == NULL)
return FALSE;
if (fname)
Var_Set(ALLSRC, fname, gn, 0);
JobRun(gn);
if (gn->made == ERROR) {
PrintOnError(gn, "\n\nStop.");
exit(1);
}
return TRUE;
}
#ifdef USE_SELECT #ifdef USE_SELECT
int int
emul_poll(struct pollfd *fd, int nfd, int timeout) emul_poll(struct pollfd *fd, int nfd, int timeout)

3
job.h
View File

@ -1,4 +1,4 @@
/* $NetBSD: job.h,v 1.40 2010/09/13 15:36:57 sjg Exp $ */ /* $NetBSD: job.h,v 1.41 2013/03/05 22:01:44 christos Exp $ */
/* /*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California. * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@ -268,5 +268,6 @@ void Job_TokenReturn(void);
Boolean Job_TokenWithdraw(void); Boolean Job_TokenWithdraw(void);
void Job_ServerStart(int, int, int); void Job_ServerStart(int, int, int);
void Job_SetPrefix(void); void Job_SetPrefix(void);
Boolean Job_RunTarget(const char *, const char *);
#endif /* _JOB_H_ */ #endif /* _JOB_H_ */

31
main.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: main.c,v 1.205 2013/01/26 15:53:00 christos Exp $ */ /* $NetBSD: main.c,v 1.210 2013/03/23 05:31:29 sjg Exp $ */
/* /*
* Copyright (c) 1988, 1989, 1990, 1993 * Copyright (c) 1988, 1989, 1990, 1993
@ -69,7 +69,7 @@
*/ */
#ifndef MAKE_NATIVE #ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: main.c,v 1.205 2013/01/26 15:53:00 christos Exp $"; static char rcsid[] = "$NetBSD: main.c,v 1.210 2013/03/23 05:31:29 sjg Exp $";
#else #else
#include <sys/cdefs.h> #include <sys/cdefs.h>
#ifndef lint #ifndef lint
@ -81,7 +81,7 @@ __COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993\
#if 0 #if 0
static char sccsid[] = "@(#)main.c 8.3 (Berkeley) 3/19/94"; static char sccsid[] = "@(#)main.c 8.3 (Berkeley) 3/19/94";
#else #else
__RCSID("$NetBSD: main.c,v 1.205 2013/01/26 15:53:00 christos Exp $"); __RCSID("$NetBSD: main.c,v 1.210 2013/03/23 05:31:29 sjg Exp $");
#endif #endif
#endif /* not lint */ #endif /* not lint */
#endif #endif
@ -119,9 +119,7 @@ __RCSID("$NetBSD: main.c,v 1.205 2013/01/26 15:53:00 christos Exp $");
#include <sys/resource.h> #include <sys/resource.h>
#include <signal.h> #include <signal.h>
#include <sys/stat.h> #include <sys/stat.h>
#ifdef MAKE_NATIVE
#include <sys/utsname.h> #include <sys/utsname.h>
#endif
#include "wait.h" #include "wait.h"
#include <errno.h> #include <errno.h>
@ -768,7 +766,7 @@ MakeMode(const char *mode)
} }
#if USE_META #if USE_META
if (strstr(mode, "meta")) if (strstr(mode, "meta"))
meta_init(mode); meta_mode_init(mode);
#endif #endif
} }
if (mp) if (mp)
@ -813,9 +811,7 @@ main(int argc, char **argv)
static char defsyspath[] = _PATH_DEFSYSPATH; static char defsyspath[] = _PATH_DEFSYSPATH;
char found_path[MAXPATHLEN + 1]; /* for searching for sys.mk */ char found_path[MAXPATHLEN + 1]; /* for searching for sys.mk */
struct timeval rightnow; /* to initialize random seed */ struct timeval rightnow; /* to initialize random seed */
#ifdef MAKE_NATIVE
struct utsname utsname; struct utsname utsname;
#endif
/* default to writing debug to stderr */ /* default to writing debug to stderr */
debug_file = stderr; debug_file = stderr;
@ -834,7 +830,7 @@ main(int argc, char **argv)
progname++; progname++;
else else
progname = argv[0]; progname = argv[0];
#ifdef RLIMIT_NOFILE #if defined(MAKE_NATIVE) || (defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE))
/* /*
* get rid of resource limit on file descriptors * get rid of resource limit on file descriptors
*/ */
@ -848,6 +844,12 @@ main(int argc, char **argv)
} }
#endif #endif
if (uname(&utsname) == -1) {
(void)fprintf(stderr, "%s: uname failed (%s).\n", progname,
strerror(errno));
exit(2);
}
/* /*
* Get the name of this type of MACHINE from utsname * Get the name of this type of MACHINE from utsname
* so we can share an executable for similar machines. * so we can share an executable for similar machines.
@ -858,11 +860,6 @@ main(int argc, char **argv)
*/ */
if (!machine) { if (!machine) {
#ifdef MAKE_NATIVE #ifdef MAKE_NATIVE
if (uname(&utsname) == -1) {
(void)fprintf(stderr, "%s: uname failed (%s).\n", progname,
strerror(errno));
exit(2);
}
machine = utsname.machine; machine = utsname.machine;
#else #else
#ifdef MAKE_MACHINE #ifdef MAKE_MACHINE
@ -892,6 +889,7 @@ main(int argc, char **argv)
*/ */
Var_Init(); /* Initialize the lists of variables for Var_Init(); /* Initialize the lists of variables for
* parsing arguments */ * parsing arguments */
Var_Set(".MAKE.OS", utsname.sysname, VAR_GLOBAL, 0);
Var_Set("MACHINE", machine, VAR_GLOBAL, 0); Var_Set("MACHINE", machine, VAR_GLOBAL, 0);
Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL, 0); Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL, 0);
#ifdef MAKE_VERSION #ifdef MAKE_VERSION
@ -987,6 +985,9 @@ main(int argc, char **argv)
} }
Job_SetPrefix(); Job_SetPrefix();
#ifdef USE_META
meta_init();
#endif
/* /*
* First snag any flags out of the MAKE environment variable. * First snag any flags out of the MAKE environment variable.
* (Note this is *not* MAKEFLAGS since /bin/make uses that and it's * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's
@ -1697,7 +1698,7 @@ Finish(int errors)
} }
/* /*
* enunlink -- * eunlink --
* Remove a file carefully, avoiding directories. * Remove a file carefully, avoiding directories.
*/ */
int int

29
make.1
View File

@ -1,4 +1,4 @@
.\" $NetBSD: make.1,v 1.210 2013/01/27 18:52:01 sjg Exp $ .\" $NetBSD: make.1,v 1.213 2013/03/31 05:49:51 sjg Exp $
.\" .\"
.\" Copyright (c) 1990, 1993 .\" Copyright (c) 1990, 1993
.\" The Regents of the University of California. All rights reserved. .\" The Regents of the University of California. All rights reserved.
@ -29,7 +29,7 @@
.\" .\"
.\" from: @(#)make.1 8.4 (Berkeley) 3/19/94 .\" from: @(#)make.1 8.4 (Berkeley) 3/19/94
.\" .\"
.Dd January 23, 2013 .Dd March 30, 2013
.Dt MAKE 1 .Dt MAKE 1
.Os .Os
.Sh NAME .Sh NAME
@ -874,6 +874,13 @@ by appending their names to
is re-exported whenever is re-exported whenever
.Ql Va .MAKEOVERRIDES .Ql Va .MAKEOVERRIDES
is modified. is modified.
.It Va .MAKE.PATH_FILEMON
If
.Nm
was built with
.Xr filemon 4
support, this is set to the path of the device node.
This allows makefiles to test for this support.
.It Va .MAKE.PID .It Va .MAKE.PID
The process-id of The process-id of
.Nm . .Nm .
@ -1757,6 +1764,20 @@ targets.
Ignore differences in commands when deciding if target is out of date. Ignore differences in commands when deciding if target is out of date.
This is useful if the command contains a value which always changes. This is useful if the command contains a value which always changes.
If the number of commands change, though, the target will still be out of date. If the number of commands change, though, the target will still be out of date.
The same effect applies to any command line that uses the variable
.Va .OODATE ,
which can be used for that purpose even when not otherwise needed or desired:
.Bd -literal -offset indent
skip-compare-for-some:
@echo this will be compared
@echo this will not ${.OODATE:M.NOMETA_CMP}
@echo this will also be compared
.Ed
The
.Cm \&:M
pattern suppresses any expansion of the unwanted variable.
.It Ic .NOPATH .It Ic .NOPATH
Do not search for the target in the directories specified by Do not search for the target in the directories specified by
.Ic .PATH . .Ic .PATH .
@ -2008,6 +2029,10 @@ If no sources are specified, the
.Ic .SILENT .Ic .SILENT
attribute is applied to every attribute is applied to every
command in the file. command in the file.
.It Ic .STALE
This target gets run when a dependency file contains stale entries, having
.Va .ALLSRC
set to the name of that dependency file.
.It Ic .SUFFIXES .It Ic .SUFFIXES
Each source specifies a suffix to Each source specifies a suffix to
.Nm . .Nm .

4
make.h
View File

@ -1,4 +1,4 @@
/* $NetBSD: make.h,v 1.89 2012/06/12 19:21:51 joerg Exp $ */ /* $NetBSD: make.h,v 1.90 2013/02/25 01:57:14 dholland Exp $ */
/* /*
* Copyright (c) 1988, 1989, 1990, 1993 * Copyright (c) 1988, 1989, 1990, 1993
@ -103,7 +103,7 @@
((__GNUC__ == (x) && __GNUC_MINOR__ >= (y)) || \ ((__GNUC__ == (x) && __GNUC_MINOR__ >= (y)) || \
(__GNUC__ > (x))) (__GNUC__ > (x)))
#else /* defined(__GNUC__) */ #else /* defined(__GNUC__) */
#define MAKE_GNUC_PREREQx, y) 0 #define MAKE_GNUC_PREREQ(x, y) 0
#endif /* defined(__GNUC__) */ #endif /* defined(__GNUC__) */
#if MAKE_GNUC_PREREQ(2, 7) #if MAKE_GNUC_PREREQ(2, 7)

45
meta.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: meta.c,v 1.26 2013/01/19 04:23:37 sjg Exp $ */ /* $NetBSD: meta.c,v 1.29 2013/03/31 05:49:51 sjg Exp $ */
/* /*
* Implement 'meta' mode. * Implement 'meta' mode.
@ -539,8 +539,24 @@ boolValue(char *s)
return TRUE; return TRUE;
} }
/*
* Initialization we need before reading makefiles.
*/
void void
meta_init(const char *make_mode) meta_init()
{
#ifdef USE_FILEMON
/* this allows makefiles to test if we have filemon support */
Var_Set(".MAKE.PATH_FILEMON", _PATH_FILEMON, VAR_GLOBAL, 0);
#endif
}
/*
* Initialization we need after reading makefiles.
*/
void
meta_mode_init(const char *make_mode)
{ {
static int once = 0; static int once = 0;
char *cp; char *cp;
@ -1037,6 +1053,7 @@ meta_oodate(GNode *gn, Boolean oodate)
char *tp = Lst_Datum(ln); char *tp = Lst_Datum(ln);
Lst_Remove(missingFiles, ln); Lst_Remove(missingFiles, ln);
free(tp); free(tp);
ln = NULL; /* we're done with it */
} }
} }
break; break;
@ -1196,17 +1213,19 @@ meta_oodate(GNode *gn, Boolean oodate)
oodate = TRUE; oodate = TRUE;
} else { } else {
char *cmd = (char *)Lst_Datum(ln); char *cmd = (char *)Lst_Datum(ln);
Boolean hasOODATE = FALSE;
if (!needOODATE) { if (strstr(cmd, "$?"))
if (strstr(cmd, "$?")) hasOODATE = TRUE;
needOODATE = TRUE; else if ((cp = strstr(cmd, ".OODATE"))) {
else if ((cp = strstr(cmd, ".OODATE"))) { /* check for $[{(].OODATE[:)}] */
/* check for $[{(].OODATE[)}] */ if (cp > cmd + 2 && cp[-2] == '$')
if (cp > cmd + 2 && cp[-2] == '$') hasOODATE = TRUE;
needOODATE = TRUE; }
} if (hasOODATE) {
if (needOODATE && DEBUG(META)) needOODATE = TRUE;
fprintf(debug_file, "%s: %d: cannot compare commands using .OODATE\n", fname, lineno); if (DEBUG(META))
fprintf(debug_file, "%s: %d: cannot compare command using .OODATE\n", fname, lineno);
} }
cmd = Var_Subst(NULL, cmd, gn, TRUE); cmd = Var_Subst(NULL, cmd, gn, TRUE);
@ -1235,7 +1254,7 @@ meta_oodate(GNode *gn, Boolean oodate)
if (buf[x - 1] == '\n') if (buf[x - 1] == '\n')
buf[x - 1] = '\0'; buf[x - 1] = '\0';
} }
if (!needOODATE && if (!hasOODATE &&
!(gn->type & OP_NOMETA_CMP) && !(gn->type & OP_NOMETA_CMP) &&
strcmp(p, cmd) != 0) { strcmp(p, cmd) != 0) {
if (DEBUG(META)) if (DEBUG(META))

5
meta.h
View File

@ -1,4 +1,4 @@
/* $NetBSD: meta.h,v 1.2 2011/03/30 22:03:49 sjg Exp $ */ /* $NetBSD: meta.h,v 1.3 2013/03/23 05:31:29 sjg Exp $ */
/* /*
* Things needed for 'meta' mode. * Things needed for 'meta' mode.
@ -41,7 +41,8 @@ typedef struct BuildMon {
extern Boolean useMeta; extern Boolean useMeta;
struct Job; /* not defined yet */ struct Job; /* not defined yet */
void meta_init(const char *); void meta_init(void);
void meta_mode_init(const char *);
void meta_job_start(struct Job *, GNode *); void meta_job_start(struct Job *, GNode *);
void meta_job_child(struct Job *); void meta_job_child(struct Job *);
void meta_job_error(struct Job *, GNode *, int, int); void meta_job_error(struct Job *, GNode *, int, int);

View File

@ -1,3 +1,71 @@
2013-03-30 Simon J. Gerraty <sjg@bad.crufty.net>
* meta2deps.py (MetaFile.__init__): ensure self.cwd is initialized.
* install-mk (MK_VERSION): bump version
2013-03-21 Simon J. Gerraty <sjg@bad.crufty.net>
* install-mk (MK_VERSION): bump version
* gendirdeps.mk: do not apply :tA to DPADD entries, since we lose
any trailing /., rather apply :tA only when needed.
* gendirdeps.mk: better mimic meta2deps handling of .dirdep files.
* meta.stage.mk (LN_CP_SCRIPT): Add LnCp to do the ln||cp dance
consistently.
* dirdeps.mk: better describe the dance in sys.mk for TARGET_SPEC.
2013-03-18 Simon J. Gerraty <sjg@bad.crufty.net>
* gendirdeps.mk: revert the dance around .MAKE.DEPENDFILE_DEFAULT
it is simpler to just not update when say building for "host"
(where we know we apply filters to DIRDEPS), and using a
non-machine qualified dependfile.
2013-03-16 Simon J. Gerraty <sjg@bad.crufty.net>
* dirdeps.mk: improve DIRDEPS filtering by allowing DEP_SKIP_DIR
and DEP_DIRDEPS_FILTER to vary by DEP_MACHINE and DEP_TARGET_SPEC
* gendirdeps.mk: ensure _objroot has trailing / if it needs it.
* meta2deps.py: if machine is "host", then also trim
self.host_target from any OBJROOTS.
2013-03-11 Simon J. Gerraty <sjg@bad.crufty.net>
* gendirdeps.mk: if .MAKE.DEPENDFILE_DEFAULT is not machine
qualified but _DEPENDFILE is, and .MAKE.DEPENDFILE_DEFAULT exists
but _DEPENDFILE does not, compare the new _DEPENDFILE against
.MAKE.DEPENDFILE_DEFAULT and discard if the same.
2013-03-08 Simon J. Gerraty <sjg@bad.crufty.net>
* meta.stage.mk: use STAGE_TARGETS to control .ORDER
and hook to all: via staging:
2013-03-07 Simon J. Gerraty <sjg@bad.crufty.net>
* sys.dependfile.mk (.MAKE.DEPENDFILE_DEFAULT):
use a separate variable for the default .MAKE.DEPENDFILE value
so that it can be controlled independently of
.MAKE.DEPENDFILE_PREFERENCE
* meta.stage.mk: throw error if cp fails etc.
Stage*() return early if passed no args.
.ORDER stage_*
2013-03-03 Simon J. Gerraty <sjg@bad.crufty.net>
* install-mk (MK_VERSION): bump version
* gendirdeps.mk: handle multiple M2D_OBJROOTS better.
2013-02-10 Simon J. Gerraty <sjg@bad.crufty.net>
* install-mk (MK_VERSION): bump version to 20130210
* import latest dirdeps.mk, gendirdeps.mk and meta2deps.py
from Juniper.
o dirdeps.mk now fully supports TARGET_SPEC consisting of more
than just MACHINE.
o no longer use DEP_MACHINE from Makefile.depend* so remove it.
2013-01-23 Simon J. Gerraty <sjg@bad.crufty.net> 2013-01-23 Simon J. Gerraty <sjg@bad.crufty.net>
* install-mk (MK_VERSION): bump version to 20130123 * install-mk (MK_VERSION): bump version to 20130123

View File

@ -1,6 +1,7 @@
# $Id: dirdeps.mk,v 1.23 2012/11/06 05:44:03 sjg Exp $ # $Id: dirdeps.mk,v 1.28 2013/03/25 21:11:43 sjg Exp $
# Copyright (c) 2010-2012, Juniper Networks, Inc. # Copyright (c) 2010-2013, Juniper Networks, Inc.
# All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions # modification, are permitted provided that the following conditions
@ -33,21 +34,31 @@
# This is what we do with DIRDEPS # This is what we do with DIRDEPS
# DIRDEPS: # DIRDEPS:
# This is a list of directories - relative to SRCTOP, it is only # This is a list of directories - relative to SRCTOP, it is
# of interest to .MAKE.LEVEL 0. # normally only of interest to .MAKE.LEVEL 0.
# In some cases the entry may be qualified with a .<machine> # In some cases the entry may be qualified with a .<machine>
# suffix, for example to force building something for the pseudo # or .<target_spec> suffix (see TARGET_SPEC_VARS below),
# for example to force building something for the pseudo
# machines "host" or "common" regardless of current ${MACHINE}. # machines "host" or "common" regardless of current ${MACHINE}.
# All unqualified entries end up being qualified with .${MACHINE} #
# and _DIRDEPS_USE below, uses the suffix to set MACHINE # All unqualified entries end up being qualified with .${TARGET_SPEC}
# and partially qualified (if TARGET_SPEC_VARS has multiple
# entries) are also expanded to a full .<target_spec>.
# The _DIRDEPS_USE target uses the suffix to set TARGET_SPEC
# correctly when visiting each entry. # correctly when visiting each entry.
# #
# Each entry is also converted into a set of paths to look for # The fully qualified directory entries are used to construct a
# Makefile.depend.<machine> to learn the dependencies of each. # dependency graph that will drive the build later.
# Each Makefile.depend.<machine> sets DEP_RELDIR to be the #
# Also, for each fully qualified directory target, we will search
# using ${.MAKE.DEPENDFILE_PREFERENCE} to find additional
# dependencies. We use Makefile.depend (default value for
# .MAKE.DEPENDFILE_PREFIX) to refer to these makefiles to
# distinguish them from others.
#
# Each Makefile.depend file sets DEP_RELDIR to be the
# the RELDIR (path relative to SRCTOP) for its directory, and # the RELDIR (path relative to SRCTOP) for its directory, and
# DEP_MACHINE to its suffix (<machine>), further since # since each Makefile.depend file includes dirdeps.mk, this
# each Makefile.depend.<machine> includes dirdeps.mk, this
# processing is recursive and results in .MAKE.LEVEL 0 learning the # processing is recursive and results in .MAKE.LEVEL 0 learning the
# dependencies of the tree wrt the initial directory (_DEP_RELDIR). # dependencies of the tree wrt the initial directory (_DEP_RELDIR).
# #
@ -55,38 +66,49 @@
# Indicates whether .MAKE.LEVEL 0 builds anything: # Indicates whether .MAKE.LEVEL 0 builds anything:
# if "no" sub-makes are used to build everything, # if "no" sub-makes are used to build everything,
# if "yes" sub-makes are only used to build for other machines. # if "yes" sub-makes are only used to build for other machines.
# It is best to use "no", but this can require fixing some
# makefiles to not do anything at .MAKE.LEVEL 0.
# #
# TARGET_SPEC_VARS # TARGET_SPEC_VARS
# All the description above (and below) assumes <machine> is the # The default value is just MACHINE, and for most environments
# only data needed to control the build. # this is sufficient. The _DIRDEPS_USE target actually sets
# This is not always the case. So in addition to setting # both MACHINE and TARGET_SPEC to the suffix of the current
# MACHINE in the build environment we set TARGET_SPEC which is # target so that in the general case TARGET_SPEC can be ignored.
# composed of the values of TARGET_SPEC_VARS separated by
# commas. The default is just MACHINE.
# #
# If more that MACHINE is needed then sys.mk needs to decompose # If more than MACHINE is needed then sys.mk needs to decompose
# TARGET_SPEC and set the relevant variables accordingly. # TARGET_SPEC and set the relevant variables accordingly.
# It is important that MACHINE be included in TARGET_SPEC_VARS # It is important that MACHINE be included in and actually be
# since if there is more the value passed as MACHINE will infact # the first member of TARGET_SPEC_VARS. This allows other
# be the TARGET_SPEC. # variables to be considered optional, and some of the treatment
# below relies on MACHINE being the first entry.
# Note: TARGET_SPEC cannot contain any '.'s so the target # Note: TARGET_SPEC cannot contain any '.'s so the target
# tripple used by compiler folk won't work (directly anyway). # triple used by compiler folk won't work (directly anyway).
# #
# For example: # For example:
# #
# # variables other than MACHINE might be optional # # Always list MACHINE first,
# # other variables might be optional.
# TARGET_SPEC_VARS = MACHINE TARGET_OS # TARGET_SPEC_VARS = MACHINE TARGET_OS
# .if ${TARGET_SPEC:Uno:M*,*} != "" # .if ${TARGET_SPEC:Uno:M*,*} != ""
# _tspec := ${TARGET_SPEC:S/,/ /g} # _tspec := ${TARGET_SPEC:S/,/ /g}
# MACHINE := ${_tspec:[1]} # MACHINE := ${_tspec:[1]}
# TARGET_OS := ${_tspec:[2]} # TARGET_OS := ${_tspec:[2]}
# # etc. # # etc.
# # We need to stop that TARGET_SPEC affecting any submakes
# # and deal with MACHINE=${TARGET_SPEC} in the environment.
# TARGET_SPEC =
# # export but do not track
# .export-env TARGET_SPEC
# .export ${TARGET_SPEC_VARS}
# .for v in ${TARGET_SPEC_VARS:O:u} # .for v in ${TARGET_SPEC_VARS:O:u}
# .if empty($v) # .if empty($v)
# .undef $v # .undef $v
# .endif # .endif
# .endfor # .endfor
# .endif # .endif
# # make sure we know what TARGET_SPEC is
# # as we may need it to find Makefile.depend*
# TARGET_SPEC = ${TARGET_SPEC_VARS:@v@${$v:U}@:ts,}
# #
.if ${.MAKE.LEVEL} == 0 .if ${.MAKE.LEVEL} == 0
@ -100,14 +122,48 @@
# do some setup we only need once # do some setup we only need once
_CURDIR ?= ${.CURDIR} _CURDIR ?= ${.CURDIR}
# make sure these are empty to start with
_DEP_TARGET_SPEC =
_DIRDEP_CHECKED =
# If TARGET_SPEC_VARS is other than just MACHINE # If TARGET_SPEC_VARS is other than just MACHINE
# it should be set by sys.mk or similar by now. # it should be set by sys.mk or similar by now.
# TARGET_SPEC must not contain any '.'s. # TARGET_SPEC must not contain any '.'s.
TARGET_SPEC_VARS ?= MACHINE TARGET_SPEC_VARS ?= MACHINE
# this is what we started with
TARGET_SPEC = ${TARGET_SPEC_VARS:@v@${$v:U}@:ts,} TARGET_SPEC = ${TARGET_SPEC_VARS:@v@${$v:U}@:ts,}
# this is what we mostly use below
DEP_TARGET_SPEC = ${TARGET_SPEC_VARS:S,^,DEP_,:@v@${$v:U}@:ts,}
# make sure we have defaults
.for v in ${TARGET_SPEC_VARS}
DEP_$v ?= ${$v}
.endfor
.if ${TARGET_SPEC_VARS:[#]} > 1
# Ok, this gets more complex (putting it mildly).
# In order to stay sane, we need to ensure that all the build_dirs
# we compute below are fully qualified wrt DEP_TARGET_SPEC.
# The makefiles may only partially specify (eg. MACHINE only),
# so we need to construct a set of modifiers to fill in the gaps.
# jot 10 should output 1 2 3 .. 10
JOT ?= jot
_tspec_x := ${${JOT} ${TARGET_SPEC_VARS:[#]}:L:sh}
# this handles unqualified entries
M_dep_qual_fixes = C;(/[^/.,]+)$$;\1.${DEP_TARGET_SPEC};
# there needs to be at least one item missing for these to make sense
.for i in ${_tspec_x:[2..-1]}
_tspec_m$i := ${TARGET_SPEC_VARS:[2..$i]:@w@[^,]+@:ts,}
_tspec_a$i := ,${TARGET_SPEC_VARS:[$i..-1]:@v@$${DEP_$v}@:ts,}
M_dep_qual_fixes += C;(\.${_tspec_m$i})$$;\1${_tspec_a$i};
.endfor
.else
# A harmless? default.
M_dep_qual_fixes = U
.endif
.if !defined(.MAKE.DEPENDFILE_PREFERENCE) .if !defined(.MAKE.DEPENDFILE_PREFERENCE)
# this makes the logic below neater? # .MAKE.DEPENDFILE_PREFERENCE makes the logic below neater?
# you really want this set by sys.mk or similar
.MAKE.DEPENDFILE_PREFERENCE = ${_CURDIR}/${.MAKE.DEPENDFILE:T} .MAKE.DEPENDFILE_PREFERENCE = ${_CURDIR}/${.MAKE.DEPENDFILE:T}
.if ${.MAKE.DEPENDFILE:E} == "${TARGET_SPEC}" .if ${.MAKE.DEPENDFILE:E} == "${TARGET_SPEC}"
.if ${TARGET_SPEC} != ${MACHINE} .if ${TARGET_SPEC} != ${MACHINE}
@ -118,12 +174,12 @@ TARGET_SPEC = ${TARGET_SPEC_VARS:@v@${$v:U}@:ts,}
.endif .endif
_default_dependfile := ${.MAKE.DEPENDFILE_PREFERENCE:[1]:T} _default_dependfile := ${.MAKE.DEPENDFILE_PREFERENCE:[1]:T}
_machine_dependfiles := ${.MAKE.DEPENDFILE_PREFERENCE:M*.${TARGET_SPEC}} \ _machine_dependfiles := ${.MAKE.DEPENDFILE_PREFERENCE:T:M*${MACHINE}*}
${.MAKE.DEPENDFILE_PREFERENCE:M*.${MACHINE}}
# for machine specific dependfiles we require ${MACHINE} to be at the end # for machine specific dependfiles we require ${MACHINE} to be at the end
# also for the sake of sanity we require a common prefix # also for the sake of sanity we require a common prefix
.if !defined(.MAKE.DEPENDFILE_PREFIX) .if !defined(.MAKE.DEPENDFILE_PREFIX)
# knowing .MAKE.DEPENDFILE_PREFIX helps
.if !empty(_machine_dependfiles) .if !empty(_machine_dependfiles)
.MAKE.DEPENDFILE_PREFIX := ${_machine_dependfiles:[1]:T:R} .MAKE.DEPENDFILE_PREFIX := ${_machine_dependfiles:[1]:T:R}
.else .else
@ -133,24 +189,45 @@ _machine_dependfiles := ${.MAKE.DEPENDFILE_PREFERENCE:M*.${TARGET_SPEC}} \
# this is how we identify non-machine specific dependfiles # this is how we identify non-machine specific dependfiles
N_notmachine := ${.MAKE.DEPENDFILE_PREFERENCE:E:N${TARGET_SPEC}:N${MACHINE}:${M_ListToSkip}} N_notmachine := ${.MAKE.DEPENDFILE_PREFERENCE:E:N*${MACHINE}*:${M_ListToSkip}}
.endif # !target(_DIRDEP_USE) .endif # !target(_DIRDEP_USE)
# if we were included recursively _DEP_TARGET_SPEC should be valid.
.if empty(_DEP_TARGET_SPEC)
# we may or may not have included a dependfile yet
_last_dependfile := ${.MAKE.MAKEFILES:M*/${.MAKE.DEPENDFILE_PREFIX}*:[-1]} _last_dependfile := ${.MAKE.MAKEFILES:M*/${.MAKE.DEPENDFILE_PREFIX}*:[-1]}
.if !empty(_debug_reldir)
.info ${DEP_RELDIR}.${DEP_TARGET_SPEC}: _last_dependfile='${_last_dependfile}'
.endif
# Note: if a makefile is read many times, the above .if empty(_last_dependfile) || ${_last_dependfile:E:${N_notmachine}} == ""
# will not work, so we also test for DEP_MACHINE==depend below. # this is all we have to work with
.if empty(_last_dependfile) DEP_MACHINE = ${TARGET_MACHINE:U${MACHINE}}
# we haven't included one yet _DEP_TARGET_SPEC := ${DEP_TARGET_SPEC}
DEP_MACHINE ?= ${TARGET_MACHINE:U${TARGET_SPEC}}
# else it should be correctly set by ${.MAKE.DEPENDFILE}
.elif ${_last_dependfile:E:${N_notmachine}} == "" || ${DEP_MACHINE:Uno:${N_notmachine}} == ""
# don't rely on manually maintained files to be correct
DEP_MACHINE := ${_DEP_MACHINE:U${TARGET_SPEC}}
.else .else
# just in case _DEP_TARGET_SPEC = ${_last_dependfile:${M_dep_qual_fixes:ts:}:E}
DEP_MACHINE ?= ${_last_dependfile:E} .endif
.if !empty(_last_dependfile)
# record that we've read dependfile for this
_DIRDEP_CHECKED += ${_CURDIR}.${TARGET_SPEC}
.endif
.endif
# by now _DEP_TARGET_SPEC should be set, parse it.
.if ${TARGET_SPEC_VARS:[#]} > 1
# we need to parse DEP_MACHINE may or may not contain more info
_tspec := ${_DEP_TARGET_SPEC:S/,/ /g}
.for i in ${_tspec_x}
DEP_${TARGET_SPEC_VARS:[$i]} := ${_tspec:[$i]}
.endfor
.for v in ${TARGET_SPEC_VARS:O:u}
.if empty(DEP_$v)
.undef DEP_$v
.endif
.endfor
.else
DEP_MACHINE := ${_DEP_TARGET_SPEC}
.endif .endif
# pickup customizations # pickup customizations
@ -179,17 +256,18 @@ _DEP_RELDIR := ${DEP_RELDIR}
SKIP_HOSTDIR ?= SKIP_HOSTDIR ?=
NSkipHostDir = ${SKIP_HOSTDIR:N*.host:S,$,.host,:N.host:${M_ListToSkip}} NSkipHostDir = ${SKIP_HOSTDIR:N*.host:S,$,.host,:N.host:${M_ListToSkip}}
NSkipHostDep = ${SKIP_HOSTDIR:R:@d@*/$d*.host@:${M_ListToSkip}}
# things we always skip # things we always skip
# SKIP_DIRDEPS allows for adding entries on command line. # SKIP_DIRDEPS allows for adding entries on command line.
SKIP_DIR += .host *.WAIT ${SKIP_DIRDEPS} SKIP_DIR += .host *.WAIT ${SKIP_DIRDEPS}
SKIP_DIR.host += ${SKIP_HOSTDIR}
.ifdef HOSTPROG DEP_SKIP_DIR = ${SKIP_DIR} \
SKIP_DIR += ${SKIP_HOSTDIR} ${SKIP_DIR.${DEP_TARGET_SPEC}:U} \
.endif ${SKIP_DIR.${DEP_MACHINE}:U} \
${SKIP_DIRDEPS.${DEP_MACHINE}:U}
NSkipDir = ${SKIP_DIR:${M_ListToSkip}} NSkipDir = ${DEP_SKIP_DIR:${M_ListToSkip}}
.if defined(NO_DIRDEPS) || defined(NODIRDEPS) .if defined(NO_DIRDEPS) || defined(NODIRDEPS)
# confine ourselves to the original dir # confine ourselves to the original dir
@ -198,12 +276,15 @@ DIRDEPS_FILTER += M${_DEP_RELDIR}*
# we supress SUBDIR when visiting the leaves # we supress SUBDIR when visiting the leaves
# we assume sys.mk will set MACHINE_ARCH # we assume sys.mk will set MACHINE_ARCH
# you can add extras to DIRDEP_USE_ENV
# if there is no makefile in the target directory, we skip it.
_DIRDEP_USE: .USE .MAKE _DIRDEP_USE: .USE .MAKE
@for m in ${.MAKE.MAKEFILE_PREFERENCE}; do \ @for m in ${.MAKE.MAKEFILE_PREFERENCE}; do \
test -s ${.TARGET:R}/$$m || continue; \ test -s ${.TARGET:R}/$$m || continue; \
echo "${TRACER}Checking ${.TARGET:R} for ${.TARGET:E} ..."; \ echo "${TRACER}Checking ${.TARGET:R} for ${.TARGET:E} ..."; \
MACHINE_ARCH= NO_SUBDIR=1 ${DIRDEP_USE_ENV} \
TARGET_SPEC=${.TARGET:E} \ TARGET_SPEC=${.TARGET:E} \
MACHINE=${.TARGET:E} MACHINE_ARCH= NO_SUBDIR=1 \ MACHINE=${.TARGET:E} \
${.MAKE} -C ${.TARGET:R} || exit 1; \ ${.MAKE} -C ${.TARGET:R} || exit 1; \
break; \ break; \
done done
@ -260,7 +341,7 @@ _this_dir := ${SRCTOP}/${DEP_RELDIR}
_dep_hack := ${_this_dir}/${.MAKE.DEPENDFILE_PREFIX}.inc _dep_hack := ${_this_dir}/${.MAKE.DEPENDFILE_PREFIX}.inc
.-include "${_dep_hack}" .-include "${_dep_hack}"
.if ${DEP_RELDIR} != ${_DEP_RELDIR} || ${DEP_MACHINE} != ${TARGET_SPEC} .if ${DEP_RELDIR} != ${_DEP_RELDIR} || ${DEP_TARGET_SPEC} != ${TARGET_SPEC}
# this should be all # this should be all
_machines := ${DEP_MACHINE} _machines := ${DEP_MACHINE}
.else .else
@ -275,17 +356,23 @@ _machines += host
_machines := ${_machines:O:u} _machines := ${_machines:O:u}
.endif .endif
# reset these each time through .if ${TARGET_SPEC_VARS:[#]} > 1
# we need to tweak _machines
_dm := ${DEP_MACHINE}
_machines := ${_machines:@DEP_MACHINE@${DEP_TARGET_SPEC}@}
DEP_MACHINE := ${_dm}
.endif
# reset each time through
_build_dirs = _build_dirs =
_depdir_files =
.if ${DEP_RELDIR} == ${_DEP_RELDIR} .if ${DEP_RELDIR} == ${_DEP_RELDIR}
# pickup other machines for this dir if necessary # pickup other machines for this dir if necessary
.if ${BUILD_AT_LEVEL0:Uyes} == "no" .if ${BUILD_AT_LEVEL0:Uyes} == "no"
_build_dirs += ${_machines:@m@${_CURDIR}.$m@} _build_dirs += ${_machines:@m@${_CURDIR}.$m@}
.else .else
_build_dirs += ${_machines:N${DEP_MACHINE}:@m@${_CURDIR}.$m@} _build_dirs += ${_machines:N${DEP_TARGET_SPEC}:@m@${_CURDIR}.$m@}
.if ${DEP_MACHINE} == ${TARGET_SPEC} .if ${DEP_TARGET_SPEC} == ${TARGET_SPEC}
# pickup local dependencies now # pickup local dependencies now
.-include <.depend> .-include <.depend>
.endif .endif
@ -293,15 +380,23 @@ _build_dirs += ${_machines:N${DEP_MACHINE}:@m@${_CURDIR}.$m@}
.endif .endif
.if !empty(_debug_reldir) .if !empty(_debug_reldir)
.info ${DEP_RELDIR}.${DEP_MACHINE}: _last_dependfile='${_last_dependfile}' .info ${DEP_RELDIR}.${DEP_TARGET_SPEC}: DIRDEPS='${DIRDEPS}'
.info ${DEP_RELDIR}.${DEP_MACHINE}: DIRDEPS='${DIRDEPS}' .info ${DEP_RELDIR}.${DEP_TARGET_SPEC}: _machines='${_machines}'
.info ${DEP_RELDIR}.${DEP_MACHINE}: _machines='${_machines}'
.endif .endif
.if !empty(DIRDEPS) .if !empty(DIRDEPS)
# these we reset each time through as they can depend on DEP_MACHINE
DEP_DIRDEPS_FILTER = \
${DIRDEPS_FILTER.${DEP_TARGET_SPEC}:U} \
${DIRDEPS_FILTER.${DEP_MACHINE}:U} \
${DIRDEPS_FILTER:U}
.if empty(DEP_DIRDEPS_FILTER)
# something harmless
DEP_DIRDEPS_FILTER = U
.endif
# this is what we start with # this is what we start with
__depdirs := ${DIRDEPS:${NSkipDir}:${DIRDEPS_FILTER:ts:}:O:u:@d@${SRCTOP}/$d@} __depdirs := ${DIRDEPS:${NSkipDir}:${DEP_DIRDEPS_FILTER:ts:}:O:u:@d@${SRCTOP}/$d@}
# some entries may be qualified with .<machine> # some entries may be qualified with .<machine>
# the :M*/*/*.* just tries to limit the dirs we check to likely ones. # the :M*/*/*.* just tries to limit the dirs we check to likely ones.
@ -327,26 +422,8 @@ _build_dirs += \
${__qual_depdirs:N*.host} \ ${__qual_depdirs:N*.host} \
${_machines:@m@${__unqual_depdirs:@d@$d.$m@}@} ${_machines:@m@${__unqual_depdirs:@d@$d.$m@}@}
_build_dirs := ${_build_dirs:O:u} # qualify everything now
_build_dirs := ${_build_dirs:${M_dep_qual_fixes:ts:}:O:u}
# this is where we will pick up more dependencies from
# the inner inline loops look complex, but save a significant
# amount of memory compared to a .for loop.
_depdir_files =
.for d in ${_build_dirs}
.if exists($d)
# easy, we're building for ${MACHINE}
_depdir_files += ${.MAKE.DEPENDFILE_PREFERENCE:T:@m@${exists($d/$m):?$d/$m:}@:[1]}
.elif exists(${d:R}) && ${d:R:T} == ${d:T:R}
# a little more complex - building for another machine
# we will ensure the file is qualified with a machine
# so that if necessary _DEP_MACHINE can be set below
_depdir_files += ${.MAKE.DEPENDFILE_PREFERENCE:T:S,.${TARGET_SPEC}$,.${d:E},:S,.${MACHINE}$,.${d:E},:@m@${exists(${d:R}/$m):?${d:R}/$m:}@:[1]:@m@${"${m:M*.${d:E}}":?$m:$m.${d:E}}@}
.endif
.endfor
# clean up
_depdir_files := ${_depdir_files:O:u}
.endif # empty DIRDEPS .endif # empty DIRDEPS
@ -360,48 +437,57 @@ dirdeps: ${_build_dirs}
${_build_dirs}: _DIRDEP_USE ${_build_dirs}: _DIRDEP_USE
.if !empty(_debug_reldir) .if !empty(_debug_reldir)
.info ${DEP_RELDIR}.${DEP_MACHINE}: ${_build_dirs} .info ${DEP_RELDIR}.${DEP_TARGET_SPEC}: needs: ${_build_dirs}
.endif .endif
# this builds the dependency graph
.for m in ${_machines} .for m in ${_machines}
# it would be nice to do :N${.TARGET} # it would be nice to do :N${.TARGET}
.if !empty(__qual_depdirs) .if !empty(__qual_depdirs)
.for q in ${__qual_depdirs:E:O:u:N$m} .for q in ${__qual_depdirs:${M_dep_qual_fixes:ts:}:E:O:u:N$m}
.if !empty(_debug_reldir) || ${DEBUG_DIRDEPS:@x@${${DEP_RELDIR}.$m:L:M$x}${${DEP_RELDIR}.$q:L:M$x}@} != "" .if !empty(_debug_reldir) || ${DEBUG_DIRDEPS:@x@${${DEP_RELDIR}.$m:L:M$x}${${DEP_RELDIR}.$q:L:M$x}@} != ""
.info ${DEP_RELDIR}.$m: ${_build_dirs:M*.$q} .info ${DEP_RELDIR}.$m: graph: ${_build_dirs:M*.$q}
.endif .endif
${_this_dir}.$m: ${_build_dirs:M*.$q} ${_this_dir}.$m: ${_build_dirs:M*.$q}
.endfor .endfor
.endif .endif
.if !empty(_debug_reldir) .if !empty(_debug_reldir)
.info ${DEP_RELDIR}.$m: ${_build_dirs:M*.$m:N${_this_dir}.$m} .info ${DEP_RELDIR}.$m: graph: ${_build_dirs:M*.$m:N${_this_dir}.$m}
.endif .endif
${_this_dir}.$m: ${_build_dirs:M*.$m:N${_this_dir}.$m} ${_this_dir}.$m: ${_build_dirs:M*.$m:N${_this_dir}.$m}
.endfor .endfor
.endif .endif
.for d in ${_depdir_files} # Now find more dependencies - and recurse.
.if ${.MAKE.MAKEFILES:M${d}} == "" .for d in ${_build_dirs}
.if ${_DIRDEP_CHECKED:M$d} == ""
# once only
_DIRDEP_CHECKED += $d
# Note: _build_dirs is fully qualifed so d:R is always the directory
.if exists(${d:R})
# Warning: there is an assumption here that MACHINE is always
# the first entry in TARGET_SPEC_VARS.
# If TARGET_SPEC and MACHINE are insufficient, you have a problem.
_m := ${.MAKE.DEPENDFILE_PREFERENCE:T:S;${TARGET_SPEC}$;${d:E};:S;${MACHINE};${d:E:C/,.*//};:@m@${exists(${d:R}/$m):?${d:R}/$m:}@:[1]}
.if !empty(_m)
_qm := ${_m:${M_dep_qual_fixes:ts:}}
.if !empty(_debug_search) .if !empty(_debug_search)
.info Looking for $d .info Looking for ${_qm}
.endif .endif
.if exists($d) # we pass _DEP_TARGET_SPEC to tell the next step what we want
.include <$d> _DEP_TARGET_SPEC := ${d:E}
.elif exists(${d:R}) # some makefiles may still look at this
# an unqualified file exists, we qualified it above so we can set _DEP_MACHINE _DEP_MACHINE := ${d:E:C/,.*//}
# it might be manually maintained and shared by all machine types .if !empty(_debug_reldir) && ${_qm} != ${_m}
# tell it the machine we are interested in. .info loading ${_m} for ${d:E}
_DEP_MACHINE := ${d:E} .endif
.if !empty(_debug_reldir) .include <${_m}>
.info loading ${d:R} for ${_DEP_MACHINE}
.endif .endif
# pretend we read $d, so we don't come by here again.
.MAKE.MAKEFILES += $d
.include <${d:R}>
.endif .endif
.endif .endif
.endfor .endfor
.endif # -V .endif # -V
.elif ${.MAKE.LEVEL} > 42 .elif ${.MAKE.LEVEL} > 42

View File

@ -1,6 +1,7 @@
# $Id: gendirdeps.mk,v 1.10 2012/06/30 00:37:50 sjg Exp $ # $Id: gendirdeps.mk,v 1.21 2013/03/28 20:01:05 sjg Exp $
# Copyright (c) 2010, Juniper Networks, Inc. # Copyright (c) 2010-2013, Juniper Networks, Inc.
# All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions # modification, are permitted provided that the following conditions
@ -50,7 +51,12 @@ _CURDIR ?= ${.CURDIR}
_OBJDIR ?= ${.OBJDIR} _OBJDIR ?= ${.OBJDIR}
_OBJTOP ?= ${OBJTOP} _OBJTOP ?= ${OBJTOP}
_OBJROOT ?= ${OBJROOT:U${_OBJTOP}} _OBJROOT ?= ${OBJROOT:U${_OBJTOP}}
_objroot ?= ${_OBJROOT:tA} .if ${_OBJROOT:M*/}
_slash=/
.else
_slash=
.endif
_objroot ?= ${_OBJROOT:tA}${_slash}
_this = ${.PARSEDIR}/${.PARSEFILE} _this = ${.PARSEDIR}/${.PARSEFILE}
@ -106,25 +112,26 @@ _py_d =
# we can afford to do this all the time. # we can afford to do this all the time.
DPDEPS ?= no DPDEPS ?= no
META2DEPS_CMD = ${_time} ${PYTHON} ${META2DEPS} ${_py_d} \ META2DEPS_CMD = ${_time} ${PYTHON} ${META2DEPS} ${_py_d} \
-R ${RELDIR} -H ${HOST_TARGET} -O ${M2D_OBJROOT} -R ${RELDIR} -H ${HOST_TARGET} \
${M2D_OBJROOTS:O:u:@o@-O $o@}
.if ${DPDEPS:tl} != "no" .if ${DPDEPS:tl} != "no"
META2DEPS_CMD += -D ${DPDEPS} META2DEPS_CMD += -D ${DPDEPS}
.endif .endif
M2D_OBJROOTS += ${OBJTOP} ${_OBJROOT} ${_objroot}
.if defined(SB_OBJROOT)
M2D_OBJROOTS += ${SB_OBJROOT}
.endif
.if ${.MAKE.DEPENDFILE_PREFERENCE:U${.MAKE.DEPENDFILE}:M*.${MACHINE}} == "" .if ${.MAKE.DEPENDFILE_PREFERENCE:U${.MAKE.DEPENDFILE}:M*.${MACHINE}} == ""
# meta2deps.py only groks objroot # meta2deps.py only groks objroot
# so we need to give it what it expects # so we need to give it what it expects
M2D_OBJROOT = ${OBJTOP}/
# and tell it not to add machine qualifiers # and tell it not to add machine qualifiers
META2DEPS_ARGS += MACHINE=none META2DEPS_ARGS += MACHINE=none
.else
.if defined(SB_OBJROOT)
M2D_OBJROOT ?= ${SB_OBJROOT}
.else
M2D_OBJROOT = ${OBJTOP}/
.endif
.endif .endif
.if defined(SB_BACKING_SB) .if defined(SB_BACKING_SB)
META2DEPS_CMD += -S ${SB_BACKING_SB}/src -O ${SB_BACKING_SB}/${SB_OBJPREFIX} META2DEPS_CMD += -S ${SB_BACKING_SB}/src
M2D_OBJROOTS += ${SB_BACKING_SB}/${SB_OBJPREFIX}
.endif .endif
META2DEPS_FILTER = sed 's,^src:,${SRCTOP}/,;s,^\([^/]\),${OBJTOP}/\1,' | META2DEPS_FILTER = sed 's,^src:,${SRCTOP}/,;s,^\([^/]\),${OBJTOP}/\1,' |
.elif ${META2DEPS:E} == "sh" .elif ${META2DEPS:E} == "sh"
@ -155,7 +162,26 @@ dir_list != cd ${_OBJDIR} && \
.if !empty(DPADD) .if !empty(DPADD)
_nonlibs := ${DPADD:T:Nlib*:N*include} _nonlibs := ${DPADD:T:Nlib*:N*include}
.if !empty(_nonlibs) .if !empty(_nonlibs)
dir_list += ${_nonlibs:@x@${DPADD:M*/$x}@:H:tA} ddep_list =
.for f in ${_nonlibs:@x@${DPADD:M*/$x}@}
.if exists($f.dirdep)
ddep_list += $f.dirdep
.elif exists(${f:H}.dirdep)
ddep_list += ${f:H}.dirdep
.else
dir_list += ${f:H:tA}
.endif
.endfor
.if !empty(ddep_list)
ddeps != cat ${ddep_list:O:u} | ${META2DEPS_FILTER} ${_skip_gendirdeps} \
sed 's,//*$$,,;s,\.${HOST_TARGET}$$,.host,;s,\.${MACHINE}$$,,'
.if ${DEBUG_GENDIRDEPS:Uno:@x@${RELDIR:M$x}@} != ""
.info ${RELDIR}: raw_dir_list='${dir_list}'
.info ${RELDIR}: ddeps='${ddeps}'
.endif
dir_list += ${ddeps}
.endif
.endif .endif
.endif .endif
@ -167,26 +193,28 @@ dir_list += ${_nonlibs:@x@${DPADD:M*/$x}@:H:tA}
# so we add # so we add
# ${"${dir_list:M*bsd/sys/${MACHINE_ARCH}/include}":?bsd/include:} # ${"${dir_list:M*bsd/sys/${MACHINE_ARCH}/include}":?bsd/include:}
# to GENDIRDEPS_DIR_LIST_XTRAS # to GENDIRDEPS_DIR_LIST_XTRAS
_objtops = ${OBJTOP} ${_OBJTOP} ${_obtop}
_objtops := ${_objtops:O:u}
dirdep_list = \ dirdep_list = \
${dir_list:M${_objtop}*/*:C,${_objtop}[^/]*/,,} \ ${_objtops:@o@${dir_list:M$o*/*:C,$o[^/]*/,,}@} \
${GENDIRDEPS_DIR_LIST_XTRAS} ${GENDIRDEPS_DIR_LIST_XTRAS}
# sort longest first
M2D_OBJROOTS := ${M2D_OBJROOTS:O:u:[-1..1]}
# anything we use from an object dir other than ours # anything we use from an object dir other than ours
# needs to be qualified with its .<machine> suffix # needs to be qualified with its .<machine> suffix
# (we used the pseudo machine "host" for the HOST_TARGET). # (we used the pseudo machine "host" for the HOST_TARGET).
qualdir_list = \ skip_ql= ${SRCTOP}* ${_objtops:@o@$o*@}
${dir_list:M${_objroot}*/*/*:N${SRCTOP}*:N${_objtop}*:C,${_objroot}([^/]+)/(.*),\2.\1,:S,.${HOST_TARGET},.host,} .for o in ${M2D_OBJROOTS:${skip_ql:${M_ListToSkip}}}
# we need := so only skip_ql to this point applies
.if ${_OBJROOT} != ${_objroot} ql := ${dir_list:${skip_ql:${M_ListToSkip}}:M$o*/*/*:C,$o([^/]+)/(.*),\2.\1,:S,.${HOST_TARGET},.host,}
dirdep_list += \ qualdir_list += ${ql}
${dir_list:M${_OBJTOP}*/*:C,${_OBJTOP}[^/]*/,,} skip_ql+= $o*
.endfor
qualdir_list += \
${dir_list:M${_OBJROOT}*/*/*:N${SRCTOP}*:N${_OBJTOP}*:C,${_OBJROOT}([^/]+)/(.*),\2.\1,:S,.${HOST_TARGET},.host,}
.endif
dirdep_list := ${dirdep_list:O:u} dirdep_list := ${dirdep_list:O:u}
qualdir_list := ${qualdir_list:O:u} qualdir_list := ${qualdir_list:N*.${MACHINE}:O:u}
DIRDEPS = \ DIRDEPS = \
${dirdep_list:N${RELDIR}:N${RELDIR}/*} \ ${dirdep_list:N${RELDIR}:N${RELDIR}/*} \
@ -207,6 +235,7 @@ DIRDEPS += \
DIRDEPS := ${DIRDEPS:${GENDIRDEPS_FILTER:UNno:ts:}:O:u} DIRDEPS := ${DIRDEPS:${GENDIRDEPS_FILTER:UNno:ts:}:O:u}
.if ${DEBUG_GENDIRDEPS:Uno:@x@${RELDIR:M$x}@} != "" .if ${DEBUG_GENDIRDEPS:Uno:@x@${RELDIR:M$x}@} != ""
.info ${RELDIR}: M2D_OBJROOTS=${M2D_OBJROOTS}
.info ${RELDIR}: dir_list='${dir_list}' .info ${RELDIR}: dir_list='${dir_list}'
.info ${RELDIR}: dirdep_list='${dirdep_list}' .info ${RELDIR}: dirdep_list='${dirdep_list}'
.info ${RELDIR}: qualdir_list='${qualdir_list}' .info ${RELDIR}: qualdir_list='${qualdir_list}'
@ -263,7 +292,6 @@ CAT_DEPEND ?= .depend
${_DEPENDFILE}: ${CAT_DEPEND:M.depend} ${META_FILES:O:u:@m@${exists($m):?$m:}@} ${_this} ${META2DEPS} ${_DEPENDFILE}: ${CAT_DEPEND:M.depend} ${META_FILES:O:u:@m@${exists($m):?$m:}@} ${_this} ${META2DEPS}
@(echo '# Autogenerated - do NOT edit!'; echo; \ @(echo '# Autogenerated - do NOT edit!'; echo; \
echo 'DEP_RELDIR := $${_PARSEDIR:S,$${SRCTOP}/,,}'; echo; \ echo 'DEP_RELDIR := $${_PARSEDIR:S,$${SRCTOP}/,,}'; echo; \
echo 'DEP_MACHINE := $${.PARSEFILE:E}'; echo; \
echo 'DIRDEPS = \'; \ echo 'DIRDEPS = \'; \
echo '${DIRDEPS:@d@ $d \\${.newline}@}'; echo; \ echo '${DIRDEPS:@d@ $d \\${.newline}@}'; echo; \
${_include_src_dirdeps} \ ${_include_src_dirdeps} \
@ -285,7 +313,6 @@ all: ${_DEPENDFILE}
${_DEPENDFILE}: ${MAKEFILE} ${_this} ${_DEPENDFILE}: ${MAKEFILE} ${_this}
@(echo '# Autogenerated - do NOT edit!'; echo; \ @(echo '# Autogenerated - do NOT edit!'; echo; \
echo 'DEP_RELDIR := $${_PARSEDIR:S,$${SRCTOP}/,,}'; echo; \ echo 'DEP_RELDIR := $${_PARSEDIR:S,$${SRCTOP}/,,}'; echo; \
echo 'DEP_MACHINE := $${.PARSEFILE:E}'; echo; \
echo 'DIRDEPS = \'; \ echo 'DIRDEPS = \'; \
echo '${DIRDEPS:@d@ $d \\${.newline}@}'; echo; \ echo '${DIRDEPS:@d@ $d \\${.newline}@}'; echo; \
echo '.include <dirdeps.mk>'; \ echo '.include <dirdeps.mk>'; \

View File

@ -55,7 +55,7 @@
# Simon J. Gerraty <sjg@crufty.net> # Simon J. Gerraty <sjg@crufty.net>
# RCSid: # RCSid:
# $Id: install-mk,v 1.83 2013/01/24 01:02:23 sjg Exp $ # $Id: install-mk,v 1.88 2013/03/31 22:31:59 sjg Exp $
# #
# @(#) Copyright (c) 1994 Simon J. Gerraty # @(#) Copyright (c) 1994 Simon J. Gerraty
# #
@ -70,7 +70,7 @@
# sjg@crufty.net # sjg@crufty.net
# #
MK_VERSION=20130123 MK_VERSION=20130330
OWNER= OWNER=
GROUP= GROUP=
MODE=444 MODE=444

View File

@ -1,4 +1,4 @@
# $Id: meta.stage.mk,v 1.17 2013/01/24 01:02:23 sjg Exp $ # $Id: meta.stage.mk,v 1.24 2013/03/23 02:25:19 sjg Exp $
# #
# @(#) Copyright (c) 2011, Simon J. Gerraty # @(#) Copyright (c) 2011, Simon J. Gerraty
# #
@ -48,37 +48,39 @@ GENDIRDEPS_FILTER += Nnot-empty-is-important \
${_STAGED_DIRS:O:u:M${OBJTOP}*:S,${OBJTOP}/,N,} \ ${_STAGED_DIRS:O:u:M${OBJTOP}*:S,${OBJTOP}/,N,} \
${_STAGED_DIRS:O:u:N${OBJTOP}*:S,${_objroot},,:C,^([^/]+)/(.*),N\2.\1,:S,${HOST_TARGET},.host,} ${_STAGED_DIRS:O:u:N${OBJTOP}*:S,${_objroot},,:C,^([^/]+)/(.*),N\2.\1,:S,${HOST_TARGET},.host,}
LN_CP_SCRIPT = LnCp() { \
rm -f $$2 2> /dev/null; \
ln $$1 $$2 2> /dev/null || \
cp -p $$1 $$2; }
# it is an error for more than one src dir to try and stage # it is an error for more than one src dir to try and stage
# the same file # the same file
STAGE_DIRDEP_SCRIPT = StageDirdep() { \ STAGE_DIRDEP_SCRIPT = ${LN_CP_SCRIPT}; StageDirdep() { \
t=$$1; \ t=$$1; \
if [ -s $$t.dirdep ]; then \ if [ -s $$t.dirdep ]; then \
cmp -s .dirdep $$t.dirdep && return; \ cmp -s .dirdep $$t.dirdep && return; \
echo "ERROR: $$t installed by `cat $$t.dirdep` not ${_dirdep}" >&2; \ echo "ERROR: $$t installed by `cat $$t.dirdep` not ${_dirdep}" >&2; \
exit 1; \ exit 1; \
fi; \ fi; \
ln .dirdep $$t.dirdep 2> /dev/null || \ LnCp .dirdep $$t.dirdep || exit 1; }
cp .dirdep $$t.dirdep; }
# common logic for staging files # common logic for staging files
# this all relies on RELDIR being set to a subdir of SRCTOP # this all relies on RELDIR being set to a subdir of SRCTOP
# we use ln(1) if we can, else cp(1) # we use ln(1) if we can, else cp(1)
STAGE_FILE_SCRIPT = ${STAGE_DIRDEP_SCRIPT}; StageFiles() { \ STAGE_FILE_SCRIPT = ${STAGE_DIRDEP_SCRIPT}; StageFiles() { \
case "$$1" in -m) mode=$$2; shift 2;; *) mode=;; esac; \ case "$$1" in "") return;; -m) mode=$$2; shift 2;; *) mode=;; esac; \
dest=$$1; shift; \ dest=$$1; shift; \
mkdir -p $$dest; \ mkdir -p $$dest; \
[ -s .dirdep ] || echo '${_dirdep}' > .dirdep; \ [ -s .dirdep ] || echo '${_dirdep}' > .dirdep; \
for f in "$$@"; do \ for f in "$$@"; do \
case "$$f" in */*) t=$$dest/${_stage_file_basename};; *) t=$$dest/$$f;; esac; \ case "$$f" in */*) t=$$dest/${_stage_file_basename};; *) t=$$dest/$$f;; esac; \
StageDirdep $$t; \ StageDirdep $$t; \
rm -f $$t; \ LnCp $$f $$t || exit 1; \
{ ln $$f $$t 2> /dev/null || \ [ -z "$$mode" ] || chmod $$mode $$t; \
cp -p $$f $$t; }; \
$${mode:+chmod $$mode $$t}; \
done; :; } done; :; }
STAGE_LINKS_SCRIPT = ${STAGE_DIRDEP_SCRIPT}; StageLinks() { \ STAGE_LINKS_SCRIPT = ${STAGE_DIRDEP_SCRIPT}; StageLinks() { \
case "$$1" in --) shift;; -*) ldest= lnf=$$1; shift;; /*) ldest=$$1/;; esac; \ case "$$1" in "") return;; --) shift;; -*) ldest= lnf=$$1; shift;; /*) ldest=$$1/;; esac; \
dest=$$1; shift; \ dest=$$1; shift; \
mkdir -p $$dest; \ mkdir -p $$dest; \
[ -s .dirdep ] || echo '${_dirdep}' > .dirdep; \ [ -s .dirdep ] || echo '${_dirdep}' > .dirdep; \
@ -89,11 +91,11 @@ STAGE_LINKS_SCRIPT = ${STAGE_DIRDEP_SCRIPT}; StageLinks() { \
shift; \ shift; \
StageDirdep $$t; \ StageDirdep $$t; \
rm -f $$t 2>/dev/null; \ rm -f $$t 2>/dev/null; \
ln $$lnf $$l $$t; \ ln $$lnf $$l $$t || exit 1; \
done; :; } done; :; }
STAGE_AS_SCRIPT = ${STAGE_DIRDEP_SCRIPT}; StageAs() { \ STAGE_AS_SCRIPT = ${STAGE_DIRDEP_SCRIPT}; StageAs() { \
case "$$1" in -m) mode=$$2; shift 2;; *) mode=;; esac; \ case "$$1" in "") return;; -m) mode=$$2; shift 2;; *) mode=;; esac; \
dest=$$1; shift; \ dest=$$1; shift; \
mkdir -p $$dest; \ mkdir -p $$dest; \
[ -s .dirdep ] || echo '${_dirdep}' > .dirdep; \ [ -s .dirdep ] || echo '${_dirdep}' > .dirdep; \
@ -103,10 +105,8 @@ STAGE_AS_SCRIPT = ${STAGE_DIRDEP_SCRIPT}; StageAs() { \
case "$$1" in */*) mkdir -p ${_stage_target_dirname};; esac; \ case "$$1" in */*) mkdir -p ${_stage_target_dirname};; esac; \
shift; \ shift; \
StageDirdep $$t; \ StageDirdep $$t; \
rm -f $$t; \ LnCp $$s $$t || exit 1; \
{ ln $$s $$t 2> /dev/null || \ [ -z "$$mode" ] || chmod $$mode $$t; \
cp -p $$s $$t; }; \
$${mode:+chmod $$mode $$t}; \
done; :; } done; :; }
# this is simple, a list of the "staged" files depends on this, # this is simple, a list of the "staged" files depends on this,
@ -114,8 +114,7 @@ _STAGE_BASENAME_USE: .USE ${.TARGET:T}
@${STAGE_FILE_SCRIPT}; StageFiles ${.TARGET:H:${STAGE_DIR_FILTER}} ${.TARGET:T} @${STAGE_FILE_SCRIPT}; StageFiles ${.TARGET:H:${STAGE_DIR_FILTER}} ${.TARGET:T}
.if !empty(STAGE_INCSDIR) .if !empty(STAGE_INCSDIR)
CLEANFILES += stage_incs STAGE_TARGETS += stage_incs
STAGE_INCS ?= ${.ALLSRC:N.dirdep} STAGE_INCS ?= ${.ALLSRC:N.dirdep}
stage_incs: .dirdep stage_incs: .dirdep
@ -124,7 +123,7 @@ stage_incs: .dirdep
.endif .endif
.if !empty(STAGE_LIBDIR) .if !empty(STAGE_LIBDIR)
CLEANFILES += stage_libs STAGE_TARGETS += stage_libs
STAGE_LIBS ?= ${.ALLSRC:N.dirdep} STAGE_LIBS ?= ${.ALLSRC:N.dirdep}
@ -152,7 +151,6 @@ STAGE_SYMLINKS ?= ${.ALLSRC:T:N.dirdep:Nstage_*}
.endif .endif
.if !empty(STAGE_SETS) .if !empty(STAGE_SETS)
CLEANFILES += ${STAGE_SETS:@s@stage*$s@} CLEANFILES += ${STAGE_SETS:@s@stage*$s@}
# some makefiles need to populate multiple directories # some makefiles need to populate multiple directories
@ -162,6 +160,7 @@ STAGE_SYMLINKS.$s ?= ${.ALLSRC:N.dirdep}
STAGE_LINKS_DIR.$s ?= ${STAGE_OBJTOP} STAGE_LINKS_DIR.$s ?= ${STAGE_OBJTOP}
STAGE_SYMLINKS_DIR.$s ?= ${STAGE_OBJTOP} STAGE_SYMLINKS_DIR.$s ?= ${STAGE_OBJTOP}
STAGE_TARGETS += stage_files
.if $s != "_default" .if $s != "_default"
stage_files: stage_files.$s stage_files: stage_files.$s
stage_files.$s: .dirdep stage_files.$s: .dirdep
@ -171,6 +170,7 @@ stage_files: .dirdep
@${STAGE_FILE_SCRIPT}; StageFiles ${FLAGS.$@} ${STAGE_FILES_DIR.$s:U${STAGE_DIR.$s}:${STAGE_DIR_FILTER}} ${STAGE_FILES.$s} @${STAGE_FILE_SCRIPT}; StageFiles ${FLAGS.$@} ${STAGE_FILES_DIR.$s:U${STAGE_DIR.$s}:${STAGE_DIR_FILTER}} ${STAGE_FILES.$s}
@touch $@ @touch $@
STAGE_TARGETS += stage_links
.if $s != "_default" .if $s != "_default"
stage_links: stage_links.$s stage_links: stage_links.$s
stage_links.$s: .dirdep stage_links.$s: .dirdep
@ -180,6 +180,7 @@ stage_links: .dirdep
@${STAGE_LINKS_SCRIPT}; StageLinks ${STAGE_LINKS_DIR.$s:U${STAGE_DIR.$s}:${STAGE_DIR_FILTER}} ${STAGE_LINKS.$s} @${STAGE_LINKS_SCRIPT}; StageLinks ${STAGE_LINKS_DIR.$s:U${STAGE_DIR.$s}:${STAGE_DIR_FILTER}} ${STAGE_LINKS.$s}
@touch $@ @touch $@
STAGE_TARGETS += stage_symlinks
.if $s != "_default" .if $s != "_default"
stage_symlinks: stage_symlinks.$s stage_symlinks: stage_symlinks.$s
stage_symlinks.$s: .dirdep stage_symlinks.$s: .dirdep
@ -195,6 +196,8 @@ stage_symlinks: .dirdep
.if !empty(STAGE_AS_SETS) .if !empty(STAGE_AS_SETS)
CLEANFILES += ${STAGE_AS_SETS:@s@stage*$s@} CLEANFILES += ${STAGE_AS_SETS:@s@stage*$s@}
STAGE_TARGETS += stage_as
# sometimes things need to be renamed as they are staged # sometimes things need to be renamed as they are staged
# each ${file} will be staged as ${STAGE_AS_${file:T}} # each ${file} will be staged as ${STAGE_AS_${file:T}}
# one could achieve the same with SYMLINKS # one could achieve the same with SYMLINKS
@ -209,4 +212,20 @@ stage_as.$s: .dirdep
.endfor .endfor
.endif .endif
CLEANFILES += ${STAGE_TARGETS}
# stage_*links usually needs to follow any others.
.for t in ${STAGE_TARGETS:N*links:O:u}
.ORDER: $t stage_links
.ORDER: $t stage_symlinks
.endfor
# make sure this exists
staging:
# generally we want staging to wait until everything else is done
STAGING_WAIT ?= .WAIT
all: ${STAGING_WAIT} staging
.endif .endif

View File

@ -35,9 +35,10 @@
""" """
RCSid: RCSid:
$Id: meta2deps.py,v 1.7 2012/11/06 05:44:03 sjg Exp $ $Id: meta2deps.py,v 1.12 2013/03/31 22:31:59 sjg Exp $
Copyright (c) 2011, Juniper Networks, Inc. Copyright (c) 2011-2013, Juniper Networks, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -149,6 +150,7 @@ def __init__(self, name, conf={}):
MACHINE the machine we built for. MACHINE the machine we built for.
set to 'none' if we are not cross-building. set to 'none' if we are not cross-building.
More specifically if machine cannot be deduced from objdirs.
HOST_TARGET HOST_TARGET
when we build for the psuedo machine 'host' when we build for the psuedo machine 'host'
@ -174,6 +176,11 @@ def __init__(self, name, conf={}):
self.debug = getv(conf, 'debug', 0) self.debug = getv(conf, 'debug', 0)
self.debug_out = getv(conf, 'debug_out', sys.stderr) self.debug_out = getv(conf, 'debug_out', sys.stderr)
self.machine = getv(conf, 'MACHINE', '')
self.curdir = getv(conf, 'CURDIR')
self.reldir = getv(conf, 'RELDIR')
self.dpdeps = getv(conf, 'DPDEPS')
if not self.conf: if not self.conf:
# some of the steps below we want to do only once # some of the steps below we want to do only once
self.conf = conf self.conf = conf
@ -189,7 +196,24 @@ def __init__(self, name, conf={}):
if not _srctop in self.srctops: if not _srctop in self.srctops:
self.srctops.append(_srctop) self.srctops.append(_srctop)
trim_list = ['/' + self.machine + '/',
'/' + self.machine,
self.machine + '/',
self.machine]
if self.machine == 'host':
trim_list += ['/' + self.host_target + '/',
'/' + self.host_target,
self.host_target + '/',
self.host_target]
for objroot in getv(conf, 'OBJROOTS', []): for objroot in getv(conf, 'OBJROOTS', []):
for e in trim_list:
if objroot.endswith(e):
# this is not what we want - fix it
objroot = objroot[0:-len(e)]
if e.endswith('/'):
objroot += '/'
if not objroot in self.objroots: if not objroot in self.objroots:
self.objroots.append(objroot) self.objroots.append(objroot)
_objroot = os.path.realpath(objroot) _objroot = os.path.realpath(objroot)
@ -198,6 +222,10 @@ def __init__(self, name, conf={}):
if not _objroot in self.objroots: if not _objroot in self.objroots:
self.objroots.append(_objroot) self.objroots.append(_objroot)
# we want the longest match
self.srctops.sort(reverse=True)
self.objroots.sort(reverse=True)
if self.debug: if self.debug:
print >> self.debug_out, "host_target=", self.host_target print >> self.debug_out, "host_target=", self.host_target
print >> self.debug_out, "srctops=", self.srctops print >> self.debug_out, "srctops=", self.srctops
@ -205,10 +233,6 @@ def __init__(self, name, conf={}):
self.dirdep_re = re.compile(r'([^/]+)/(.+)') self.dirdep_re = re.compile(r'([^/]+)/(.+)')
self.curdir = getv(conf, 'CURDIR')
self.machine = getv(conf, 'MACHINE', '')
self.reldir = getv(conf, 'RELDIR')
self.dpdeps = getv(conf, 'DPDEPS')
if self.dpdeps and not self.reldir: if self.dpdeps and not self.reldir:
if self.debug: if self.debug:
print >> self.debug_out, "need reldir:", print >> self.debug_out, "need reldir:",
@ -221,6 +245,8 @@ def __init__(self, name, conf={}):
if not self.reldir: if not self.reldir:
self.dpdeps = None # we cannot do it? self.dpdeps = None # we cannot do it?
self.cwd = os.getcwd() # make sure this is initialized
if name: if name:
self.parse() self.parse()

View File

@ -77,9 +77,10 @@
# RCSid: # RCSid:
# $Id: meta2deps.sh,v 1.4 2012/11/07 06:55:21 sjg Exp $ # $Id: meta2deps.sh,v 1.5 2013/02/10 19:21:46 sjg Exp $
# Copyright (c) 2010, Juniper Networks, Inc. # Copyright (c) 2010-2012, Juniper Networks, Inc.
# All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions # modification, are permitted provided that the following conditions

View File

@ -1,4 +1,4 @@
# $Id: sys.dependfile.mk,v 1.4 2012/11/08 18:31:42 sjg Exp $ # $Id: sys.dependfile.mk,v 1.5 2013/03/08 00:59:21 sjg Exp $
# #
# @(#) Copyright (c) 2012, Simon J. Gerraty # @(#) Copyright (c) 2012, Simon J. Gerraty
# #
@ -25,16 +25,20 @@
# All depend file names should start with this # All depend file names should start with this
.MAKE.DEPENDFILE_PREFIX ?= Makefile.depend .MAKE.DEPENDFILE_PREFIX ?= Makefile.depend
# The order of preference: we will use the first one of these we find # The order of preference: we will use the first one of these we find.
# otherwise the 1st entry will be used by default. # It usually makes sense to order from most specific to least.
.MAKE.DEPENDFILE_PREFERENCE ?= \ .MAKE.DEPENDFILE_PREFERENCE ?= \
${.CURDIR}/${.MAKE.DEPENDFILE_PREFIX}.${MACHINE} \ ${.CURDIR}/${.MAKE.DEPENDFILE_PREFIX}.${MACHINE} \
${.CURDIR}/${.MAKE.DEPENDFILE_PREFIX} ${.CURDIR}/${.MAKE.DEPENDFILE_PREFIX}
# Normally the 1st entry is our default choice
# Another useful default is ${.MAKE.DEPENDFILE_PREFIX}
.MAKE.DEPENDFILE_DEFAULT ?= ${.MAKE.DEPENDFILE_PREFERENCE:[1]}
_e := ${.MAKE.DEPENDFILE_PREFERENCE:@m@${exists($m):?$m:}@} _e := ${.MAKE.DEPENDFILE_PREFERENCE:@m@${exists($m):?$m:}@}
.if !empty(_e) .if !empty(_e)
.MAKE.DEPENDFILE := ${_e:[1]} .MAKE.DEPENDFILE := ${_e:[1]}
.elif ${.MAKE.DEPENDFILE_PREFERENCE:M*${MACHINE}} != "" && ${.MAKE.DEPENDFILE_PREFERENCE:[1]:E} != ${MACHINE} .elif ${.MAKE.DEPENDFILE_PREFERENCE:M*${MACHINE}} != "" && ${.MAKE.DEPENDFILE_DEFAULT:E} != ${MACHINE}
# MACHINE specific depend files are supported, but *not* default. # MACHINE specific depend files are supported, but *not* default.
# If any already exist, we should follow suit. # If any already exist, we should follow suit.
_aml = ${ALL_MACHINE_LIST:Uarm amd64 i386 powerpc:N${MACHINE}} ${MACHINE} _aml = ${ALL_MACHINE_LIST:Uarm amd64 i386 powerpc:N${MACHINE}} ${MACHINE}
@ -44,4 +48,4 @@ _e := ${_aml:@MACHINE@${.MAKE.DEPENDFILE_PREFERENCE:@m@${exists($m):?$m:}@}@}
.MAKE.DEPENDFILE ?= ${.MAKE.DEPENDFILE_PREFERENCE:M*${MACHINE}:[1]} .MAKE.DEPENDFILE ?= ${.MAKE.DEPENDFILE_PREFERENCE:M*${MACHINE}:[1]}
.endif .endif
.endif .endif
.MAKE.DEPENDFILE ?= ${.MAKE.DEPENDFILE_PREFERENCE:[1]} .MAKE.DEPENDFILE ?= ${.MAKE.DEPENDFILE_DEFAULT}

96
parse.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: parse.c,v 1.185 2012/06/12 19:21:51 joerg Exp $ */ /* $NetBSD: parse.c,v 1.188 2013/03/22 16:07:59 sjg Exp $ */
/* /*
* Copyright (c) 1988, 1989, 1990, 1993 * Copyright (c) 1988, 1989, 1990, 1993
@ -69,14 +69,14 @@
*/ */
#ifndef MAKE_NATIVE #ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: parse.c,v 1.185 2012/06/12 19:21:51 joerg Exp $"; static char rcsid[] = "$NetBSD: parse.c,v 1.188 2013/03/22 16:07:59 sjg Exp $";
#else #else
#include <sys/cdefs.h> #include <sys/cdefs.h>
#ifndef lint #ifndef lint
#if 0 #if 0
static char sccsid[] = "@(#)parse.c 8.3 (Berkeley) 3/19/94"; static char sccsid[] = "@(#)parse.c 8.3 (Berkeley) 3/19/94";
#else #else
__RCSID("$NetBSD: parse.c,v 1.185 2012/06/12 19:21:51 joerg Exp $"); __RCSID("$NetBSD: parse.c,v 1.188 2013/03/22 16:07:59 sjg Exp $");
#endif #endif
#endif /* not lint */ #endif /* not lint */
#endif #endif
@ -213,6 +213,7 @@ typedef enum {
ExShell, /* .SHELL */ ExShell, /* .SHELL */
Silent, /* .SILENT */ Silent, /* .SILENT */
SingleShell, /* .SINGLESHELL */ SingleShell, /* .SINGLESHELL */
Stale, /* .STALE */
Suffixes, /* .SUFFIXES */ Suffixes, /* .SUFFIXES */
Wait, /* .WAIT */ Wait, /* .WAIT */
Attribute /* Generic attribute */ Attribute /* Generic attribute */
@ -336,6 +337,7 @@ static const struct {
{ ".SHELL", ExShell, 0 }, { ".SHELL", ExShell, 0 },
{ ".SILENT", Silent, OP_SILENT }, { ".SILENT", Silent, OP_SILENT },
{ ".SINGLESHELL", SingleShell, 0 }, { ".SINGLESHELL", SingleShell, 0 },
{ ".STALE", Stale, 0 },
{ ".SUFFIXES", Suffixes, 0 }, { ".SUFFIXES", Suffixes, 0 },
{ ".USE", Attribute, OP_USE }, { ".USE", Attribute, OP_USE },
{ ".USEBEFORE", Attribute, OP_USEBEFORE }, { ".USEBEFORE", Attribute, OP_USEBEFORE },
@ -915,6 +917,8 @@ ParseDoOp(void *gnp, void *opp)
gn->type |= op & ~OP_OPMASK; gn->type |= op & ~OP_OPMASK;
cohort = Targ_FindNode(gn->name, TARG_NOHASH); cohort = Targ_FindNode(gn->name, TARG_NOHASH);
if (doing_depend)
ParseMark(cohort);
/* /*
* Make the cohort invisible as well to avoid duplicating it into * Make the cohort invisible as well to avoid duplicating it into
* other variables. True, parents of this target won't tend to do * other variables. True, parents of this target won't tend to do
@ -987,6 +991,8 @@ ParseDoSrc(int tOp, const char *src)
*/ */
snprintf(wait_src, sizeof wait_src, ".WAIT_%u", ++wait_number); snprintf(wait_src, sizeof wait_src, ".WAIT_%u", ++wait_number);
gn = Targ_FindNode(wait_src, TARG_NOHASH); gn = Targ_FindNode(wait_src, TARG_NOHASH);
if (doing_depend)
ParseMark(gn);
gn->type = OP_WAIT | OP_PHONY | OP_DEPENDS | OP_NOTMAIN; gn->type = OP_WAIT | OP_PHONY | OP_DEPENDS | OP_NOTMAIN;
Lst_ForEach(targets, ParseLinkSrc, gn); Lst_ForEach(targets, ParseLinkSrc, gn);
return; return;
@ -1018,6 +1024,8 @@ ParseDoSrc(int tOp, const char *src)
* source and the current one. * source and the current one.
*/ */
gn = Targ_FindNode(src, TARG_CREATE); gn = Targ_FindNode(src, TARG_CREATE);
if (doing_depend)
ParseMark(gn);
if (predecessor != NULL) { if (predecessor != NULL) {
(void)Lst_AtEnd(predecessor->order_succ, gn); (void)Lst_AtEnd(predecessor->order_succ, gn);
(void)Lst_AtEnd(gn->order_pred, predecessor); (void)Lst_AtEnd(gn->order_pred, predecessor);
@ -1049,6 +1057,8 @@ ParseDoSrc(int tOp, const char *src)
/* Find/create the 'src' node and attach to all targets */ /* Find/create the 'src' node and attach to all targets */
gn = Targ_FindNode(src, TARG_CREATE); gn = Targ_FindNode(src, TARG_CREATE);
if (doing_depend)
ParseMark(gn);
if (tOp) { if (tOp) {
gn->type |= tOp; gn->type |= tOp;
} else { } else {
@ -1294,6 +1304,7 @@ ParseDoDependency(char *line)
* apply the .DEFAULT commands. * apply the .DEFAULT commands.
* .PHONY The list of targets * .PHONY The list of targets
* .NOPATH Don't search for file in the path * .NOPATH Don't search for file in the path
* .STALE
* .BEGIN * .BEGIN
* .END * .END
* .ERROR * .ERROR
@ -1304,42 +1315,45 @@ ParseDoDependency(char *line)
* .ORDER Must set initial predecessor to NULL * .ORDER Must set initial predecessor to NULL
*/ */
switch (specType) { switch (specType) {
case ExPath: case ExPath:
if (paths == NULL) { if (paths == NULL) {
paths = Lst_Init(FALSE); paths = Lst_Init(FALSE);
} }
(void)Lst_AtEnd(paths, dirSearchPath); (void)Lst_AtEnd(paths, dirSearchPath);
break; break;
case Main: case Main:
if (!Lst_IsEmpty(create)) { if (!Lst_IsEmpty(create)) {
specType = Not; specType = Not;
} }
break; break;
case Begin: case Begin:
case End: case End:
case dotError: case Stale:
case Interrupt: case dotError:
gn = Targ_FindNode(line, TARG_CREATE); case Interrupt:
gn->type |= OP_NOTMAIN|OP_SPECIAL; gn = Targ_FindNode(line, TARG_CREATE);
(void)Lst_AtEnd(targets, gn); if (doing_depend)
break; ParseMark(gn);
case Default: gn->type |= OP_NOTMAIN|OP_SPECIAL;
gn = Targ_NewGN(".DEFAULT"); (void)Lst_AtEnd(targets, gn);
gn->type |= (OP_NOTMAIN|OP_TRANSFORM); break;
(void)Lst_AtEnd(targets, gn); case Default:
DEFAULT = gn; gn = Targ_NewGN(".DEFAULT");
break; gn->type |= (OP_NOTMAIN|OP_TRANSFORM);
case NotParallel: (void)Lst_AtEnd(targets, gn);
maxJobs = 1; DEFAULT = gn;
break; break;
case SingleShell: case NotParallel:
compatMake = TRUE; maxJobs = 1;
break; break;
case Order: case SingleShell:
predecessor = NULL; compatMake = TRUE;
break; break;
default: case Order:
break; predecessor = NULL;
break;
default:
break;
} }
} else if (strncmp(line, ".PATH", 5) == 0) { } else if (strncmp(line, ".PATH", 5) == 0) {
/* /*
@ -1398,6 +1412,8 @@ ParseDoDependency(char *line)
} else { } else {
gn = Suff_AddTransform(targName); gn = Suff_AddTransform(targName);
} }
if (doing_depend)
ParseMark(gn);
(void)Lst_AtEnd(targets, gn); (void)Lst_AtEnd(targets, gn);
} }
@ -1445,6 +1461,7 @@ ParseDoDependency(char *line)
Parse_Error(PARSE_WARNING, "Special and mundane targets don't mix. Mundane ones ignored"); Parse_Error(PARSE_WARNING, "Special and mundane targets don't mix. Mundane ones ignored");
break; break;
case Default: case Default:
case Stale:
case Begin: case Begin:
case End: case End:
case dotError: case dotError:
@ -2454,6 +2471,7 @@ ParseGmakeExport(char *line)
"Variable/Value missing from \"export\""); "Variable/Value missing from \"export\"");
return; return;
} }
*value++ = '\0'; /* terminate variable */
/* /*
* Expand the value before putting it in the environment. * Expand the value before putting it in the environment.

View File

@ -1,6 +1,6 @@
# $Id: Makefile.in,v 1.40 2012/12/28 21:28:19 sjg Exp $ # $Id: Makefile.in,v 1.42 2013/03/23 02:31:13 sjg Exp $
# #
# $NetBSD: Makefile,v 1.35 2012/11/09 19:08:28 sjg Exp $ # $NetBSD: Makefile,v 1.36 2013/03/22 16:36:46 sjg Exp $
# #
# Unit tests for make(1) # Unit tests for make(1)
# The main targets are: # The main targets are:
@ -28,6 +28,7 @@ SUBFILES= \
error \ error \
export \ export \
export-all \ export-all \
export-env \
doterror \ doterror \
dotwait \ dotwait \
forloop \ forloop \
@ -72,10 +73,12 @@ TOOL_TR?= tr
TOOL_DIFF?= diff TOOL_DIFF?= diff
DIFF_FLAGS?= @diff_u@ DIFF_FLAGS?= @diff_u@
.if defined(.PARSEDIR)
# ensure consistent results from sort(1) # ensure consistent results from sort(1)
LC_ALL= C LC_ALL= C
LANG= C LANG= C
.export LANG LC_ALL .export LANG LC_ALL
.endif
# The driver. # The driver.
# We always pretend .MAKE was called 'make' # We always pretend .MAKE was called 'make'

24
unit-tests/export-env Normal file
View File

@ -0,0 +1,24 @@
# $Id: export-env,v 1.1.1.1 2013/03/23 02:26:59 sjg Exp $
# our normal .export, subsequent changes affect the environment
UT_TEST=this
.export UT_TEST
UT_TEST:= ${.PARSEFILE}
# not so with .export-env
UT_ENV=exported
.export-env UT_ENV
UT_ENV=not-exported
# gmake style export goes further; affects nothing but the environment
UT_EXP=before-export
export UT_EXP=exported
UT_EXP=not-exported
all:
@echo make:; ${UT_TEST UT_ENV UT_EXP:L:@v@echo $v=${$v};@}
@echo env:; ${UT_TEST UT_ENV UT_EXP:L:@v@echo $v=$${$v};@}

View File

@ -43,6 +43,14 @@ UT_OK=good
UT_OKDIR=unit-tests UT_OKDIR=unit-tests
UT_TEST=export-all UT_TEST=export-all
UT_ZOO=hoopie UT_ZOO=hoopie
make:
UT_TEST=export-env
UT_ENV=not-exported
UT_EXP=not-exported
env:
UT_TEST=export-env
UT_ENV=exported
UT_EXP=exported
At first, I am At first, I am
happy happy
and now: sad and now: sad

50
var.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: var.c,v 1.172 2012/11/15 16:42:26 christos Exp $ */ /* $NetBSD: var.c,v 1.173 2013/02/24 19:43:37 christos Exp $ */
/* /*
* Copyright (c) 1988, 1989, 1990, 1993 * Copyright (c) 1988, 1989, 1990, 1993
@ -69,14 +69,14 @@
*/ */
#ifndef MAKE_NATIVE #ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: var.c,v 1.172 2012/11/15 16:42:26 christos Exp $"; static char rcsid[] = "$NetBSD: var.c,v 1.173 2013/02/24 19:43:37 christos Exp $";
#else #else
#include <sys/cdefs.h> #include <sys/cdefs.h>
#ifndef lint #ifndef lint
#if 0 #if 0
static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94"; static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94";
#else #else
__RCSID("$NetBSD: var.c,v 1.172 2012/11/15 16:42:26 christos Exp $"); __RCSID("$NetBSD: var.c,v 1.173 2013/02/24 19:43:37 christos Exp $");
#endif #endif
#endif /* not lint */ #endif /* not lint */
#endif #endif
@ -309,7 +309,6 @@ static char *VarGetPattern(GNode *, Var_Parse_State *,
int, const char **, int, int *, int *, int, const char **, int, int *, int *,
VarPattern *); VarPattern *);
static char *VarQuote(char *); static char *VarQuote(char *);
static char *VarChangeCase(char *, int);
static char *VarHash(char *); static char *VarHash(char *);
static char *VarModify(GNode *, Var_Parse_State *, static char *VarModify(GNode *, Var_Parse_State *,
const char *, const char *,
@ -2350,37 +2349,6 @@ VarHash(char *str)
return Buf_Destroy(&buf, FALSE); return Buf_Destroy(&buf, FALSE);
} }
/*-
*-----------------------------------------------------------------------
* VarChangeCase --
* Change the string to all uppercase or all lowercase
*
* Input:
* str String to modify
* upper TRUE -> uppercase, else lowercase
*
* Results:
* The string with case changed
*
* Side Effects:
* None.
*
*-----------------------------------------------------------------------
*/
static char *
VarChangeCase(char *str, int upper)
{
Buffer buf;
int (*modProc)(int);
modProc = (upper ? toupper : tolower);
Buf_Init(&buf, 0);
for (; *str ; str++) {
Buf_AddByte(&buf, modProc(*str));
}
return Buf_Destroy(&buf, FALSE);
}
static char * static char *
VarStrftime(const char *fmt, int zulu) VarStrftime(const char *fmt, int zulu)
{ {
@ -3057,8 +3025,16 @@ ApplyModifiers(char *nstr, const char *tstr,
VarRealpath, NULL); VarRealpath, NULL);
cp = tstr + 2; cp = tstr + 2;
termc = *cp; termc = *cp;
} else if (tstr[1] == 'u' || tstr[1] == 'l') { } else if (tstr[1] == 'u') {
newStr = VarChangeCase(nstr, (tstr[1] == 'u')); char *dp = bmake_strdup(nstr);
for (newStr = dp; *dp; dp++)
*dp = toupper((unsigned char)*dp);
cp = tstr + 2;
termc = *cp;
} else if (tstr[1] == 'l') {
char *dp = bmake_strdup(nstr);
for (newStr = dp; *dp; dp++)
*dp = tolower((unsigned char)*dp);
cp = tstr + 2; cp = tstr + 2;
termc = *cp; termc = *cp;
} else if (tstr[1] == 'W' || tstr[1] == 'w') { } else if (tstr[1] == 'W' || tstr[1] == 'w') {