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>
* Merge with NetBSD make, pick up

1
FILES
View File

@ -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

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
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

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
.\" 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 .

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
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

View File

@ -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

18
configure vendored
View File

@ -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'`\\"

View File

@ -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

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.
@ -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);
}
}
}

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.
@ -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)

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.
@ -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_ */

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
@ -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

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
.\" 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 .

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
@ -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)

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.
@ -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);
Boolean hasOODATE = FALSE;
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);
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))

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.
@ -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);

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>
* 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
# 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
.info Looking for ${_qm}
.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}
# 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

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
# 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>'; \

View File

@ -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

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
#
@ -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

View File

@ -35,9 +35,10 @@
"""
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 @@ def __init__(self, name, conf={}):
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 @@ def __init__(self, name, conf={}):
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 @@ def __init__(self, name, conf={}):
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 @@ def __init__(self, name, conf={}):
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 @@ def __init__(self, name, conf={}):
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 @@ def __init__(self, name, conf={}):
if not self.reldir:
self.dpdeps = None # we cannot do it?
self.cwd = os.getcwd() # make sure this is initialized
if name:
self.parse()

View File

@ -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

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
#
@ -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}

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
@ -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.

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)
# 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'

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_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

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
@ -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') {