aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog44
-rw-r--r--FILES1
-rw-r--r--Makefile10
-rw-r--r--bmake.129
-rw-r--r--bmake.cat124
-rwxr-xr-xboot-strap5
-rwxr-xr-xconfigure18
-rw-r--r--configure.in4
-rw-r--r--dir.c15
-rw-r--r--job.c104
-rw-r--r--job.h3
-rw-r--r--main.c31
-rw-r--r--make.129
-rw-r--r--make.h4
-rw-r--r--meta.c47
-rw-r--r--meta.h5
-rw-r--r--mk/ChangeLog68
-rw-r--r--mk/dirdeps.mk274
-rw-r--r--mk/gendirdeps.mk81
-rw-r--r--mk/install-mk4
-rw-r--r--mk/meta.stage.mk59
-rwxr-xr-xmk/meta2deps.py38
-rwxr-xr-xmk/meta2deps.sh5
-rw-r--r--mk/sys.dependfile.mk14
-rw-r--r--parse.c96
-rw-r--r--unit-tests/Makefile.in7
-rw-r--r--unit-tests/export-env24
-rw-r--r--unit-tests/test.exp8
-rw-r--r--var.c50
29 files changed, 771 insertions, 330 deletions
diff --git a/ChangeLog b/ChangeLog
index 9d54c18ca223..f0374ba707eb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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>
* Merge with NetBSD make, pick up
diff --git a/FILES b/FILES
index b75cf1c2d61e..dedc1ac8b07c 100644
--- a/FILES
+++ b/FILES
@@ -102,6 +102,7 @@ unit-tests/dotwait
unit-tests/error
unit-tests/export
unit-tests/export-all
+unit-tests/export-env
unit-tests/forloop
unit-tests/forsubst
unit-tests/hash
diff --git a/Makefile b/Makefile
index 360732685bcc..edf0bd8b8e68 100644
--- a/Makefile
+++ b/Makefile
@@ -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
-MAKE_VERSION= 20130123
+MAKE_VERSION= 20130330
PROG= bmake
@@ -187,14 +187,14 @@ MANDIR= ${SHAREDIR}/man
.if !exists(.depend)
${OBJS}: config.h
.endif
-.if ${MK_AUTOCONF_MK} == "yes"
-.include <autoconf.mk>
-.endif
# make sure that MAKE_VERSION gets updated.
main.o: ${SRCS} ${MAKEFILE}
# start-delete2 for bsd.after-import.mk
+.if ${MK_AUTOCONF_MK} == "yes"
+.include <autoconf.mk>
+.endif
SHARE_MK?=${SHAREDIR}/mk
MKSRC=${srcdir}/mk
INSTALL?=${srcdir}/install-sh
diff --git a/bmake.1 b/bmake.1
index 82cec21dca4a..2403eae7078f 100644
--- a/bmake.1
+++ b/bmake.1
@@ -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
.\" The Regents of the University of California. All rights reserved.
@@ -29,7 +29,7 @@
.\"
.\" from: @(#)make.1 8.4 (Berkeley) 3/19/94
.\"
-.Dd January 23, 2013
+.Dd March 30, 2013
.Dt MAKE 1
.Os
.Sh NAME
@@ -874,6 +874,13 @@ by appending their names to
is re-exported whenever
.Ql Va .MAKEOVERRIDES
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
The process-id of
.Nm .
@@ -1757,6 +1764,20 @@ targets.
Ignore differences in commands when deciding if target is out of date.
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.
+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
Do not search for the target in the directories specified by
.Ic .PATH .
@@ -2008,6 +2029,10 @@ If no sources are specified, the
.Ic .SILENT
attribute is applied to every
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
Each source specifies a suffix to
.Nm .
diff --git a/bmake.cat1 b/bmake.cat1
index 7800726ccf60..e446e891450c 100644
--- a/bmake.cat1
+++ b/bmake.cat1
@@ -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
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_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
of date. 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.
+ 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
..PPAATTHH.
@@ -1278,6 +1295,9 @@ SSPPEECCIIAALL TTAARRGGEETTSS
sources are specified, the ..SSIILLEENNTT attribute is applied to every
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
Each source specifies a suffix to bbmmaakkee. If no sources are
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.
-NetBSD 5.1 January 23, 2013 NetBSD 5.1
+NetBSD 5.1 March 30, 2013 NetBSD 5.1
diff --git a/boot-strap b/boot-strap
index 7eff5f65ae16..2193926d8023 100755
--- a/boot-strap
+++ b/boot-strap
@@ -111,7 +111,7 @@
# Simon J. Gerraty <sjg@crufty.net>
# 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
#
@@ -159,6 +159,9 @@ source_rc() {
cmd_args="$@"
+# clear some things from the environment that we care about
+unset MAKEOBJDIR MAKEOBJDIRPREFIX
+
# --install[-host-target] will set this
INSTALL_PREFIX=
# other things we pass to install step
diff --git a/configure b/configure
index f79b26f86376..a515b278c276 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# 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>.
#
@@ -549,8 +549,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='bmake'
PACKAGE_TARNAME='bmake'
-PACKAGE_VERSION='20121212'
-PACKAGE_STRING='bmake 20121212'
+PACKAGE_VERSION='20130303'
+PACKAGE_STRING='bmake 20130303'
PACKAGE_BUGREPORT='sjg@NetBSD.org'
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.
# This message is too long to be a string in the A/UX 3.1 sh.
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]...
@@ -1281,7 +1281,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of bmake 20121212:";;
+ short | recursive ) echo "Configuration of bmake 20130303:";;
esac
cat <<\_ACEOF
@@ -1386,7 +1386,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-bmake configure 20121212
+bmake configure 20130303
generated by GNU Autoconf 2.64
Copyright (C) 2009 Free Software Foundation, Inc.
@@ -1907,7 +1907,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
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
$ $0 $@
@@ -6374,7 +6374,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
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
CONFIG_FILES = $CONFIG_FILES
@@ -6434,7 +6434,7 @@ Report bugs to <sjg@NetBSD.org>."
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_version="\\
-bmake config.status 20121212
+bmake config.status 20130303
configured by $0, generated by GNU Autoconf 2.64,
with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
diff --git a/configure.in b/configure.in
index 0caafdfd07dc..ba82a75e598d 100644
--- a/configure.in
+++ b/configure.in
@@ -1,10 +1,10 @@
dnl
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 Process this file with autoconf to produce a configure script
dnl
-AC_INIT([bmake], [20121212], [sjg@NetBSD.org])
+AC_INIT([bmake], [20130303], [sjg@NetBSD.org])
AC_CONFIG_HEADER(config.h)
dnl make srcdir absolute
diff --git a/dir.c b/dir.c
index 1c56ea3e8973..7b12769c2dcf 100644
--- a/dir.c
+++ b/dir.c
@@ -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.
@@ -70,14 +70,14 @@
*/
#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
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)dir.c 8.2 (Berkeley) 1/2/94";
#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 /* not lint */
#endif
@@ -145,6 +145,7 @@ __RCSID("$NetBSD: dir.c,v 1.65 2012/06/12 19:21:50 joerg Exp $");
#include "make.h"
#include "hash.h"
#include "dir.h"
+#include "job.h"
/*
* 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.
*/
gn->path = bmake_strdup(fullName);
- fprintf(stdout,
- "%s: ignoring stale %s for %s, found %s\n",
- progname, makeDependfile, gn->name, fullName);
+ if (!Job_RunTarget(".STALE", gn->fname))
+ fprintf(stdout,
+ "%s: %s, %d: ignoring stale %s for %s, "
+ "found %s\n", progname, gn->fname, gn->lineno,
+ makeDependfile, gn->name, fullName);
}
}
}
diff --git a/job.c b/job.c
index 3049e60b1611..a77eaab107ba 100644
--- a/job.c
+++ b/job.c
@@ -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.
@@ -70,14 +70,14 @@
*/
#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
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)job.c 8.2 (Berkeley) 3/19/94";
#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 /* not lint */
#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 "wait.h"
+#include <assert.h>
#include <errno.h>
#include <fcntl.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";
if (gn->flags & FROM_DEPEND) {
- fprintf(stdout, "%s: ignoring stale %s for %s\n",
- progname, makeDependfile, gn->name);
+ if (!Job_RunTarget(".STALE", gn->fname))
+ fprintf(stdout, "%s: %s, %d: ignoring stale %s for %s\n",
+ progname, gn->fname, gn->lineno, makeDependfile,
+ gn->name);
return TRUE;
}
@@ -2063,32 +2066,45 @@ Job_CatchOutput(void)
(void)fflush(stdout);
/* 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;
- nready -= 1;
- while (read(childExitJob.inPipe, &token, 1) == -1 && errno == EAGAIN)
- continue;
- if (token == DO_JOB_RESUME[0])
- /* Complete relay requested from our SIGCONT handler */
- JobRestartJobs();
- Job_CatchChildren();
+ ssize_t count;
+ count = read(childExitJob.inPipe, &token, 1);
+ switch (count) {
+ case 0:
+ Punt("unexpected eof on token pipe");
+ case -1:
+ 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)
- return;
-
- if (wantToken && readyfd(&tokenWaitJob))
- nready--;
+ Job_CatchChildren();
+ if (nready == 0)
+ return;
for (i = 2; i < nfds; i++) {
if (!fds[i].revents)
continue;
job = jobfds[i];
- if (job->job_state != JOB_ST_RUNNING)
- continue;
- JobDoOutput(job, FALSE);
+ if (job->job_state == JOB_ST_RUNNING)
+ JobDoOutput(job, FALSE);
+ if (--nready == 0)
+ return;
}
}
@@ -2179,8 +2195,6 @@ Job_SetPrefix(void)
void
Job_Init(void)
{
- GNode *begin; /* node for commands to do at the very start */
-
/* Allocate space for all the job info */
job_table = bmake_malloc(maxJobs * sizeof *job_table);
memset(job_table, 0, maxJobs * sizeof *job_table);
@@ -2256,15 +2270,7 @@ Job_Init(void)
ADDSIG(SIGCONT, JobContinueSig)
#undef ADDSIG
- begin = Targ_FindNode(".BEGIN", TARG_NOCREATE);
-
- if (begin != NULL) {
- JobRun(begin);
- if (begin->made == ERROR) {
- PrintOnError(begin, "\n\nStop.");
- exit(1);
- }
- }
+ (void)Job_RunTarget(".BEGIN", NULL);
postCommands = Targ_FindNode(".END", TARG_CREATE);
}
@@ -2930,6 +2936,38 @@ Job_TokenWithdraw(void)
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
int
emul_poll(struct pollfd *fd, int nfd, int timeout)
diff --git a/job.h b/job.h
index 560b70bf7326..5323b100412b 100644
--- a/job.h
+++ b/job.h
@@ -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.
@@ -268,5 +268,6 @@ void Job_TokenReturn(void);
Boolean Job_TokenWithdraw(void);
void Job_ServerStart(int, int, int);
void Job_SetPrefix(void);
+Boolean Job_RunTarget(const char *, const char *);
#endif /* _JOB_H_ */
diff --git a/main.c b/main.c
index f4bd721844cd..84c6935f81e4 100644
--- a/main.c
+++ b/main.c
@@ -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
@@ -69,7 +69,7 @@
*/
#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
#include <sys/cdefs.h>
#ifndef lint
@@ -81,7 +81,7 @@ __COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993\
#if 0
static char sccsid[] = "@(#)main.c 8.3 (Berkeley) 3/19/94";
#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 /* not lint */
#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 <signal.h>
#include <sys/stat.h>
-#ifdef MAKE_NATIVE
#include <sys/utsname.h>
-#endif
#include "wait.h"
#include <errno.h>
@@ -768,7 +766,7 @@ MakeMode(const char *mode)
}
#if USE_META
if (strstr(mode, "meta"))
- meta_init(mode);
+ meta_mode_init(mode);
#endif
}
if (mp)
@@ -813,9 +811,7 @@ main(int argc, char **argv)
static char defsyspath[] = _PATH_DEFSYSPATH;
char found_path[MAXPATHLEN + 1]; /* for searching for sys.mk */
struct timeval rightnow; /* to initialize random seed */
-#ifdef MAKE_NATIVE
struct utsname utsname;
-#endif
/* default to writing debug to stderr */
debug_file = stderr;
@@ -834,7 +830,7 @@ main(int argc, char **argv)
progname++;
else
progname = argv[0];
-#ifdef RLIMIT_NOFILE
+#if defined(MAKE_NATIVE) || (defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE))
/*
* get rid of resource limit on file descriptors
*/
@@ -848,6 +844,12 @@ main(int argc, char **argv)
}
#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
* so we can share an executable for similar machines.
@@ -858,11 +860,6 @@ main(int argc, char **argv)
*/
if (!machine) {
#ifdef MAKE_NATIVE
- if (uname(&utsname) == -1) {
- (void)fprintf(stderr, "%s: uname failed (%s).\n", progname,
- strerror(errno));
- exit(2);
- }
machine = utsname.machine;
#else
#ifdef MAKE_MACHINE
@@ -892,6 +889,7 @@ main(int argc, char **argv)
*/
Var_Init(); /* Initialize the lists of variables for
* parsing arguments */
+ Var_Set(".MAKE.OS", utsname.sysname, VAR_GLOBAL, 0);
Var_Set("MACHINE", machine, VAR_GLOBAL, 0);
Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL, 0);
#ifdef MAKE_VERSION
@@ -987,6 +985,9 @@ main(int argc, char **argv)
}
Job_SetPrefix();
+#ifdef USE_META
+ meta_init();
+#endif
/*
* First snag any flags out of the MAKE environment variable.
* (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.
*/
int
diff --git a/make.1 b/make.1
index 198410cd5751..8c386826af1a 100644
--- a/make.1
+++ b/make.1
@@ -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
.\" The Regents of the University of California. All rights reserved.
@@ -29,7 +29,7 @@
.\"
.\" from: @(#)make.1 8.4 (Berkeley) 3/19/94
.\"
-.Dd January 23, 2013
+.Dd March 30, 2013
.Dt MAKE 1
.Os
.Sh NAME
@@ -874,6 +874,13 @@ by appending their names to
is re-exported whenever
.Ql Va .MAKEOVERRIDES
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
The process-id of
.Nm .
@@ -1757,6 +1764,20 @@ targets.
Ignore differences in commands when deciding if target is out of date.
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.
+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
Do not search for the target in the directories specified by
.Ic .PATH .
@@ -2008,6 +2029,10 @@ If no sources are specified, the
.Ic .SILENT
attribute is applied to every
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
Each source specifies a suffix to
.Nm .
diff --git a/make.h b/make.h
index 384d109877b1..c9c72bcb0d51 100644
--- a/make.h
+++ b/make.h
@@ -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
@@ -103,7 +103,7 @@
((__GNUC__ == (x) && __GNUC_MINOR__ >= (y)) || \
(__GNUC__ > (x)))
#else /* defined(__GNUC__) */
-#define MAKE_GNUC_PREREQx, y) 0
+#define MAKE_GNUC_PREREQ(x, y) 0
#endif /* defined(__GNUC__) */
#if MAKE_GNUC_PREREQ(2, 7)
diff --git a/meta.c b/meta.c
index d6110d928f41..1bbbe33ec529 100644
--- a/meta.c
+++ b/meta.c
@@ -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.
@@ -539,8 +539,24 @@ boolValue(char *s)
return TRUE;
}
+/*
+ * Initialization we need before reading makefiles.
+ */
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;
char *cp;
@@ -1037,6 +1053,7 @@ meta_oodate(GNode *gn, Boolean oodate)
char *tp = Lst_Datum(ln);
Lst_Remove(missingFiles, ln);
free(tp);
+ ln = NULL; /* we're done with it */
}
}
break;
@@ -1196,17 +1213,19 @@ meta_oodate(GNode *gn, Boolean oodate)
oodate = TRUE;
} else {
char *cmd = (char *)Lst_Datum(ln);
-
- if (!needOODATE) {
- if (strstr(cmd, "$?"))
- needOODATE = TRUE;
- else if ((cp = strstr(cmd, ".OODATE"))) {
- /* check for $[{(].OODATE[)}] */
- if (cp > cmd + 2 && cp[-2] == '$')
- needOODATE = TRUE;
- }
- if (needOODATE && DEBUG(META))
- fprintf(debug_file, "%s: %d: cannot compare commands using .OODATE\n", fname, lineno);
+ Boolean hasOODATE = FALSE;
+
+ if (strstr(cmd, "$?"))
+ hasOODATE = TRUE;
+ else if ((cp = strstr(cmd, ".OODATE"))) {
+ /* check for $[{(].OODATE[:)}] */
+ if (cp > cmd + 2 && cp[-2] == '$')
+ hasOODATE = TRUE;
+ }
+ if (hasOODATE) {
+ needOODATE = TRUE;
+ if (DEBUG(META))
+ fprintf(debug_file, "%s: %d: cannot compare command using .OODATE\n", fname, lineno);
}
cmd = Var_Subst(NULL, cmd, gn, TRUE);
@@ -1235,7 +1254,7 @@ meta_oodate(GNode *gn, Boolean oodate)
if (buf[x - 1] == '\n')
buf[x - 1] = '\0';
}
- if (!needOODATE &&
+ if (!hasOODATE &&
!(gn->type & OP_NOMETA_CMP) &&
strcmp(p, cmd) != 0) {
if (DEBUG(META))
diff --git a/meta.h b/meta.h
index 1ce01ca901cb..57c73ca9b5f1 100644
--- a/meta.h
+++ b/meta.h
@@ -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.
@@ -41,7 +41,8 @@ typedef struct BuildMon {
extern Boolean useMeta;
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_child(struct Job *);
void meta_job_error(struct Job *, GNode *, int, int);
diff --git a/mk/ChangeLog b/mk/ChangeLog
index fee1c905c444..0f49477da486 100644
--- a/mk/ChangeLog
+++ b/mk/ChangeLog
@@ -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>
* install-mk (MK_VERSION): bump version to 20130123
diff --git a/mk/dirdeps.mk b/mk/dirdeps.mk
index 9f051e9203e7..e812416cc88e 100644
--- a/mk/dirdeps.mk
+++ b/mk/dirdeps.mk
@@ -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
# modification, are permitted provided that the following conditions
@@ -33,21 +34,31 @@
# This is what we do with DIRDEPS
# DIRDEPS:
-# This is a list of directories - relative to SRCTOP, it is only
-# of interest to .MAKE.LEVEL 0.
+# This is a list of directories - relative to SRCTOP, it is
+# normally only of interest to .MAKE.LEVEL 0.
# 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}.
-# 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.
#
-# Each entry is also converted into a set of paths to look for
-# Makefile.depend.<machine> to learn the dependencies of each.
-# Each Makefile.depend.<machine> sets DEP_RELDIR to be the
+# The fully qualified directory entries are used to construct a
+# dependency graph that will drive the build later.
+#
+# 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
-# DEP_MACHINE to its suffix (<machine>), further since
-# each Makefile.depend.<machine> includes dirdeps.mk, this
+# since each Makefile.depend file includes dirdeps.mk, this
# processing is recursive and results in .MAKE.LEVEL 0 learning the
# dependencies of the tree wrt the initial directory (_DEP_RELDIR).
#
@@ -55,38 +66,49 @@
# Indicates whether .MAKE.LEVEL 0 builds anything:
# if "no" sub-makes are used to build everything,
# 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
-# All the description above (and below) assumes <machine> is the
-# only data needed to control the build.
-# This is not always the case. So in addition to setting
-# MACHINE in the build environment we set TARGET_SPEC which is
-# composed of the values of TARGET_SPEC_VARS separated by
-# commas. The default is just MACHINE.
+# The default value is just MACHINE, and for most environments
+# this is sufficient. The _DIRDEPS_USE target actually sets
+# both MACHINE and TARGET_SPEC to the suffix of the current
+# target so that in the general case TARGET_SPEC can be ignored.
#
-# 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.
-# It is important that MACHINE be included in TARGET_SPEC_VARS
-# since if there is more the value passed as MACHINE will infact
-# be the TARGET_SPEC.
+# It is important that MACHINE be included in and actually be
+# the first member of TARGET_SPEC_VARS. This allows other
+# 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
-# tripple used by compiler folk won't work (directly anyway).
+# triple used by compiler folk won't work (directly anyway).
#
# For example:
#
-# # variables other than MACHINE might be optional
+# # Always list MACHINE first,
+# # other variables might be optional.
# TARGET_SPEC_VARS = MACHINE TARGET_OS
# .if ${TARGET_SPEC:Uno:M*,*} != ""
# _tspec := ${TARGET_SPEC:S/,/ /g}
# MACHINE := ${_tspec:[1]}
# TARGET_OS := ${_tspec:[2]}
# # 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}
# .if empty($v)
# .undef $v
# .endif
# .endfor
# .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
@@ -100,14 +122,48 @@
# do some setup we only need once
_CURDIR ?= ${.CURDIR}
+# make sure these are empty to start with
+_DEP_TARGET_SPEC =
+_DIRDEP_CHECKED =
+
# If TARGET_SPEC_VARS is other than just MACHINE
# it should be set by sys.mk or similar by now.
# TARGET_SPEC must not contain any '.'s.
TARGET_SPEC_VARS ?= MACHINE
+# this is what we started with
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)
-# 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}
.if ${.MAKE.DEPENDFILE:E} == "${TARGET_SPEC}"
.if ${TARGET_SPEC} != ${MACHINE}
@@ -118,12 +174,12 @@ TARGET_SPEC = ${TARGET_SPEC_VARS:@v@${$v:U}@:ts,}
.endif
_default_dependfile := ${.MAKE.DEPENDFILE_PREFERENCE:[1]:T}
-_machine_dependfiles := ${.MAKE.DEPENDFILE_PREFERENCE:M*.${TARGET_SPEC}} \
- ${.MAKE.DEPENDFILE_PREFERENCE:M*.${MACHINE}}
+_machine_dependfiles := ${.MAKE.DEPENDFILE_PREFERENCE:T:M*${MACHINE}*}
# for machine specific dependfiles we require ${MACHINE} to be at the end
# also for the sake of sanity we require a common prefix
.if !defined(.MAKE.DEPENDFILE_PREFIX)
+# knowing .MAKE.DEPENDFILE_PREFIX helps
.if !empty(_machine_dependfiles)
.MAKE.DEPENDFILE_PREFIX := ${_machine_dependfiles:[1]:T:R}
.else
@@ -133,24 +189,45 @@ _machine_dependfiles := ${.MAKE.DEPENDFILE_PREFERENCE:M*.${TARGET_SPEC}} \
# 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)
+# 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]}
+.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
-# will not work, so we also test for DEP_MACHINE==depend below.
-.if empty(_last_dependfile)
-# we haven't included one yet
-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}}
+.if empty(_last_dependfile) || ${_last_dependfile:E:${N_notmachine}} == ""
+# this is all we have to work with
+DEP_MACHINE = ${TARGET_MACHINE:U${MACHINE}}
+_DEP_TARGET_SPEC := ${DEP_TARGET_SPEC}
.else
-# just in case
-DEP_MACHINE ?= ${_last_dependfile:E}
+_DEP_TARGET_SPEC = ${_last_dependfile:${M_dep_qual_fixes:ts:}: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
# pickup customizations
@@ -179,17 +256,18 @@ _DEP_RELDIR := ${DEP_RELDIR}
SKIP_HOSTDIR ?=
NSkipHostDir = ${SKIP_HOSTDIR:N*.host:S,$,.host,:N.host:${M_ListToSkip}}
-NSkipHostDep = ${SKIP_HOSTDIR:R:@d@*/$d*.host@:${M_ListToSkip}}
# things we always skip
# SKIP_DIRDEPS allows for adding entries on command line.
SKIP_DIR += .host *.WAIT ${SKIP_DIRDEPS}
+SKIP_DIR.host += ${SKIP_HOSTDIR}
-.ifdef HOSTPROG
-SKIP_DIR += ${SKIP_HOSTDIR}
-.endif
+DEP_SKIP_DIR = ${SKIP_DIR} \
+ ${SKIP_DIR.${DEP_TARGET_SPEC}:U} \
+ ${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)
# confine ourselves to the original dir
@@ -198,12 +276,15 @@ DIRDEPS_FILTER += M${_DEP_RELDIR}*
# we supress SUBDIR when visiting the leaves
# 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
@for m in ${.MAKE.MAKEFILE_PREFERENCE}; do \
test -s ${.TARGET:R}/$$m || continue; \
echo "${TRACER}Checking ${.TARGET:R} for ${.TARGET:E} ..."; \
+ MACHINE_ARCH= NO_SUBDIR=1 ${DIRDEP_USE_ENV} \
TARGET_SPEC=${.TARGET:E} \
- MACHINE=${.TARGET:E} MACHINE_ARCH= NO_SUBDIR=1 \
+ MACHINE=${.TARGET:E} \
${.MAKE} -C ${.TARGET:R} || exit 1; \
break; \
done
@@ -260,7 +341,7 @@ _this_dir := ${SRCTOP}/${DEP_RELDIR}
_dep_hack := ${_this_dir}/${.MAKE.DEPENDFILE_PREFIX}.inc
.-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
_machines := ${DEP_MACHINE}
.else
@@ -275,17 +356,23 @@ _machines += host
_machines := ${_machines:O:u}
.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 =
-_depdir_files =
.if ${DEP_RELDIR} == ${_DEP_RELDIR}
# pickup other machines for this dir if necessary
.if ${BUILD_AT_LEVEL0:Uyes} == "no"
_build_dirs += ${_machines:@m@${_CURDIR}.$m@}
.else
-_build_dirs += ${_machines:N${DEP_MACHINE}:@m@${_CURDIR}.$m@}
-.if ${DEP_MACHINE} == ${TARGET_SPEC}
+_build_dirs += ${_machines:N${DEP_TARGET_SPEC}:@m@${_CURDIR}.$m@}
+.if ${DEP_TARGET_SPEC} == ${TARGET_SPEC}
# pickup local dependencies now
.-include <.depend>
.endif
@@ -293,15 +380,23 @@ _build_dirs += ${_machines:N${DEP_MACHINE}:@m@${_CURDIR}.$m@}
.endif
.if !empty(_debug_reldir)
-.info ${DEP_RELDIR}.${DEP_MACHINE}: _last_dependfile='${_last_dependfile}'
-.info ${DEP_RELDIR}.${DEP_MACHINE}: DIRDEPS='${DIRDEPS}'
-.info ${DEP_RELDIR}.${DEP_MACHINE}: _machines='${_machines}'
+.info ${DEP_RELDIR}.${DEP_TARGET_SPEC}: DIRDEPS='${DIRDEPS}'
+.info ${DEP_RELDIR}.${DEP_TARGET_SPEC}: _machines='${_machines}'
.endif
.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
-__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>
# the :M*/*/*.* just tries to limit the dirs we check to likely ones.
@@ -327,26 +422,8 @@ _build_dirs += \
${__qual_depdirs:N*.host} \
${_machines:@m@${__unqual_depdirs:@d@$d.$m@}@}
-_build_dirs := ${_build_dirs: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}
+# qualify everything now
+_build_dirs := ${_build_dirs:${M_dep_qual_fixes:ts:}:O:u}
.endif # empty DIRDEPS
@@ -360,48 +437,57 @@ dirdeps: ${_build_dirs}
${_build_dirs}: _DIRDEP_USE
.if !empty(_debug_reldir)
-.info ${DEP_RELDIR}.${DEP_MACHINE}: ${_build_dirs}
+.info ${DEP_RELDIR}.${DEP_TARGET_SPEC}: needs: ${_build_dirs}
.endif
+# this builds the dependency graph
.for m in ${_machines}
# it would be nice to do :N${.TARGET}
.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}@} != ""
-.info ${DEP_RELDIR}.$m: ${_build_dirs:M*.$q}
+.info ${DEP_RELDIR}.$m: graph: ${_build_dirs:M*.$q}
.endif
${_this_dir}.$m: ${_build_dirs:M*.$q}
.endfor
.endif
.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
${_this_dir}.$m: ${_build_dirs:M*.$m:N${_this_dir}.$m}
.endfor
.endif
-.for d in ${_depdir_files}
-.if ${.MAKE.MAKEFILES:M${d}} == ""
+# Now find more dependencies - and recurse.
+.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)
-.info Looking for $d
-.endif
-.if exists($d)
-.include <$d>
-.elif exists(${d:R})
-# an unqualified file exists, we qualified it above so we can set _DEP_MACHINE
-# it might be manually maintained and shared by all machine types
-# tell it the machine we are interested in.
-_DEP_MACHINE := ${d:E}
-.if !empty(_debug_reldir)
-.info loading ${d:R} for ${_DEP_MACHINE}
+.info Looking for ${_qm}
+.endif
+# we pass _DEP_TARGET_SPEC to tell the next step what we want
+_DEP_TARGET_SPEC := ${d:E}
+# some makefiles may still look at this
+_DEP_MACHINE := ${d:E:C/,.*//}
+.if !empty(_debug_reldir) && ${_qm} != ${_m}
+.info loading ${_m} for ${d:E}
+.endif
+.include <${_m}>
.endif
-# pretend we read $d, so we don't come by here again.
-.MAKE.MAKEFILES += $d
-.include <${d:R}>
.endif
.endif
.endfor
+
.endif # -V
.elif ${.MAKE.LEVEL} > 42
diff --git a/mk/gendirdeps.mk b/mk/gendirdeps.mk
index 890f4956f38e..5742c6fbcc1d 100644
--- a/mk/gendirdeps.mk
+++ b/mk/gendirdeps.mk
@@ -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
# modification, are permitted provided that the following conditions
@@ -50,7 +51,12 @@ _CURDIR ?= ${.CURDIR}
_OBJDIR ?= ${.OBJDIR}
_OBJTOP ?= ${OBJTOP}
_OBJROOT ?= ${OBJROOT:U${_OBJTOP}}
-_objroot ?= ${_OBJROOT:tA}
+.if ${_OBJROOT:M*/}
+_slash=/
+.else
+_slash=
+.endif
+_objroot ?= ${_OBJROOT:tA}${_slash}
_this = ${.PARSEDIR}/${.PARSEFILE}
@@ -106,25 +112,26 @@ _py_d =
# we can afford to do this all the time.
DPDEPS ?= no
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"
META2DEPS_CMD += -D ${DPDEPS}
.endif
+
+M2D_OBJROOTS += ${OBJTOP} ${_OBJROOT} ${_objroot}
+.if defined(SB_OBJROOT)
+M2D_OBJROOTS += ${SB_OBJROOT}
+.endif
.if ${.MAKE.DEPENDFILE_PREFERENCE:U${.MAKE.DEPENDFILE}:M*.${MACHINE}} == ""
# meta2deps.py only groks objroot
# so we need to give it what it expects
-M2D_OBJROOT = ${OBJTOP}/
# and tell it not to add machine qualifiers
META2DEPS_ARGS += MACHINE=none
-.else
-.if defined(SB_OBJROOT)
-M2D_OBJROOT ?= ${SB_OBJROOT}
-.else
-M2D_OBJROOT = ${OBJTOP}/
-.endif
.endif
.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
META2DEPS_FILTER = sed 's,^src:,${SRCTOP}/,;s,^\([^/]\),${OBJTOP}/\1,' |
.elif ${META2DEPS:E} == "sh"
@@ -155,7 +162,26 @@ dir_list != cd ${_OBJDIR} && \
.if !empty(DPADD)
_nonlibs := ${DPADD:T:Nlib*:N*include}
.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
@@ -167,26 +193,28 @@ dir_list += ${_nonlibs:@x@${DPADD:M*/$x}@:H:tA}
# so we add
# ${"${dir_list:M*bsd/sys/${MACHINE_ARCH}/include}":?bsd/include:}
# to GENDIRDEPS_DIR_LIST_XTRAS
+_objtops = ${OBJTOP} ${_OBJTOP} ${_obtop}
+_objtops := ${_objtops:O:u}
dirdep_list = \
- ${dir_list:M${_objtop}*/*:C,${_objtop}[^/]*/,,} \
+ ${_objtops:@o@${dir_list:M$o*/*:C,$o[^/]*/,,}@} \
${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
# needs to be qualified with its .<machine> suffix
# (we used the pseudo machine "host" for the HOST_TARGET).
-qualdir_list = \
- ${dir_list:M${_objroot}*/*/*:N${SRCTOP}*:N${_objtop}*:C,${_objroot}([^/]+)/(.*),\2.\1,:S,.${HOST_TARGET},.host,}
-
-.if ${_OBJROOT} != ${_objroot}
-dirdep_list += \
- ${dir_list:M${_OBJTOP}*/*:C,${_OBJTOP}[^/]*/,,}
-
-qualdir_list += \
- ${dir_list:M${_OBJROOT}*/*/*:N${SRCTOP}*:N${_OBJTOP}*:C,${_OBJROOT}([^/]+)/(.*),\2.\1,:S,.${HOST_TARGET},.host,}
-.endif
+skip_ql= ${SRCTOP}* ${_objtops:@o@$o*@}
+.for o in ${M2D_OBJROOTS:${skip_ql:${M_ListToSkip}}}
+# we need := so only skip_ql to this point applies
+ql := ${dir_list:${skip_ql:${M_ListToSkip}}:M$o*/*/*:C,$o([^/]+)/(.*),\2.\1,:S,.${HOST_TARGET},.host,}
+qualdir_list += ${ql}
+skip_ql+= $o*
+.endfor
dirdep_list := ${dirdep_list:O:u}
-qualdir_list := ${qualdir_list:O:u}
+qualdir_list := ${qualdir_list:N*.${MACHINE}:O:u}
DIRDEPS = \
${dirdep_list:N${RELDIR}:N${RELDIR}/*} \
@@ -207,6 +235,7 @@ DIRDEPS += \
DIRDEPS := ${DIRDEPS:${GENDIRDEPS_FILTER:UNno:ts:}:O:u}
.if ${DEBUG_GENDIRDEPS:Uno:@x@${RELDIR:M$x}@} != ""
+.info ${RELDIR}: M2D_OBJROOTS=${M2D_OBJROOTS}
.info ${RELDIR}: dir_list='${dir_list}'
.info ${RELDIR}: dirdep_list='${dirdep_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}
@(echo '# Autogenerated - do NOT edit!'; echo; \
echo 'DEP_RELDIR := $${_PARSEDIR:S,$${SRCTOP}/,,}'; echo; \
- echo 'DEP_MACHINE := $${.PARSEFILE:E}'; echo; \
echo 'DIRDEPS = \'; \
echo '${DIRDEPS:@d@ $d \\${.newline}@}'; echo; \
${_include_src_dirdeps} \
@@ -285,7 +313,6 @@ all: ${_DEPENDFILE}
${_DEPENDFILE}: ${MAKEFILE} ${_this}
@(echo '# Autogenerated - do NOT edit!'; echo; \
echo 'DEP_RELDIR := $${_PARSEDIR:S,$${SRCTOP}/,,}'; echo; \
- echo 'DEP_MACHINE := $${.PARSEFILE:E}'; echo; \
echo 'DIRDEPS = \'; \
echo '${DIRDEPS:@d@ $d \\${.newline}@}'; echo; \
echo '.include <dirdeps.mk>'; \
diff --git a/mk/install-mk b/mk/install-mk
index 7dea1fc33df3..c45c6ca828d0 100644
--- a/mk/install-mk
+++ b/mk/install-mk
@@ -55,7 +55,7 @@
# Simon J. Gerraty <sjg@crufty.net>
# 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
#
@@ -70,7 +70,7 @@
# sjg@crufty.net
#
-MK_VERSION=20130123
+MK_VERSION=20130330
OWNER=
GROUP=
MODE=444
diff --git a/mk/meta.stage.mk b/mk/meta.stage.mk
index cf62db4311e1..0faeef34cbcc 100644
--- a/mk/meta.stage.mk
+++ b/mk/meta.stage.mk
@@ -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
#
@@ -48,37 +48,39 @@ GENDIRDEPS_FILTER += Nnot-empty-is-important \
${_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,}
+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
# the same file
-STAGE_DIRDEP_SCRIPT = StageDirdep() { \
+STAGE_DIRDEP_SCRIPT = ${LN_CP_SCRIPT}; StageDirdep() { \
t=$$1; \
if [ -s $$t.dirdep ]; then \
cmp -s .dirdep $$t.dirdep && return; \
echo "ERROR: $$t installed by `cat $$t.dirdep` not ${_dirdep}" >&2; \
exit 1; \
fi; \
- ln .dirdep $$t.dirdep 2> /dev/null || \
- cp .dirdep $$t.dirdep; }
+ LnCp .dirdep $$t.dirdep || exit 1; }
# common logic for staging files
# this all relies on RELDIR being set to a subdir of SRCTOP
# we use ln(1) if we can, else cp(1)
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; \
mkdir -p $$dest; \
[ -s .dirdep ] || echo '${_dirdep}' > .dirdep; \
for f in "$$@"; do \
case "$$f" in */*) t=$$dest/${_stage_file_basename};; *) t=$$dest/$$f;; esac; \
StageDirdep $$t; \
- rm -f $$t; \
- { ln $$f $$t 2> /dev/null || \
- cp -p $$f $$t; }; \
- $${mode:+chmod $$mode $$t}; \
+ LnCp $$f $$t || exit 1; \
+ [ -z "$$mode" ] || chmod $$mode $$t; \
done; :; }
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; \
mkdir -p $$dest; \
[ -s .dirdep ] || echo '${_dirdep}' > .dirdep; \
@@ -89,11 +91,11 @@ STAGE_LINKS_SCRIPT = ${STAGE_DIRDEP_SCRIPT}; StageLinks() { \
shift; \
StageDirdep $$t; \
rm -f $$t 2>/dev/null; \
- ln $$lnf $$l $$t; \
+ ln $$lnf $$l $$t || exit 1; \
done; :; }
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; \
mkdir -p $$dest; \
[ -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; \
shift; \
StageDirdep $$t; \
- rm -f $$t; \
- { ln $$s $$t 2> /dev/null || \
- cp -p $$s $$t; }; \
- $${mode:+chmod $$mode $$t}; \
+ LnCp $$s $$t || exit 1; \
+ [ -z "$$mode" ] || chmod $$mode $$t; \
done; :; }
# 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}
.if !empty(STAGE_INCSDIR)
-CLEANFILES += stage_incs
-
+STAGE_TARGETS += stage_incs
STAGE_INCS ?= ${.ALLSRC:N.dirdep}
stage_incs: .dirdep
@@ -124,7 +123,7 @@ stage_incs: .dirdep
.endif
.if !empty(STAGE_LIBDIR)
-CLEANFILES += stage_libs
+STAGE_TARGETS += stage_libs
STAGE_LIBS ?= ${.ALLSRC:N.dirdep}
@@ -152,7 +151,6 @@ STAGE_SYMLINKS ?= ${.ALLSRC:T:N.dirdep:Nstage_*}
.endif
.if !empty(STAGE_SETS)
-
CLEANFILES += ${STAGE_SETS:@s@stage*$s@}
# some makefiles need to populate multiple directories
@@ -162,6 +160,7 @@ STAGE_SYMLINKS.$s ?= ${.ALLSRC:N.dirdep}
STAGE_LINKS_DIR.$s ?= ${STAGE_OBJTOP}
STAGE_SYMLINKS_DIR.$s ?= ${STAGE_OBJTOP}
+STAGE_TARGETS += stage_files
.if $s != "_default"
stage_files: stage_files.$s
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}
@touch $@
+STAGE_TARGETS += stage_links
.if $s != "_default"
stage_links: stage_links.$s
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}
@touch $@
+STAGE_TARGETS += stage_symlinks
.if $s != "_default"
stage_symlinks: stage_symlinks.$s
stage_symlinks.$s: .dirdep
@@ -195,6 +196,8 @@ stage_symlinks: .dirdep
.if !empty(STAGE_AS_SETS)
CLEANFILES += ${STAGE_AS_SETS:@s@stage*$s@}
+STAGE_TARGETS += stage_as
+
# sometimes things need to be renamed as they are staged
# each ${file} will be staged as ${STAGE_AS_${file:T}}
# one could achieve the same with SYMLINKS
@@ -209,4 +212,20 @@ stage_as.$s: .dirdep
.endfor
.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
diff --git a/mk/meta2deps.py b/mk/meta2deps.py
index cb6d3213b221..6b6157c3ab4c 100755
--- a/mk/meta2deps.py
+++ b/mk/meta2deps.py
@@ -35,9 +35,10 @@ We only pay attention to a subset of the information in the
"""
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
modification, are permitted provided that the following conditions
@@ -149,6 +150,7 @@ class MetaFile:
MACHINE the machine we built for.
set to 'none' if we are not cross-building.
+ More specifically if machine cannot be deduced from objdirs.
HOST_TARGET
when we build for the psuedo machine 'host'
@@ -174,6 +176,11 @@ class MetaFile:
self.debug = getv(conf, 'debug', 0)
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:
# some of the steps below we want to do only once
self.conf = conf
@@ -189,7 +196,24 @@ class MetaFile:
if not _srctop in self.srctops:
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 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:
self.objroots.append(objroot)
_objroot = os.path.realpath(objroot)
@@ -198,6 +222,10 @@ class MetaFile:
if not _objroot in self.objroots:
self.objroots.append(_objroot)
+ # we want the longest match
+ self.srctops.sort(reverse=True)
+ self.objroots.sort(reverse=True)
+
if self.debug:
print >> self.debug_out, "host_target=", self.host_target
print >> self.debug_out, "srctops=", self.srctops
@@ -205,10 +233,6 @@ class MetaFile:
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.debug:
print >> self.debug_out, "need reldir:",
@@ -221,6 +245,8 @@ class MetaFile:
if not self.reldir:
self.dpdeps = None # we cannot do it?
+ self.cwd = os.getcwd() # make sure this is initialized
+
if name:
self.parse()
diff --git a/mk/meta2deps.sh b/mk/meta2deps.sh
index e7ddd829aed4..9c76b77964dd 100755
--- a/mk/meta2deps.sh
+++ b/mk/meta2deps.sh
@@ -77,9 +77,10 @@
# 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
# modification, are permitted provided that the following conditions
diff --git a/mk/sys.dependfile.mk b/mk/sys.dependfile.mk
index 752a46fe8ce1..42cec61fce13 100644
--- a/mk/sys.dependfile.mk
+++ b/mk/sys.dependfile.mk
@@ -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
#
@@ -25,16 +25,20 @@
# All depend file names should start with this
.MAKE.DEPENDFILE_PREFIX ?= Makefile.depend
-# The order of preference: we will use the first one of these we find
-# otherwise the 1st entry will be used by default.
+# The order of preference: we will use the first one of these we find.
+# It usually makes sense to order from most specific to least.
.MAKE.DEPENDFILE_PREFERENCE ?= \
${.CURDIR}/${.MAKE.DEPENDFILE_PREFIX}.${MACHINE} \
${.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:}@}
.if !empty(_e)
.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.
# If any already exist, we should follow suit.
_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]}
.endif
.endif
-.MAKE.DEPENDFILE ?= ${.MAKE.DEPENDFILE_PREFERENCE:[1]}
+.MAKE.DEPENDFILE ?= ${.MAKE.DEPENDFILE_DEFAULT}
diff --git a/parse.c b/parse.c
index 0b18f5d12e68..14c868b1f9d3 100644
--- a/parse.c
+++ b/parse.c
@@ -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
@@ -69,14 +69,14 @@
*/
#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
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)parse.c 8.3 (Berkeley) 3/19/94";
#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 /* not lint */
#endif
@@ -213,6 +213,7 @@ typedef enum {
ExShell, /* .SHELL */
Silent, /* .SILENT */
SingleShell, /* .SINGLESHELL */
+ Stale, /* .STALE */
Suffixes, /* .SUFFIXES */
Wait, /* .WAIT */
Attribute /* Generic attribute */
@@ -336,6 +337,7 @@ static const struct {
{ ".SHELL", ExShell, 0 },
{ ".SILENT", Silent, OP_SILENT },
{ ".SINGLESHELL", SingleShell, 0 },
+{ ".STALE", Stale, 0 },
{ ".SUFFIXES", Suffixes, 0 },
{ ".USE", Attribute, OP_USE },
{ ".USEBEFORE", Attribute, OP_USEBEFORE },
@@ -915,6 +917,8 @@ ParseDoOp(void *gnp, void *opp)
gn->type |= op & ~OP_OPMASK;
cohort = Targ_FindNode(gn->name, TARG_NOHASH);
+ if (doing_depend)
+ ParseMark(cohort);
/*
* Make the cohort invisible as well to avoid duplicating it into
* 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);
gn = Targ_FindNode(wait_src, TARG_NOHASH);
+ if (doing_depend)
+ ParseMark(gn);
gn->type = OP_WAIT | OP_PHONY | OP_DEPENDS | OP_NOTMAIN;
Lst_ForEach(targets, ParseLinkSrc, gn);
return;
@@ -1018,6 +1024,8 @@ ParseDoSrc(int tOp, const char *src)
* source and the current one.
*/
gn = Targ_FindNode(src, TARG_CREATE);
+ if (doing_depend)
+ ParseMark(gn);
if (predecessor != NULL) {
(void)Lst_AtEnd(predecessor->order_succ, gn);
(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 */
gn = Targ_FindNode(src, TARG_CREATE);
+ if (doing_depend)
+ ParseMark(gn);
if (tOp) {
gn->type |= tOp;
} else {
@@ -1294,6 +1304,7 @@ ParseDoDependency(char *line)
* apply the .DEFAULT commands.
* .PHONY The list of targets
* .NOPATH Don't search for file in the path
+ * .STALE
* .BEGIN
* .END
* .ERROR
@@ -1304,42 +1315,45 @@ ParseDoDependency(char *line)
* .ORDER Must set initial predecessor to NULL
*/
switch (specType) {
- case ExPath:
- if (paths == NULL) {
- paths = Lst_Init(FALSE);
- }
- (void)Lst_AtEnd(paths, dirSearchPath);
- break;
- case Main:
- if (!Lst_IsEmpty(create)) {
- specType = Not;
- }
- break;
- case Begin:
- case End:
- case dotError:
- case Interrupt:
- gn = Targ_FindNode(line, TARG_CREATE);
- gn->type |= OP_NOTMAIN|OP_SPECIAL;
- (void)Lst_AtEnd(targets, gn);
- break;
- case Default:
- gn = Targ_NewGN(".DEFAULT");
- gn->type |= (OP_NOTMAIN|OP_TRANSFORM);
- (void)Lst_AtEnd(targets, gn);
- DEFAULT = gn;
- break;
- case NotParallel:
- maxJobs = 1;
- break;
- case SingleShell:
- compatMake = TRUE;
- break;
- case Order:
- predecessor = NULL;
- break;
- default:
- break;
+ case ExPath:
+ if (paths == NULL) {
+ paths = Lst_Init(FALSE);
+ }
+ (void)Lst_AtEnd(paths, dirSearchPath);
+ break;
+ case Main:
+ if (!Lst_IsEmpty(create)) {
+ specType = Not;
+ }
+ break;
+ case Begin:
+ case End:
+ case Stale:
+ case dotError:
+ case Interrupt:
+ gn = Targ_FindNode(line, TARG_CREATE);
+ if (doing_depend)
+ ParseMark(gn);
+ gn->type |= OP_NOTMAIN|OP_SPECIAL;
+ (void)Lst_AtEnd(targets, gn);
+ break;
+ case Default:
+ gn = Targ_NewGN(".DEFAULT");
+ gn->type |= (OP_NOTMAIN|OP_TRANSFORM);
+ (void)Lst_AtEnd(targets, gn);
+ DEFAULT = gn;
+ break;
+ case NotParallel:
+ maxJobs = 1;
+ break;
+ case SingleShell:
+ compatMake = TRUE;
+ break;
+ case Order:
+ predecessor = NULL;
+ break;
+ default:
+ break;
}
} else if (strncmp(line, ".PATH", 5) == 0) {
/*
@@ -1398,6 +1412,8 @@ ParseDoDependency(char *line)
} else {
gn = Suff_AddTransform(targName);
}
+ if (doing_depend)
+ ParseMark(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");
break;
case Default:
+ case Stale:
case Begin:
case End:
case dotError:
@@ -2454,6 +2471,7 @@ ParseGmakeExport(char *line)
"Variable/Value missing from \"export\"");
return;
}
+ *value++ = '\0'; /* terminate variable */
/*
* Expand the value before putting it in the environment.
diff --git a/unit-tests/Makefile.in b/unit-tests/Makefile.in
index a64a07434383..bfd29b261397 100644
--- a/unit-tests/Makefile.in
+++ b/unit-tests/Makefile.in
@@ -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)
# The main targets are:
@@ -28,6 +28,7 @@ SUBFILES= \
error \
export \
export-all \
+ export-env \
doterror \
dotwait \
forloop \
@@ -72,10 +73,12 @@ TOOL_TR?= tr
TOOL_DIFF?= diff
DIFF_FLAGS?= @diff_u@
+.if defined(.PARSEDIR)
# ensure consistent results from sort(1)
LC_ALL= C
LANG= C
.export LANG LC_ALL
+.endif
# The driver.
# We always pretend .MAKE was called 'make'
diff --git a/unit-tests/export-env b/unit-tests/export-env
new file mode 100644
index 000000000000..b6ce6a251cc6
--- /dev/null
+++ b/unit-tests/export-env
@@ -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};@}
+
+
+
+
diff --git a/unit-tests/test.exp b/unit-tests/test.exp
index 368dc3156dbb..b6fad78d21bc 100644
--- a/unit-tests/test.exp
+++ b/unit-tests/test.exp
@@ -43,6 +43,14 @@ UT_OK=good
UT_OKDIR=unit-tests
UT_TEST=export-all
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
happy
and now: sad
diff --git a/var.c b/var.c
index 2e73d5ba753d..c8fd8f50c933 100644
--- a/var.c
+++ b/var.c
@@ -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
@@ -69,14 +69,14 @@
*/
#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
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94";
#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 /* not lint */
#endif
@@ -309,7 +309,6 @@ static char *VarGetPattern(GNode *, Var_Parse_State *,
int, const char **, int, int *, int *,
VarPattern *);
static char *VarQuote(char *);
-static char *VarChangeCase(char *, int);
static char *VarHash(char *);
static char *VarModify(GNode *, Var_Parse_State *,
const char *,
@@ -2350,37 +2349,6 @@ VarHash(char *str)
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 *
VarStrftime(const char *fmt, int zulu)
{
@@ -3057,8 +3025,16 @@ ApplyModifiers(char *nstr, const char *tstr,
VarRealpath, NULL);
cp = tstr + 2;
termc = *cp;
- } else if (tstr[1] == 'u' || tstr[1] == 'l') {
- newStr = VarChangeCase(nstr, (tstr[1] == 'u'));
+ } else if (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;
termc = *cp;
} else if (tstr[1] == 'W' || tstr[1] == 'w') {