Merge bmake-20100414

This commit is contained in:
joerg 2010-04-20 13:37:49 +00:00
parent ad61420f55
commit 0ee378e1ac
28 changed files with 2881 additions and 4723 deletions

View file

@ -1,3 +1,79 @@
2010-04-14 Simon J. Gerraty <sjg@bad.crufty.net>
* Makefile.in (MAKE_VERSION): bump version to 20100414
* Merge with NetBSD make, pick up
o use realpath to resolve argv[0] (for .MAKE) if needed.
o add realpath from libc.
o add :tA to resolve variable via realpath(3) if possible.
2010-04-08 Simon J. Gerraty <sjg@bad.crufty.net>
* Makefile.in (MAKE_VERSION): bump version to 20100408
* Merge with NetBSD make, pick up
o unit tests for .ERROR, .error
o fix for .ERROR to ensure it cannot be default target.
2010-04-06 Simon J. Gerraty <sjg@bad.crufty.net>
* Makefile.in (MAKE_VERSION): bump version to 20100406
* Merge with NetBSD make, pick up
o fix for compat mode "Error code" going to debug_file.
o fix for .ALLSRC being populated twice.
o support for .info, .warning and .error directives
o .MAKE.MODE to control make's operational mode
o .MAKE.MAKEFILE_PREFERENCE to control the preferred makefile
name(s).
o .MAKE.DEPENDFILE to control the name of the depend file
o .ERROR target - run on failure.
2010-03-18 Simon J. Gerraty <sjg@bad.crufty.net>
* make-bootstrap.sh.in: extract MAKE_VERSION from Makefile
* os.sh,arch.c: patch for Haiku from joerg at netbsd
2010-03-17 Simon J. Gerraty <sjg@bad.crufty.net>
* Makefile.in (MAKE_VERSION): bump version to 20100222
* Merge with NetBSD make, pick up
o better error msg for .for with mutiple inter vars
* boot-strap:
o use make-bootstrap.sh from joerg at netbsd
to avoid the need for a native make when bootstrapping.
o add "" everywhere ;-)
o if /usr/share/tmac/andoc.tmac exists install nroff bmake.1
otherwise the pre-formated version.
2010-01-04 Simon J. Gerraty <sjg@bad.crufty.net>
* Makefile.in (MAKE_VERSION): bump version to 20100102
* Merge with NetBSD make, pick up:
o fix for -m .../
2009-11-18 Simon J. Gerraty <sjg@void.crufty.net>
* Makefile.in (MAKE_VERSION): bump version to 20091118
* Merge with NetBSD make, pick up:
o .unexport
o report lines that start with '.' and should have ':'
(catch typo's of .el*if).
2009-10-30 Simon J. Gerraty <sjg@void.crufty.net>
* configure.in: Ensure that srcdir and mksrc are absolute paths.
2009-10-09 Simon J. Gerraty <sjg@void.crufty.net>
* Makefile.in (MAKE_VERSION): fix version to 20091007
2009-10-07 Simon J. Gerraty <sjg@void.crufty.net>
* Makefile.in (MAKE_VERSION): bump version to 200910007
* Merge with NetBSD make, pick up:
o fix for parsing of :S;...;...; applied to .for loop iterator
appearing in a dependency line.
2009-09-09 Simon J. Gerraty <sjg@void.crufty.net>
* Makefile.in (MAKE_VERSION): bump version to 20090909

View file

@ -30,6 +30,7 @@ hash.h
install-sh
job.c
job.h
realpath.c
strlist.c
strlist.h
trace.c
@ -64,13 +65,13 @@ lst.lib/lstPrev.c
lst.lib/lstRemove.c
lst.lib/lstReplace.c
lst.lib/lstSucc.c
lst.lib/makefile.boot.in
machine.sh
main.c
make.1
bmake.1
make.c
make.h
makefile.boot.in
make-bootstrap.sh.in
missing/sys/cdefs.h
mkdeps.sh
nonints.h
@ -87,12 +88,17 @@ util.c
var.c
wait.h
unit-tests/Makefile.in
unit-tests/cond1
unit-tests/comment
unit-tests/cond1
unit-tests/doterror
unit-tests/dotwait
unit-tests/error
unit-tests/export
unit-tests/export-all
unit-tests/forsubst
unit-tests/moderrs
unit-tests/modmatch
unit-tests/modmisc
unit-tests/modorder
unit-tests/modts
unit-tests/modword
@ -100,6 +106,6 @@ unit-tests/posix
unit-tests/qequals
unit-tests/ternary
unit-tests/test.exp
unit-tests/unexport
unit-tests/unexport-env
unit-tests/varcmd
unit-tests/modmisc
unit-tests/dotwait

View file

@ -1,7 +1,7 @@
# $NetBSD: Makefile.in,v 1.14 2009/09/19 09:01:59 seb Exp $
# $NetBSD: Makefile.in,v 1.15 2010/04/20 13:37:49 joerg Exp $
# @(#)Makefile 5.2 (Berkeley) 12/28/90
# $Id: Makefile.in,v 1.14 2009/09/19 09:01:59 seb Exp $
# $Id: Makefile.in,v 1.15 2010/04/20 13:37:49 joerg Exp $
PROG= bmake
SRCS= arch.c buf.c compat.c cond.c dir.c for.c hash.c job.c main.c \
@ -21,7 +21,7 @@ srcdir= @srcdir@
CC?= @CC@
# Base version on src date
MAKE_VERSION= 20090909
MAKE_VERSION= 20100414
MACHINE=@machine@
MACHINE_ARCH=@machine_arch@
DEFAULT_SYS_PATH = @default_sys_path@

View file

@ -1,4 +1,4 @@
/* $NetBSD: arch.c,v 1.4 2009/09/18 21:27:25 joerg Exp $ */
/* $NetBSD: arch.c,v 1.5 2010/04/20 13:37:49 joerg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@ -69,14 +69,14 @@
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: arch.c,v 1.4 2009/09/18 21:27:25 joerg Exp $";
static char rcsid[] = "$NetBSD: arch.c,v 1.5 2010/04/20 13:37:49 joerg Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)arch.c 8.2 (Berkeley) 1/2/94";
#else
__RCSID("$NetBSD: arch.c,v 1.4 2009/09/18 21:27:25 joerg Exp $");
__RCSID("$NetBSD: arch.c,v 1.5 2010/04/20 13:37:49 joerg Exp $");
#endif
#endif /* not lint */
#endif
@ -139,6 +139,19 @@ __RCSID("$NetBSD: arch.c,v 1.4 2009/09/18 21:27:25 joerg Exp $");
#include <ctype.h>
#ifdef HAVE_AR_H
#include <ar.h>
#else
struct ar_hdr {
char ar_name[16]; /* name */
char ar_date[12]; /* modification time */
char ar_uid[6]; /* user id */
char ar_gid[6]; /* group id */
char ar_mode[8]; /* octal file permissions */
char ar_size[10]; /* size in bytes */
#ifndef ARFMAG
#define ARFMAG "`\n"
#endif
char ar_fmag[2]; /* consistency check */
};
#endif
#if defined(HAVE_RANLIB_H) && !(defined(__ELF__) || defined(NO_RANLIB))
#include <ranlib.h>
@ -204,6 +217,12 @@ static int ArchSVR4Entry(Arch *, char *, size_t, FILE *);
#ifndef AR_FMAG
# define AR_FMAG ar_fmag
#endif
#ifndef ARMAG
# define ARMAG "!<arch>\n"
#endif
#ifndef SARMAG
# define SARMAG 8
#endif
#define AR_MAX_NAME_LEN (sizeof(arh.AR_NAME)-1)

View file

@ -1,4 +1,4 @@
.\" $NetBSD: bmake.1,v 1.3 2009/09/18 21:27:25 joerg Exp $
.\" $NetBSD: bmake.1,v 1.4 2010/04/20 13:37:49 joerg 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 September 7, 2009
.Dd April 14, 2010
.Dt MAKE 1
.Os
.Sh NAME
@ -652,31 +652,13 @@ The preferred variable to use is the environment variable
because it is more compatible with other versions of
.Nm
and cannot be confused with the special target with the same name.
.It Va .MAKE.DEPENDFILE
Names the makefile (default
.Ql Pa .depend )
from which generated dependencies are read.
.It Va .MAKE.EXPORTED
The list of variables exported by
.Nm .
.It Va .MAKE.MAKEFILES
The list of makefiles read by
.Nm ,
which is useful for tracking dependencies.
Each makefile is recorded only once, regardless of the number of times read.
.It Va .MAKE.LEVEL
The recursion depth of
.Nm .
The initial instance of
.Nm
will be 0, and an incremented value is put into the environment
to be seen by the next generation.
This allows tests like:
.Li .if ${.MAKE.LEVEL} == 0
to protect things which should only be evaluated in the initial instance of
.Nm .
.It Va .MAKE.PID
The process-id of
.Nm .
.It Va .MAKE.PPID
The parent process-id of
.Nm .
.It Va .MAKE.JOB.PREFIX
If
.Nm
@ -707,6 +689,38 @@ variable which is then
entered into the environment for all programs which
.Nm
executes.
.It Va .MAKE.LEVEL
The recursion depth of
.Nm .
The initial instance of
.Nm
will be 0, and an incremented value is put into the environment
to be seen by the next generation.
This allows tests like:
.Li .if ${.MAKE.LEVEL} == 0
to protect things which should only be evaluated in the initial instance of
.Nm .
.It Va .MAKE.MAKEFILE_PREFERENCE
The ordered list of makefile names
(default
.Ql Pa makefile ,
.Ql Pa Makefile )
that
.Nm
will look for.
.It Va .MAKE.MAKEFILES
The list of makefiles read by
.Nm ,
which is useful for tracking dependencies.
Each makefile is recorded only once, regardless of the number of times read.
.It Va .MAKE.MODE
Processed after reading all makefiles.
Can affect the mode that
.Nm
runs in.
Currently just
.Ql Pa compat
mode.
.It Va .MAKEOVERRIDES
This variable is used to record the names of variables assigned to
on the command line, so that they may be exported as part of
@ -721,6 +735,12 @@ by appending their names to
is re-exported whenever
.Ql Va .MAKEOVERRIDES
is modified.
.It Va .MAKE.PID
The process-id of
.Nm .
.It Va .MAKE.PPID
The parent process-id of
.Nm .
.It Va MAKE_PRINT_VAR_ON_ERROR
When
.Nm
@ -925,6 +945,10 @@ safely through recursive invocations of
.Nm .
.It Cm \&:R
Replaces each word in the variable with everything but its suffix.
.It Cm \&:tA
Attempt to convert variable to an absolute path using
.Xr realpath 3 ,
if that fails, the value is unchanged.
.It Cm \&:tl
Converts variable to lower-case letters.
.It Cm \&:ts Ns Ar c
@ -934,6 +958,7 @@ This modifier sets the separator to the character
If
.Ar c
is omitted, then no separator is used.
The common escapes (including octal numeric codes), work as expected.
.It Cm \&:tu
Converts variable to upper-case letters.
.It Cm \&:tW
@ -947,10 +972,7 @@ words delimited by white space.
See also
.Ql Cm \&:[@] .
.Sm off
.It Cm \&:S No \&/ Ar old_string Xo
.No \&/ Ar new_string
.No \&/ Op Cm 1gW
.Xc
.It Cm \&:S No \&/ Ar old_string No \&/ Ar new_string No \&/ Op Cm 1gW
.Sm on
Modify the first occurrence of
.Ar old_string
@ -1005,10 +1027,7 @@ of a dollar sign
.Pq Ql \&$ ,
not a preceding dollar sign as is usual.
.Sm off
.It Cm \&:C No \&/ Ar pattern Xo
.No \&/ Ar replacement
.No \&/ Op Cm 1gW
.Xc
.It Cm \&:C No \&/ Ar pattern No \&/ Ar replacement No \&/ Op Cm 1gW
.Sm on
The
.Cm \&:C
@ -1061,8 +1080,11 @@ otherwise return the
Since the variable name is used as the expression, \&:\&? must be the
first modifier after the variable name itself - which will, of course,
usually contain variable expansions.
If the expression is a single token, it will likely be treated as a check
for the name being defined.
A common error is trying to use expressions like
.Dl ${NUMBERS:M42:?match:no}
which actually tests defined(NUMBERS),
to determine is any words match "42" you need to use something like:
.Dl ${${NUMBERS:M42} != "":?match:no} .
.It Ar :old_string=new_string
This is the
.At V
@ -1093,10 +1115,8 @@ expansion of a dollar sign
.Pq Ql \&$ ,
not a preceding dollar sign as is usual.
.Sm off
.It Cm \&:@ Ar temp Cm @ Xo
.Ar string Cm @
.It Cm \&:@ Ar temp Cm @ Ar string Cm @
.Sm on
.Xc
This is the loop expansion mechanism from the OSF Development
Environment (ODE) make.
Unlike
@ -1279,93 +1299,101 @@ Conditional expressions are also preceded by a single dot as the first
character of a line.
The possible conditionals are as follows:
.Bl -tag -width Ds
.It Ic .export Ar variable
.It Ic .error Ar message
The message is printed along with the name of the makefile and line number,
then
.Nm
will exit.
.It Ic .export Ar variable ...
Export the specified global variable.
If no variable is provided, all globals are exported
If no variable list is provided, all globals are exported
except for internal variables (those that start with
.Ql \&. ) .
This is not affected by the
.Fl X
flag, so should be used with caution.
.Pp
Appending a variable name to
.Va .MAKE.EXPORTED
is equivalent to exporting a variable.
.It Ic .info Ar message
The message is printed along with the name of the makefile and line number.
.It Ic .undef Ar variable
Un-define the specified global variable.
Only global variables may be un-defined.
.It Xo
.Ic \&.if
.Oo \&! Oc Ns Ar expression
.Op Ar operator expression ...
.Xc
.It Ic .unexport Ar variable ...
The opposite of
.Ql .export .
The specified global
.Va variable
will be removed from
.Va .MAKE.EXPORTED .
If no variable list is provided, all globals are unexported,
and
.Va .MAKE.EXPORTED
deleted.
.It Ic .unexport-env
Unexport all globals previously exported and
clear the environment inherited from the parent.
This operation will cause a memory leak of the original environment,
so should be used sparingly.
Testing for
.Va .MAKE.LEVEL
being 0, would make sense.
Also note that any variables which originated in the parent environment
should be explicitly preserved if desired.
For example:
.Bd -literal -offset indent
.Li .if ${.MAKE.LEVEL} == 0
PATH := ${PATH}
.Li .unexport-env
.Li .export PATH
.Li .endif
.Pp
.Ed
Would result in an environment containing only
.Ql Ev PATH ,
which is the minimal useful environment.
Actually
.Ql Ev .MAKE.LEVEL
will also be pushed into the new environment.
.It Ic .warning Ar message
The message prefixed by
.Ql Pa warning:
is printed along with the name of the makefile and line number.
.It Ic \&.if Oo \&! Oc Ns Ar expression Op Ar operator expression ...
Test the value of an expression.
.It Xo
.Ic .ifdef
.Oo \&! Oc Ns Ar variable
.Op Ar operator variable ...
.Xc
.It Ic .ifdef Oo \&! Oc Ns Ar variable Op Ar operator variable ...
Test the value of a variable.
.It Xo
.Ic .ifndef
.Oo \&! Oc Ns Ar variable
.Op Ar operator variable ...
.Xc
.It Ic .ifndef Oo \&! Oc Ns Ar variable Op Ar operator variable ...
Test the value of a variable.
.It Xo
.Ic .ifmake
.Oo \&! Oc Ns Ar target
.Op Ar operator target ...
.Xc
.It Ic .ifmake Oo \&! Oc Ns Ar target Op Ar operator target ...
Test the target being built.
.It Xo
.Ic .ifnmake
.Oo \&! Ns Oc Ar target
.Op Ar operator target ...
.Xc
.It Ic .ifnmake Oo \&! Ns Oc Ar target Op Ar operator target ...
Test the target being built.
.It Ic .else
Reverse the sense of the last conditional.
.It Xo
.Ic .elif
.Oo \&! Ns Oc Ar expression
.Op Ar operator expression ...
.Xc
.It Ic .elif Oo \&! Ns Oc Ar expression Op Ar operator expression ...
A combination of
.Ql Ic .else
followed by
.Ql Ic .if .
.It Xo
.Ic .elifdef
.Oo \&! Oc Ns Ar variable
.Op Ar operator variable ...
.Xc
.It Ic .elifdef Oo \&! Oc Ns Ar variable Op Ar operator variable ...
A combination of
.Ql Ic .else
followed by
.Ql Ic .ifdef .
.It Xo
.Ic .elifndef
.Oo \&! Oc Ns Ar variable
.Op Ar operator variable ...
.Xc
.It Ic .elifndef Oo \&! Oc Ns Ar variable Op Ar operator variable ...
A combination of
.Ql Ic .else
followed by
.Ql Ic .ifndef .
.It Xo
.Ic .elifmake
.Oo \&! Oc Ns Ar target
.Op Ar operator target ...
.Xc
.It Ic .elifmake Oo \&! Oc Ns Ar target Op Ar operator target ...
A combination of
.Ql Ic .else
followed by
.Ql Ic .ifmake .
.It Xo
.Ic .elifnmake
.Oo \&! Oc Ns Ar target
.Op Ar operator target ...
.Xc
.It Ic .elifnmake Oo \&! Oc Ns Ar target Op Ar operator target ...
A combination of
.Ql Ic .else
followed by
@ -1485,13 +1513,7 @@ For loops are typically used to apply a set of rules to a list of files.
The syntax of a for loop is:
.Pp
.Bl -tag -compact -width Ds
.It Xo
.Ic \&.for
.Ar variable
.Op Ar variable ...
.Ic in
.Ar expression
.Xc
.It Ic \&.for Ar variable Oo Ar variable ... Oc Ic in Ar expression
.It Aq make-rules
.It Ic \&.endfor
.El
@ -1641,6 +1663,13 @@ to the target's own name.
.It Ic .END
Any command lines attached to this target are executed after everything
else is done.
.It Ic .ERROR
Any command lines attached to this target are executed when another target fails.
The
.Ic .ERROR_TARGET
variable is set to the target that failed.
See also
.Ic MAKE_PRINT_VAR_ON_ERROR .
.It Ic .IGNORE
Mark each of the sources with the
.Ic .IGNORE
@ -1764,10 +1793,10 @@ character when used outside of any quoting characters.
.El
Example:
.Bd -literal
\&.SHELL: name=ksh path=/bin/ksh hasErrCtl=true \\
check="set -e" ignore="set +e" \\
echo="set -v" quiet="set +v" filter="set +v" \\
echoFlag=v errFlag=e newline="'\\n'"
\&.SHELL: name=ksh path=/bin/ksh hasErrCtl=true \e
check="set -e" ignore="set +e" \e
echo="set -v" quiet="set +v" filter="set +v" \e
echoFlag=v errFlag=e newline="'\en'"
.Ed
.It Ic .SILENT
Apply the

View file

@ -395,24 +395,12 @@ VVAARRIIAABBLLEE AASSSSIIGGNNMMEENNTTSS
bbmmaakkee and cannot be confused with the special target with
the same name.
_._M_A_K_E_._D_E_P_E_N_D_F_I_L_E
Names the makefile (default `_._d_e_p_e_n_d') from which gener-
ated dependencies are read.
_._M_A_K_E_._E_X_P_O_R_T_E_D The list of variables exported by bbmmaakkee.
_._M_A_K_E_._M_A_K_E_F_I_L_E_S
The list of makefiles read by bbmmaakkee, which is useful for
tracking dependencies. Each makefile is recorded only
once, regardless of the number of times read.
_._M_A_K_E_._L_E_V_E_L The recursion depth of bbmmaakkee. The initial instance of
bbmmaakkee will be 0, and an incremented value is put into the
environment to be seen by the next generation. This
allows tests like: .if ${.MAKE.LEVEL} == 0 to protect
things which should only be evaluated in the initial
instance of bbmmaakkee.
_._M_A_K_E_._P_I_D The process-id of bbmmaakkee.
_._M_A_K_E_._P_P_I_D The parent process-id of bbmmaakkee.
_._M_A_K_E_._J_O_B_._P_R_E_F_I_X
If bbmmaakkee is run with _j then output for each target is
prefixed with a token `--- target ---' the first part of
@ -429,6 +417,25 @@ VVAARRIIAABBLLEE AASSSSIIGGNNMMEENNTTSS
`MAKEFLAGS' variable which is then entered into the envi-
ronment for all programs which bbmmaakkee executes.
_._M_A_K_E_._L_E_V_E_L The recursion depth of bbmmaakkee. The initial instance of
bbmmaakkee will be 0, and an incremented value is put into the
environment to be seen by the next generation. This
allows tests like: .if ${.MAKE.LEVEL} == 0 to protect
things which should only be evaluated in the initial
instance of bbmmaakkee.
_._M_A_K_E_._M_A_K_E_F_I_L_E___P_R_E_F_E_R_E_N_C_E
The ordered list of makefile names (default `_m_a_k_e_f_i_l_e',
`_M_a_k_e_f_i_l_e') that bbmmaakkee will look for.
_._M_A_K_E_._M_A_K_E_F_I_L_E_S
The list of makefiles read by bbmmaakkee, which is useful for
tracking dependencies. Each makefile is recorded only
once, regardless of the number of times read.
_._M_A_K_E_._M_O_D_E Processed after reading all makefiles. Can affect the
mode that bbmmaakkee runs in. Currently just `_c_o_m_p_a_t' mode.
_._M_A_K_E_O_V_E_R_R_I_D_E_S This variable is used to record the names of variables
assigned to on the command line, so that they may be
exported as part of `MAKEFLAGS'. This behaviour can be
@ -438,6 +445,10 @@ 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_I_D The process-id of bbmmaakkee.
_._M_A_K_E_._P_P_I_D The parent process-id of bbmmaakkee.
_M_A_K_E___P_R_I_N_T___V_A_R___O_N___E_R_R_O_R
When bbmmaakkee stops due to an error, it prints its name and
the value of `_._C_U_R_D_I_R' as well as the value of any vari-
@ -572,12 +583,16 @@ VVAARRIIAABBLLEE AASSSSIIGGNNMMEENNTTSS
::RR Replaces each word in the variable with everything but its suffix.
::ttAA Attempt to convert variable to an absolute path using realpath(3),
if that fails, the value is unchanged.
::ttll Converts variable to lower-case letters.
::ttss_c
Words in the variable are normally separated by a space on expan-
sion. This modifier sets the separator to the character _c. If _c is
omitted, then no separator is used.
omitted, then no separator is used. The common escapes (including
octal numeric codes), work as expected.
::ttuu Converts variable to upper-case letters.
@ -633,8 +648,12 @@ VVAARRIIAABBLLEE AASSSSIIGGNNMMEENNTTSS
_t_r_u_e___s_t_r_i_n_g, otherwise return the _f_a_l_s_e___s_t_r_i_n_g. Since the variable
name is used as the expression, :? must be the first modifier after
the variable name itself - which will, of course, usually contain
variable expansions. If the expression is a single token, it will
likely be treated as a check for the name being defined.
variable expansions. A common error is trying to use expressions
like
${NUMBERS:M42:?match:no}
which actually tests defined(NUMBERS), to determine is any words
match "42" you need to use something like:
${${NUMBERS:M42} != :?match:no}.
_:_o_l_d___s_t_r_i_n_g_=_n_e_w___s_t_r_i_n_g
This is the AT&T System V UNIX style variable substitution. It must
@ -756,17 +775,54 @@ IINNCCLLUUDDEE SSTTAATTEEMMEENNTTSS,, CCOONNDDIITTIIOO
Conditional expressions are also preceded by a single dot as the first
character of a line. The possible conditionals are as follows:
..eexxppoorrtt _v_a_r_i_a_b_l_e
Export the specified global variable. If no variable is pro-
vided, all globals are exported except for internal variables
..eerrrroorr _m_e_s_s_a_g_e
The message is printed along with the name of the makefile and
line number, then bbmmaakkee will exit.
..eexxppoorrtt _v_a_r_i_a_b_l_e _._._.
Export the specified global variable. If no variable list is
provided, all globals are exported except for internal variables
(those that start with `.'). This is not affected by the --XX
flag, so should be used with caution. Appending a variable name
to _._M_A_K_E_._E_X_P_O_R_T_E_D is equivalent to exporting a variable.
flag, so should be used with caution.
Appending a variable name to _._M_A_K_E_._E_X_P_O_R_T_E_D is equivalent to
exporting a variable.
..iinnffoo _m_e_s_s_a_g_e
The message is printed along with the name of the makefile and
line number.
..uunnddeeff _v_a_r_i_a_b_l_e
Un-define the specified global variable. Only global variables
may be un-defined.
..uunneexxppoorrtt _v_a_r_i_a_b_l_e _._._.
The opposite of `.export'. The specified global _v_a_r_i_a_b_l_e will be
removed from _._M_A_K_E_._E_X_P_O_R_T_E_D. If no variable list is provided,
all globals are unexported, and _._M_A_K_E_._E_X_P_O_R_T_E_D deleted.
..uunneexxppoorrtt--eennvv
Unexport all globals previously exported and clear the environ-
ment inherited from the parent. This operation will cause a mem-
ory leak of the original environment, so should be used spar-
ingly. Testing for _._M_A_K_E_._L_E_V_E_L being 0, would make sense. Also
note that any variables which originated in the parent environ-
ment should be explicitly preserved if desired. For example:
.if ${.MAKE.LEVEL} == 0
PATH := ${PATH}
.unexport-env
.export PATH
.endif
Would result in an environment containing only `PATH', which is
the minimal useful environment. Actually `.MAKE.LEVEL' will also
be pushed into the new environment.
..wwaarrnniinngg _m_e_s_s_a_g_e
The message prefixed by `_w_a_r_n_i_n_g_:' is printed along with the name
of the makefile and line number.
..iiff [!]_e_x_p_r_e_s_s_i_o_n [_o_p_e_r_a_t_o_r _e_x_p_r_e_s_s_i_o_n _._._.]
Test the value of an expression.
@ -965,6 +1021,10 @@ SSPPEECCIIAALL TTAARRGGEETTSS
..EENNDD Any command lines attached to this target are executed after
everything else is done.
..EERRRROORR Any command lines attached to this target are executed when
another target fails. The ..EERRRROORR__TTAARRGGEETT variable is set to the
target that failed. See also MMAAKKEE__PPRRIINNTT__VVAARR__OONN__EERRRROORR.
..IIGGNNOORREE Mark each of the sources with the ..IIGGNNOORREE attribute. If no
sources are specified, this is the equivalent of specifying the
--ii option.
@ -1104,4 +1164,4 @@ HHIISSTTOORRYY
bbmmaakkee is derived from NetBSD's make(1). It uses autoconf to facilitate
portability to other platforms.
NetBSD 5.0 September 7, 2009 NetBSD 5.0
NetBSD 5.0 April 14, 2010 NetBSD 5.0

View file

@ -56,7 +56,7 @@
# Simon J. Gerraty <sjg@crufty.net>
# RCSid:
# $Id: boot-strap,v 1.5 2009/09/18 21:27:25 joerg Exp $
# $Id: boot-strap,v 1.6 2010/04/20 13:37:49 joerg Exp $
#
# @(#) Copyright (c) 2001 Simon J. Gerraty
#
@ -72,10 +72,10 @@
#
Mydir=`dirname $0`
. $Mydir/os.sh
case $Mydir in
. "$Mydir/os.sh"
case "$Mydir" in
/*) ;;
*) Mydir=`cd $Mydir; /bin/pwd`;;
*) Mydir=`cd "$Mydir" && 'pwd'`;;
esac
@ -92,49 +92,50 @@ Error() {
}
source_rc() {
rc=$1; shift
rc="$1"; shift
for d in ${*:-""}
do
r=${d:+$d/}$rc
[ -f $r -a -s $r ] || continue
r="${d:+$d/}$rc"
[ -f "$r" -a -s "$r" ] || continue
echo "NOTE: reading $r"
. $r
. "$r"
break
done
}
CONFIGURE_ARGS=
# pick a useful default prefix (for me at least ;-)
for prefix in /opt/$HOST_TARGET $HOME/$HOST_TARGET /usr/pkg /usr/local ""
for prefix in /opt/$HOST_TARGET "$HOME/$HOST_TARGET" /usr/pkg /usr/local ""
do
[ -d ${prefix:-.} ] && break
[ -d "${prefix:-.}" ] && break
done
srcdir=
mksrc=
objdir=
quiet=:
source_rc .bmake-boot-strap.rc . $Mydir/.. $HOME
source_rc .bmake-boot-strap.rc . "$Mydir/.." "$HOME"
while :
do
case "$1" in
--) shift; break;;
--prefix) prefix=$2; shift 2;;
--prefix=*) prefix=`IFS="="; set -- $1; echo $2`; shift;;
--src=*) srcdir=`IFS="="; set -- $1; echo $2`; shift;;
--with-mksrc=*|--mksrc=*) mksrc=`IFS="="; set -- $1; echo $2`; shift;;
--share=*) share_dir=`IFS="="; set -- $1; echo $2`; shift;;
--share) share_dir=$2; shift 2;;
-s|--src) srcdir=$2; shift 2;;
-m|--mksrc) mksrc=$2; shift 2;;
-o|--objdir) objdir=$2; shift 2;;
-q) quiet=; shift;;
-c) source_rc $2; shift 2;;
--*) CONFIGURE_ARGS="$CONFIGURE_ARGS $1"; shift;;
*=*) eval "$1"; export `IFS="="; set -- $1; echo $1`; shift;;
--prefix) prefix="$2"; shift;;
--prefix=*) prefix=`IFS="="; set -- "$1"; echo "$2"`;;
--src=*) srcdir=`IFS="="; set -- "$1"; echo "$2"`;;
--with-mksrc=*|--mksrc=*) mksrc=`IFS="="; set -- "$1"; echo "$2"`;;
--share=*) share_dir=`IFS="="; set -- "$1"; echo "$2"`;;
--share) share_dir="$2"; shift;;
-s|--src) srcdir="$2"; shift;;
-m|--mksrc) mksrc="$2"; shift;;
-o|--objdir) objdir="$2"; shift;;
-q) quiet=;;
-c) source_rc "$2"; shift;;
--*) CONFIGURE_ARGS="$CONFIGURE_ARGS $1";;
*=*) eval "$1"; export `IFS="="; set -- "$1"; echo "$1"`;;
*) break;;
esac
shift
done
AddConfigure() {
@ -145,47 +146,49 @@ AddConfigure() {
}
GetDir() {
match=$1
match="$1"
shift
for dir in $*
do
[ -d $dir ] || continue
[ -d "$dir" ] || continue
case "/$dir/" in
*$match*) ;;
*) continue;;
esac
case "$dir/" in
*./*) cd $dir && /bin/pwd;;
*./*) cd "$dir" && 'pwd';;
/*) echo $dir;;
*) cd $dir && /bin/pwd;;
*) cd "$dir" && 'pwd';;
esac
break
done
}
srcdir=`GetDir /bmake $srcdir $2 $Mydir ./bmake* $Mydir/../bmake*`
[ -d ${srcdir:-/dev/null} ] || Usage
srcdir=`GetDir /bmake "$srcdir" "$2" "$Mydir" ./bmake* "$Mydir"/../bmake*`
[ -d "${srcdir:-/dev/null}" ] || Usage
case "$mksrc" in
none|-) # we don't want it
mksrc=
;;
*) # guess we want mksrc...
mksrc=`GetDir /mk $mksrc $3 ./mk* $srcdir/mk* $srcdir/../mk*`
[ -d ${mksrc:-/dev/null} ] || Usage "Use '-m none' to build without mksrc"
mksrc=`GetDir /mk "$mksrc" "$3" ./mk* "$srcdir"/mk* "$srcdir"/../mk*`
[ -d "${mksrc:-/dev/null}" ] || Usage "Use '-m none' to build without mksrc"
;;
esac
# Ok, get to work...
objdir=${objdir:-$OS}
[ -d $objdir ] || mkdir -p $objdir
[ -d $objdir ] || mkdir $objdir
cd $objdir || exit 1
objdir="${objdir:-$OS}"
[ -d "$objdir" ] || mkdir -p "$objdir"
[ -d "$objdir" ] || mkdir "$objdir"
cd "$objdir" || exit 1
# make it absolute
objdir=`'pwd'`
ShareDir() {
case "/$1" in
*/$HOST_TARGET)
if [ -d $1/../share ]; then
echo `dirname $1`/share
if [ -d "$1/../share" ]; then
echo `dirname "$1"`/share
return
fi
;;
@ -193,29 +196,46 @@ ShareDir() {
echo $1/share
}
share_dir=${share_dir:-`ShareDir $prefix`}
share_dir="${share_dir:-`ShareDir $prefix`}"
AddConfigure --prefix= $prefix
AddConfigure --prefix= "$prefix"
case "$CONFIGURE_ARGS" in
*--with-prefix-sys-path*) ;; # skip
*) AddConfigure --with-default-sys-path= $share_dir/mk;;
*) AddConfigure --with-default-sys-path= "$share_dir/mk";;
esac
if [ "$mksrc" ]; then
AddConfigure --with-mksrc= $mksrc
AddConfigure --with-mksrc= "$mksrc"
# not all cc's support this
export CFLAGS_MF=
fi
$srcdir/configure $CONFIGURE_ARGS || exit 1
${MAKE:-make} -f makefile.boot clean
${MAKE:-make} -f makefile.boot bootstrap || exit 1
chmod 755 make-bootstrap.sh || exit 1
./make-bootstrap.sh || exit 1
MAKESYSPATH="$share_dir/mk:/usr/share/mk"
if [ -s "${mksrc:-/dev/null}/install-mk" ]; then
sh "${mksrc}/install-mk" "$objdir/mk"
MAKESYSPATH=".../mk:${MAKESYSPATH}"
fi
export MAKESYSPATH
./bmake test || exit 1
# If -q given, we don't want all the install instructions
$quiet exit 0
make_version=`./bmake -m ./mk -m $share_dir/mk -m /usr/share/mk -f ./Makefile -V MAKE_VERSION | ( read one two; echo $one )`
make_version=`./bmake -f ./Makefile -V MAKE_VERSION | ( read one two; echo $one )`
bmake_version=bmake-$make_version
if [ -s /usr/share/tmac/andoc.tmac ]; then
# this should be ok
man_subdir=man1
man_src=$srcdir/bmake.1
else
# guess not
man_subdir=cat1
man_src=$srcdir/bmake.cat1
fi
install_prefix() {
(
bin_dir=
@ -230,7 +250,7 @@ install_prefix() {
esac
done
bin_dir=${bin_dir:-$1/bin}
share_dir=${share_dir:-`ShareDir $1`}
share_dir=${share_dir:-`ShareDir "$1"`}
man_dir=${man_dir:-$share_dir/man}
mk_dir=${mk_dir:-$share_dir/mk}
echo
@ -240,13 +260,8 @@ install_prefix() {
echo cp $objdir/bmake $bin_dir/$bmake_version
echo rm -f $bin_dir/bmake
echo ln -s $bmake_version $bin_dir/bmake
if [ -s bmake.cat1 ]; then
echo mkdir -p $man_dir/man1
echo cp $srcdir/bmake.1 $man_dir/man1
else
echo mkdir -p $man_dir/cat1
echo cp $srcdir/bmake.cat1 $man_dir/cat1/bmake.1
fi
echo mkdir -p $man_dir/$man_subdir
echo cp $man_src $man_dir/$man_subdir/bmake.1
if [ "$mksrc" ]; then
ev=`env | grep '_MK='`
echo $ev sh $mksrc/install-mk $mk_dir
@ -254,14 +269,14 @@ install_prefix() {
)
}
case $prefix/ in
$HOME/*) ;;
case "$prefix/" in
"$HOME"/*) ;;
*) CONFIGS=${CONFIGS:-/configs}
[ -d $CONFIGS ] &&
install_prefix mksrc= $CONFIGS/$OS/$OSMAJOR.X/$MACHINE_ARCH$prefix
install_prefix mksrc= "$CONFIGS/$OS/$OSMAJOR.X/$MACHINE_ARCH$prefix"
# I like to keep a copy here...
install_prefix share_dir=$HOME/share $HOME/$HOST_TARGET
install_prefix share_dir="$HOME/share" "$HOME/$HOST_TARGET"
;;
esac
install_prefix $prefix
install_prefix "$prefix"

View file

@ -1,4 +1,4 @@
/* $NetBSD: compat.c,v 1.5 2009/09/18 21:27:25 joerg Exp $ */
/* $NetBSD: compat.c,v 1.6 2010/04/20 13:37:49 joerg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@ -70,14 +70,14 @@
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: compat.c,v 1.5 2009/09/18 21:27:25 joerg Exp $";
static char rcsid[] = "$NetBSD: compat.c,v 1.6 2010/04/20 13:37:49 joerg Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)compat.c 8.2 (Berkeley) 3/19/94";
#else
__RCSID("$NetBSD: compat.c,v 1.5 2009/09/18 21:27:25 joerg Exp $");
__RCSID("$NetBSD: compat.c,v 1.6 2010/04/20 13:37:49 joerg Exp $");
#endif
#endif /* not lint */
#endif
@ -410,7 +410,7 @@ again:
}
fprintf(debug_file, "\n");
}
fprintf(debug_file, "*** Error code %d", status);
printf("*** Error code %d", status);
}
} else {
status = WTERMSIG(reason); /* signaled */
@ -577,7 +577,7 @@ Compat_Make(void *gnp, void *pgnp)
} else if (keepgoing) {
pgn->flags &= ~REMAKE;
} else {
PrintOnError("\n\nStop.");
PrintOnError(gn, "\n\nStop.");
exit(1);
}
} else if (gn->made == ERROR) {
@ -668,7 +668,7 @@ Compat_Run(Lst targs)
if (gn != NULL) {
Compat_Make(gn, gn);
if (gn->made == ERROR) {
PrintOnError("\n\nStop.");
PrintOnError(gn, "\n\nStop.");
exit(1);
}
}
@ -709,7 +709,7 @@ Compat_Run(Lst targs)
if (errors == 0) {
Compat_Make(ENDNode, ENDNode);
if (gn->made == ERROR) {
PrintOnError("\n\nStop.");
PrintOnError(gn, "\n\nStop.");
exit(1);
}
}

View file

@ -1,4 +1,4 @@
/* $NetBSD: cond.c,v 1.5 2009/09/18 21:27:25 joerg Exp $ */
/* $NetBSD: cond.c,v 1.6 2010/04/20 13:37:49 joerg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@ -70,14 +70,14 @@
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: cond.c,v 1.5 2009/09/18 21:27:25 joerg Exp $";
static char rcsid[] = "$NetBSD: cond.c,v 1.6 2010/04/20 13:37:49 joerg Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)cond.c 8.2 (Berkeley) 1/2/94";
#else
__RCSID("$NetBSD: cond.c,v 1.5 2009/09/18 21:27:25 joerg Exp $");
__RCSID("$NetBSD: cond.c,v 1.6 2010/04/20 13:37:49 joerg Exp $");
#endif
#endif /* not lint */
#endif
@ -124,16 +124,20 @@ __RCSID("$NetBSD: cond.c,v 1.5 2009/09/18 21:27:25 joerg Exp $");
* is applied.
*
* Tokens are scanned from the 'condExpr' string. The scanner (CondToken)
* will return TOK_AND for '&' and '&&', TOK_OR for '|' and '||', TOK_NOT for '!',
* TOK_LPAREN for '(', TOK_RPAREN for ')' and will evaluate the other terminal
* symbols, using either the default function or the function given in the
* terminal, and return the result as either TOK_TRUE or TOK_FALSE.
* will return TOK_AND for '&' and '&&', TOK_OR for '|' and '||',
* TOK_NOT for '!', TOK_LPAREN for '(', TOK_RPAREN for ')' and will evaluate
* the other terminal symbols, using either the default function or the
* function given in the terminal, and return the result as either TOK_TRUE
* or TOK_FALSE.
*
* All Non-Terminal functions (CondE, CondF and CondT) return TOK_ERROR on error.
* TOK_FALSE is 0 and TOK_TRUE 1 so we can directly assign C comparisons.
*
* All Non-Terminal functions (CondE, CondF and CondT) return TOK_ERROR on
* error.
*/
typedef enum {
TOK_AND, TOK_OR, TOK_NOT, TOK_TRUE, TOK_FALSE, TOK_LPAREN, TOK_RPAREN,
TOK_EOF, TOK_NONE, TOK_ERROR
TOK_FALSE = 0, TOK_TRUE = 1, TOK_AND, TOK_OR, TOK_NOT,
TOK_LPAREN, TOK_RPAREN, TOK_EOF, TOK_NONE, TOK_ERROR
} Token;
/*-
@ -678,21 +682,21 @@ compare_expression(Boolean doEval)
}
/* For .ifxxx "..." check for non-empty string. */
if (lhsQuoted) {
t = lhs[0] != 0 ? TOK_TRUE : TOK_FALSE;
t = lhs[0] != 0;
goto done;
}
/* For .ifxxx <number> compare against zero */
if (CondCvtArg(lhs, &left)) {
t = left != 0.0 ? TOK_TRUE : TOK_FALSE;
t = left != 0.0;
goto done;
}
/* For .if ${...} check for non-empty string (defProc is ifdef). */
if (if_info->form[0] == 0) {
t = lhs[0] != 0 ? TOK_TRUE : TOK_FALSE;
t = lhs[0] != 0;
goto done;
}
/* Otherwise action default test ... */
t = if_info->defProc(strlen(lhs), lhs) != if_info->doNot ? TOK_TRUE : TOK_FALSE;
t = if_info->defProc(strlen(lhs), lhs) != if_info->doNot;
goto done;
}
@ -726,9 +730,9 @@ do_string_compare:
* t is set to the result.
*/
if (*op == '=') {
t = strcmp(lhs, rhs) ? TOK_FALSE : TOK_TRUE;
t = strcmp(lhs, rhs) == 0;
} else {
t = strcmp(lhs, rhs) ? TOK_TRUE : TOK_FALSE;
t = strcmp(lhs, rhs) != 0;
}
} else {
/*
@ -750,7 +754,7 @@ do_string_compare:
"Unknown operator");
goto done;
}
t = (left != right ? TOK_TRUE : TOK_FALSE);
t = (left != right);
break;
case '=':
if (op[1] != '=') {
@ -758,20 +762,20 @@ do_string_compare:
"Unknown operator");
goto done;
}
t = (left == right ? TOK_TRUE : TOK_FALSE);
t = (left == right);
break;
case '<':
if (op[1] == '=') {
t = (left <= right ? TOK_TRUE : TOK_FALSE);
t = (left <= right);
} else {
t = (left < right ? TOK_TRUE : TOK_FALSE);
t = (left < right);
}
break;
case '>':
if (op[1] == '=') {
t = (left >= right ? TOK_TRUE : TOK_FALSE);
t = (left >= right);
} else {
t = (left > right ? TOK_TRUE : TOK_FALSE);
t = (left > right);
}
break;
}
@ -872,7 +876,7 @@ compare_function(Boolean doEval)
return arglen < 0 ? TOK_ERROR : TOK_FALSE;
}
/* Evaluate the argument using the required function. */
t = !doEval || fn_def->fn_proc(arglen, arg) ? TOK_TRUE : TOK_FALSE;
t = !doEval || fn_def->fn_proc(arglen, arg);
if (arg)
free(arg);
condExpr = cp;
@ -905,7 +909,7 @@ compare_function(Boolean doEval)
* after .if must have been taken literally, so the argument cannot
* be empty - even if it contained a variable expansion.
*/
t = !doEval || if_info->defProc(arglen, arg) != if_info->doNot ? TOK_TRUE : TOK_FALSE;
t = !doEval || if_info->defProc(arglen, arg) != if_info->doNot;
if (arg)
free(arg);
return t;

View file

@ -1,5 +1,8 @@
/* config.h.in. Generated from configure.in by autoheader. */
/* Define if building universal (internal helper macro) */
#undef AC_APPLE_UNIVERSAL_BUILD
/* Path of default shell */
#undef DEFSHELL_CUSTOM
@ -62,6 +65,9 @@
/* Define to 1 if you have the <ranlib.h> header file. */
#undef HAVE_RANLIB_H
/* Define to 1 if you have the `realpath' function. */
#undef HAVE_REALPATH
/* Define to 1 if you have the `select' function. */
#undef HAVE_SELECT
@ -101,7 +107,7 @@
/* Define to 1 if you have the `strtol' function. */
#undef HAVE_STRTOL
/* Define to 1 if `st_rdev' is member of `struct stat'. */
/* Define to 1 if `struct stat' is a member of `st_rdev'. */
#undef HAVE_STRUCT_STAT_ST_RDEV
/* Define to 1 if your `struct stat' has `st_rdev'. Deprecated, use
@ -188,6 +194,9 @@
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the home page for this package. */
#undef PACKAGE_URL
/* Define to the version of this package. */
#undef PACKAGE_VERSION
@ -206,24 +215,6 @@
/* Define to 1 if your <sys/time.h> declares `struct tm'. */
#undef TM_IN_SYS_TIME
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel and VAX). */
#if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
#elif ! defined __LITTLE_ENDIAN__
# undef WORDS_BIGENDIAN
#endif
/* Define to 1 if on MINIX. */
#undef _MINIX
/* Define to 2 if the system does not provide POSIX.1 features except with
this defined. */
#undef _POSIX_1_SOURCE
/* Define to 1 if you need to in order for `stat' and other things to work. */
#undef _POSIX_SOURCE
/* Enable extensions on AIX 3, Interix. */
#ifndef _ALL_SOURCE
# undef _ALL_SOURCE
@ -246,6 +237,28 @@
#endif
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
# undef WORDS_BIGENDIAN
# endif
#endif
/* Define to 1 if on MINIX. */
#undef _MINIX
/* Define to 2 if the system does not provide POSIX.1 features except with
this defined. */
#undef _POSIX_1_SOURCE
/* Define to 1 if you need to in order for `stat' and other things to work. */
#undef _POSIX_SOURCE
/* Define to empty if `const' does not conform to ANSI C. */
#undef const

File diff suppressed because it is too large Load diff

View file

@ -1,10 +1,10 @@
dnl
dnl RCSid:
dnl $Id: configure.in,v 1.9 2009/09/18 21:27:25 joerg Exp $
dnl $Id: configure.in,v 1.10 2010/04/20 13:37:49 joerg Exp $
dnl
dnl Process this file with autoconf to produce a configure script
dnl
AC_INIT(makefile.boot.in)
AC_INIT([bmake], [20100414], [sjg@NetBSD.org])
AC_CONFIG_HEADER(config.h)
dnl
@ -115,8 +115,12 @@ AC_CHECK_FUNCS( \
wait4 \
waitpid \
)
dnl AC_REPLACE_FUNCS(setenv getenv)
AC_REPLACE_FUNCS(getenv)
dnl functions which we may need to provide
AC_REPLACE_FUNCS( \
getenv \
realpath \
)
AC_CHECK_LIB([util], [emalloc],
[ AC_CHECK_LIB([util], [erealloc],
@ -265,9 +269,12 @@ esac
dnl
dnl Now make sure we have a value
dnl
srcdir=`cd $srcdir && pwd`
for mksrc in $mksrc $srcdir/mk $srcdir/../mk mk
do
test -s $mksrc/install-mk && break
test -s $mksrc/install-mk || continue
mksrc=`cd $mksrc && pwd`
break
done
mksrc=`echo $mksrc | sed "s,$srcdir,\\\${srcdir},"`
echo "Using: MKSRC=$mksrc" 1>&6
@ -291,23 +298,14 @@ AC_SUBST(default_sys_path)
AC_SUBST(INSTALL)
AC_SUBST(GCC)
AC_SUBST(diff_u)
AC_OUTPUT(Makefile makefile.boot lst.lib/makefile.boot unit-tests/Makefile)
AC_OUTPUT(Makefile make-bootstrap.sh unit-tests/Makefile)
cat <<EOF
You can now run
make -f makefile.boot bootstrap
./make-bootstrap.sh
to produce a fully functional bmake. You can then use:
make -f makefile.boot install
for an initial installation. If you already have macros installed
you can use:
./bmake -f Makefile
to install etc.
to produce a fully functional bmake.
EOF

View file

@ -1,4 +1,4 @@
/* $NetBSD: for.c,v 1.4 2009/09/18 21:27:25 joerg Exp $ */
/* $NetBSD: for.c,v 1.5 2010/04/20 13:37:49 joerg Exp $ */
/*
* Copyright (c) 1992, The Regents of the University of California.
@ -30,14 +30,14 @@
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: for.c,v 1.4 2009/09/18 21:27:25 joerg Exp $";
static char rcsid[] = "$NetBSD: for.c,v 1.5 2010/04/20 13:37:49 joerg Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)for.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: for.c,v 1.4 2009/09/18 21:27:25 joerg Exp $");
__RCSID("$NetBSD: for.c,v 1.5 2010/04/20 13:37:49 joerg Exp $");
#endif
#endif /* not lint */
#endif
@ -237,7 +237,8 @@ For_Eval(char *line)
if (strlist_num(&new_for->items) % strlist_num(&new_for->vars)) {
Parse_Error(PARSE_FATAL,
"Wrong number of words in .for substitution list %d %d",
"Wrong number of words (%d) in .for substitution list"
" with %d vars",
strlist_num(&new_for->items), strlist_num(&new_for->vars));
/*
* Return 'success' so that the body of the .for loop is accumulated.

View file

@ -1,4 +1,4 @@
/* $NetBSD: job.c,v 1.8 2009/09/18 21:27:25 joerg Exp $ */
/* $NetBSD: job.c,v 1.9 2010/04/20 13:37:49 joerg 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.8 2009/09/18 21:27:25 joerg Exp $";
static char rcsid[] = "$NetBSD: job.c,v 1.9 2010/04/20 13:37:49 joerg 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.8 2009/09/18 21:27:25 joerg Exp $");
__RCSID("$NetBSD: job.c,v 1.9 2010/04/20 13:37:49 joerg Exp $");
#endif
#endif /* not lint */
#endif
@ -1239,8 +1239,8 @@ 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 .depend for %s\n",
progname, gn->name);
fprintf(stdout, "%s: ignoring stale %s for %s\n",
progname, makeDependfile, gn->name);
return TRUE;
}
@ -1911,7 +1911,7 @@ JobRun(GNode *targ)
#else
Compat_Make(targ, targ);
if (targ->made == ERROR) {
PrintOnError("\n\nStop.");
PrintOnError(targ, "\n\nStop.");
exit(1);
}
#endif
@ -2241,7 +2241,7 @@ Job_Init(void)
if (begin != NULL) {
JobRun(begin);
if (begin->made == ERROR) {
PrintOnError("\n\nStop.");
PrintOnError(begin, "\n\nStop.");
exit(1);
}
}

View file

@ -1,10 +0,0 @@
# $NetBSD: Makefile,v 1.2 2008/03/09 19:54:29 joerg Exp $
OBJ=lstAppend.o lstDupl.o lstInit.o lstOpen.o lstAtEnd.o lstEnQueue.o \
lstInsert.o lstAtFront.o lstIsAtEnd.o lstClose.o lstFind.o lstIsEmpty.o \
lstRemove.o lstConcat.o lstFindFrom.o lstLast.o lstReplace.o lstFirst.o \
lstDatum.o lstForEach.o lstMember.o lstSucc.o lstDeQueue.o \
lstForEachFrom.o lstDestroy.o lstNext.o lstPrev.o
CPPFLAGS=-I${.CURDIR}/..
all: ${OBJ}

View file

@ -1,44 +0,0 @@
# RCSid:
# $Id: makefile.boot.in,v 1.4 2008/03/09 19:54:29 joerg Exp $
srcdir=@srcdir@
VPATH=.:$(srcdir)
OBJ=lstAppend.o lstDupl.o lstInit.o lstOpen.o lstAtEnd.o lstEnQueue.o \
lstInsert.o lstAtFront.o lstIsAtEnd.o lstClose.o lstFind.o lstIsEmpty.o \
lstRemove.o lstConcat.o lstFindFrom.o lstLast.o lstReplace.o lstFirst.o \
lstDatum.o lstForEach.o lstMember.o lstSucc.o lstDeQueue.o \
lstForEachFrom.o lstDestroy.o lstNext.o lstPrev.o
CFLAGS=@CFLAGS@ -I..
all: ${OBJ}
depend:
VPATH=${VPATH} ${MKDEP} -f makefile.boot ${CFLAGS} ${OBJ:.o=.c}
#lstAppend.o: $(srcdir)/lstAppend.c
#lstDupl.o: $(srcdir)/lstDupl.c
#lstInit.o: $(srcdir)/lstInit.c
#lstOpen.o: $(srcdir)/lstOpen.c
#lstAtEnd.o: $(srcdir)/lstAtEnd.c
#lstEnQueue.o: $(srcdir)/lstEnQueue.c
#lstInsert.o: $(srcdir)/lstInsert.c
#lstAtFront.o: $(srcdir)/lstAtFront.c
#lstIsAtEnd.o: $(srcdir)/lstIsAtEnd.c
#lstClose.o: $(srcdir)/lstClose.c
#lstFind.o: $(srcdir)/lstFind.c
#lstIsEmpty.o: $(srcdir)/lstIsEmpty.c
#lstRemove.o: $(srcdir)/lstRemove.c
#lstConcat.o: $(srcdir)/lstConcat.c
#lstFindFrom.o: $(srcdir)/lstFindFrom.c
#lstLast.o: $(srcdir)/lstLast.c
#lstReplace.o: $(srcdir)/lstReplace.c
#lstFirst.o: $(srcdir)/lstFirst.c
#lstDatum.o: $(srcdir)/lstDatum.c
#lstForEach.o: $(srcdir)/lstForEach.c
#lstMember.o: $(srcdir)/lstMember.c
#lstSucc.o: $(srcdir)/lstSucc.c
#lstDeQueue.o: $(srcdir)/lstDeQueue.c
#lstForEachFrom.o: $(srcdir)/lstForEachFrom.c
#lstDestroy.o: $(srcdir)/lstDestroy.c
#lstNext.o: $(srcdir)/lstNext.c

View file

@ -1,4 +1,4 @@
/* $NetBSD: main.c,v 1.6 2009/09/18 21:27:25 joerg Exp $ */
/* $NetBSD: main.c,v 1.7 2010/04/20 13:37:49 joerg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@ -69,7 +69,7 @@
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: main.c,v 1.6 2009/09/18 21:27:25 joerg Exp $";
static char rcsid[] = "$NetBSD: main.c,v 1.7 2010/04/20 13:37:49 joerg 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.6 2009/09/18 21:27:25 joerg Exp $");
__RCSID("$NetBSD: main.c,v 1.7 2010/04/20 13:37:49 joerg Exp $");
#endif
#endif /* not lint */
#endif
@ -186,6 +186,7 @@ static Boolean ignorePWD; /* if we use -C, PWD is meaningless */
static char curdir[MAXPATHLEN + 1]; /* startup directory */
static char objdir[MAXPATHLEN + 1]; /* where we chdir'ed to */
char *progname; /* the program name */
char *makeDependfile;
Boolean forceJobs = FALSE;
@ -404,6 +405,10 @@ rearg:
strerror(errno));
exit(1);
}
if (getcwd(curdir, MAXPATHLEN) == NULL) {
(void)fprintf(stderr, "%s: %s.\n", progname, strerror(errno));
exit(2);
}
ignorePWD = TRUE;
break;
case 'D':
@ -520,7 +525,6 @@ rearg:
found_path, sizeof(found_path)))
break; /* nothing doing */
(void)Dir_AddDir(sysIncPath, found_path);
} else {
(void)Dir_AddDir(sysIncPath, argvalue);
}
@ -706,6 +710,22 @@ ReadAllMakefiles(const void *p, const void *q)
return (ReadMakefile(p, q) == 0);
}
static int
str2Lst_Append(Lst lp, char *str, const char *sep)
{
char *cp;
int n;
if (!sep)
sep = " \t";
for (n = 0, cp = strtok(str, sep); cp; cp = strtok(NULL, sep)) {
(void)Lst_AtEnd(lp, cp);
n++;
}
return (n);
}
#ifdef SIGINFO
/*ARGSUSED*/
static void
@ -722,6 +742,27 @@ siginfo(int signo)
}
#endif
/*
* Allow makefiles some control over the mode we run in.
*/
void
MakeMode(const char *mode)
{
char *mp = NULL;
if (!mode)
mode = mp = Var_Subst(NULL, "${" MAKE_MODE ":tl}", VAR_GLOBAL, 0);
if (mode && *mode) {
if (strstr(mode, "compat")) {
compatMake = TRUE;
forceJobs = FALSE;
}
}
if (mp)
free(mp);
}
/*-
* main --
* The main function, for obvious reasons. Initializes variables
@ -843,6 +884,15 @@ main(int argc, char **argv)
Var_Set("MAKE_VERSION", MAKE_VERSION, VAR_GLOBAL, 0);
#endif
Var_Set(".newline", "\n", VAR_GLOBAL, 0); /* handy for :@ loops */
/*
* This is the traditional preference for makefiles.
*/
#ifndef MAKEFILE_PREFERENCE_LIST
# define MAKEFILE_PREFERENCE_LIST "makefile Makefile"
#endif
Var_Set(MAKEFILE_PREFERENCE, MAKEFILE_PREFERENCE_LIST,
VAR_GLOBAL, 0);
Var_Set(MAKE_DEPENDFILE, ".depend", VAR_GLOBAL, 0);
create = Lst_Init(FALSE);
makefiles = Lst_Init(FALSE);
@ -878,8 +928,16 @@ main(int argc, char **argv)
* MFLAGS also gets initialized empty, for compatibility.
*/
Parse_Init();
Var_Set("MAKE", argv[0], VAR_GLOBAL, 0);
Var_Set(".MAKE", argv[0], VAR_GLOBAL, 0);
if (argv[0][0] == '/') {
p1 = argv[0];
} else {
p1 = realpath(argv[0], mdpath);
if (!p1 || *p1 != '/') {
p1 = argv[0]; /* realpath failed */
}
}
Var_Set("MAKE", p1, VAR_GLOBAL, 0);
Var_Set(".MAKE", p1, VAR_GLOBAL, 0);
Var_Set(MAKEFLAGS, "", VAR_GLOBAL, 0);
Var_Set(MAKEOVERRIDES, "", VAR_GLOBAL, 0);
Var_Set("MFLAGS", "", VAR_GLOBAL, 0);
@ -914,18 +972,20 @@ main(int argc, char **argv)
Main_ParseArgLine(getenv("MAKE"));
#endif
MainParseArgs(argc, argv);
/*
* Find where we are (now) and take care of PWD for the automounter...
* All this code is so that we know where we are when we start up
* on a different machine with pmake.
* Find where we are (now).
* We take care of PWD for the automounter below...
*/
if (getcwd(curdir, MAXPATHLEN) == NULL) {
(void)fprintf(stderr, "%s: %s.\n", progname, strerror(errno));
exit(2);
}
MainParseArgs(argc, argv);
/*
* Verify that cwd is sane.
*/
if (stat(curdir, &sa) == -1) {
(void)fprintf(stderr, "%s: %s: %s.\n",
progname, curdir, strerror(errno));
@ -933,6 +993,8 @@ main(int argc, char **argv)
}
/*
* All this code is so that we know where we are when we start up
* on a different machine with pmake.
* Overriding getcwd() with $PWD totally breaks MAKEOBJDIRPREFIX
* since the value of curdir can vary depending on how we got
* here. Ie sitting at a shell prompt (shell that provides $PWD)
@ -1079,16 +1141,27 @@ main(int argc, char **argv)
if (ln != NULL)
Fatal("%s: cannot open %s.", progname,
(char *)Lst_Datum(ln));
} else if (ReadMakefile("makefile", NULL) != 0)
(void)ReadMakefile("Makefile", NULL);
} else {
p1 = Var_Subst(NULL, "${" MAKEFILE_PREFERENCE "}",
VAR_CMD, 0);
if (p1) {
(void)str2Lst_Append(makefiles, p1, NULL);
(void)Lst_Find(makefiles, NULL, ReadMakefile);
free(p1);
}
}
/* In particular suppress .depend for '-r -V .OBJDIR -f /dev/null' */
if (!noBuiltins || !printVars) {
makeDependfile = Var_Subst(NULL, "${.MAKE.DEPENDFILE:T}",
VAR_CMD, 0);
doing_depend = TRUE;
(void)ReadMakefile(".depend", NULL);
(void)ReadMakefile(makeDependfile, NULL);
doing_depend = FALSE;
}
MakeMode(NULL);
Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1), VAR_GLOBAL);
if (p1)
free(p1);
@ -1248,14 +1321,11 @@ ReadMakefile(const void *p, const void *q __unused)
int fd;
size_t len = MAXPATHLEN;
char *name, *path = bmake_malloc(len);
int setMAKEFILE;
if (!strcmp(fname, "-")) {
Parse_File("(stdin)", dup(fileno(stdin)));
Var_Set("MAKEFILE", "", VAR_GLOBAL, 0);
} else {
setMAKEFILE = strcmp(fname, ".depend");
/* if we've chdir'd, rebuild the path name */
if (strcmp(curdir, objdir) && *fname != '/') {
size_t plen = strlen(curdir) + strlen(fname) + 2;
@ -1302,7 +1372,7 @@ ReadMakefile(const void *p, const void *q __unused)
* makefile specified, as it is set by SysV make.
*/
found:
if (setMAKEFILE)
if (!doing_depend)
Var_Set("MAKEFILE", fname, VAR_GLOBAL, 0);
Parse_File(fname, fd);
}
@ -1713,7 +1783,7 @@ Fatal(const char *fmt, ...)
(void)fprintf(stderr, "\n");
(void)fflush(stderr);
PrintOnError(NULL);
PrintOnError(NULL, NULL);
if (DEBUG(GRAPH2) || DEBUG(GRAPH3))
Targ_PrintGraph(2);
@ -1745,7 +1815,7 @@ Punt(const char *fmt, ...)
(void)fprintf(stderr, "\n");
(void)fflush(stderr);
PrintOnError(NULL);
PrintOnError(NULL, NULL);
DieHorribly();
}
@ -1866,8 +1936,9 @@ PrintAddr(void *a, void *b)
void
PrintOnError(const char *s)
PrintOnError(GNode *gn, const char *s)
{
static GNode *en = NULL;
char tmp[64];
char *cp;
@ -1875,6 +1946,24 @@ PrintOnError(const char *s)
printf("%s", s);
printf("\n%s: stopped in %s\n", progname, curdir);
if (en)
return; /* we've been here! */
if (gn) {
/*
* We can print this even if there is no .ERROR target.
*/
Var_Set(".ERROR_TARGET", gn->name, VAR_GLOBAL, 0);
}
/*
* See if there is a .ERROR target, and run it if so.
*/
en = Targ_FindNode(".ERROR", TARG_NOCREATE);
if (en) {
en->type |= OP_SPECIAL;
Compat_Make(en, en);
}
strncpy(tmp, "${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'\n@}",
sizeof(tmp) - 1);
cp = Var_Subst(NULL, tmp, VAR_GLOBAL, 0);

View file

@ -1,4 +1,4 @@
.\" $NetBSD: make.1,v 1.4 2009/09/18 21:27:25 joerg Exp $
.\" $NetBSD: make.1,v 1.5 2010/04/20 13:37:49 joerg 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 September 7, 2009
.Dd April 14, 2010
.Dt MAKE 1
.Os
.Sh NAME
@ -652,31 +652,13 @@ The preferred variable to use is the environment variable
because it is more compatible with other versions of
.Nm
and cannot be confused with the special target with the same name.
.It Va .MAKE.DEPENDFILE
Names the makefile (default
.Ql Pa .depend )
from which generated dependencies are read.
.It Va .MAKE.EXPORTED
The list of variables exported by
.Nm .
.It Va .MAKE.MAKEFILES
The list of makefiles read by
.Nm ,
which is useful for tracking dependencies.
Each makefile is recorded only once, regardless of the number of times read.
.It Va .MAKE.LEVEL
The recursion depth of
.Nm .
The initial instance of
.Nm
will be 0, and an incremented value is put into the environment
to be seen by the next generation.
This allows tests like:
.Li .if ${.MAKE.LEVEL} == 0
to protect things which should only be evaluated in the initial instance of
.Nm .
.It Va .MAKE.PID
The process-id of
.Nm .
.It Va .MAKE.PPID
The parent process-id of
.Nm .
.It Va .MAKE.JOB.PREFIX
If
.Nm
@ -707,6 +689,38 @@ variable which is then
entered into the environment for all programs which
.Nm
executes.
.It Va .MAKE.LEVEL
The recursion depth of
.Nm .
The initial instance of
.Nm
will be 0, and an incremented value is put into the environment
to be seen by the next generation.
This allows tests like:
.Li .if ${.MAKE.LEVEL} == 0
to protect things which should only be evaluated in the initial instance of
.Nm .
.It Va .MAKE.MAKEFILE_PREFERENCE
The ordered list of makefile names
(default
.Ql Pa makefile ,
.Ql Pa Makefile )
that
.Nm
will look for.
.It Va .MAKE.MAKEFILES
The list of makefiles read by
.Nm ,
which is useful for tracking dependencies.
Each makefile is recorded only once, regardless of the number of times read.
.It Va .MAKE.MODE
Processed after reading all makefiles.
Can affect the mode that
.Nm
runs in.
Currently just
.Ql Pa compat
mode.
.It Va .MAKEOVERRIDES
This variable is used to record the names of variables assigned to
on the command line, so that they may be exported as part of
@ -721,6 +735,12 @@ by appending their names to
is re-exported whenever
.Ql Va .MAKEOVERRIDES
is modified.
.It Va .MAKE.PID
The process-id of
.Nm .
.It Va .MAKE.PPID
The parent process-id of
.Nm .
.It Va MAKE_PRINT_VAR_ON_ERROR
When
.Nm
@ -925,6 +945,10 @@ safely through recursive invocations of
.Nm .
.It Cm \&:R
Replaces each word in the variable with everything but its suffix.
.It Cm \&:tA
Attempt to convert variable to an absolute path using
.Xr realpath 3 ,
if that fails, the value is unchanged.
.It Cm \&:tl
Converts variable to lower-case letters.
.It Cm \&:ts Ns Ar c
@ -934,6 +958,7 @@ This modifier sets the separator to the character
If
.Ar c
is omitted, then no separator is used.
The common escapes (including octal numeric codes), work as expected.
.It Cm \&:tu
Converts variable to upper-case letters.
.It Cm \&:tW
@ -947,10 +972,7 @@ words delimited by white space.
See also
.Ql Cm \&:[@] .
.Sm off
.It Cm \&:S No \&/ Ar old_string Xo
.No \&/ Ar new_string
.No \&/ Op Cm 1gW
.Xc
.It Cm \&:S No \&/ Ar old_string No \&/ Ar new_string No \&/ Op Cm 1gW
.Sm on
Modify the first occurrence of
.Ar old_string
@ -1005,10 +1027,7 @@ of a dollar sign
.Pq Ql \&$ ,
not a preceding dollar sign as is usual.
.Sm off
.It Cm \&:C No \&/ Ar pattern Xo
.No \&/ Ar replacement
.No \&/ Op Cm 1gW
.Xc
.It Cm \&:C No \&/ Ar pattern No \&/ Ar replacement No \&/ Op Cm 1gW
.Sm on
The
.Cm \&:C
@ -1061,8 +1080,11 @@ otherwise return the
Since the variable name is used as the expression, \&:\&? must be the
first modifier after the variable name itself - which will, of course,
usually contain variable expansions.
If the expression is a single token, it will likely be treated as a check
for the name being defined.
A common error is trying to use expressions like
.Dl ${NUMBERS:M42:?match:no}
which actually tests defined(NUMBERS),
to determine is any words match "42" you need to use something like:
.Dl ${${NUMBERS:M42} != "":?match:no} .
.It Ar :old_string=new_string
This is the
.At V
@ -1093,10 +1115,8 @@ expansion of a dollar sign
.Pq Ql \&$ ,
not a preceding dollar sign as is usual.
.Sm off
.It Cm \&:@ Ar temp Cm @ Xo
.Ar string Cm @
.It Cm \&:@ Ar temp Cm @ Ar string Cm @
.Sm on
.Xc
This is the loop expansion mechanism from the OSF Development
Environment (ODE) make.
Unlike
@ -1279,93 +1299,101 @@ Conditional expressions are also preceded by a single dot as the first
character of a line.
The possible conditionals are as follows:
.Bl -tag -width Ds
.It Ic .export Ar variable
.It Ic .error Ar message
The message is printed along with the name of the makefile and line number,
then
.Nm
will exit.
.It Ic .export Ar variable ...
Export the specified global variable.
If no variable is provided, all globals are exported
If no variable list is provided, all globals are exported
except for internal variables (those that start with
.Ql \&. ) .
This is not affected by the
.Fl X
flag, so should be used with caution.
.Pp
Appending a variable name to
.Va .MAKE.EXPORTED
is equivalent to exporting a variable.
.It Ic .info Ar message
The message is printed along with the name of the makefile and line number.
.It Ic .undef Ar variable
Un-define the specified global variable.
Only global variables may be un-defined.
.It Xo
.Ic \&.if
.Oo \&! Oc Ns Ar expression
.Op Ar operator expression ...
.Xc
.It Ic .unexport Ar variable ...
The opposite of
.Ql .export .
The specified global
.Va variable
will be removed from
.Va .MAKE.EXPORTED .
If no variable list is provided, all globals are unexported,
and
.Va .MAKE.EXPORTED
deleted.
.It Ic .unexport-env
Unexport all globals previously exported and
clear the environment inherited from the parent.
This operation will cause a memory leak of the original environment,
so should be used sparingly.
Testing for
.Va .MAKE.LEVEL
being 0, would make sense.
Also note that any variables which originated in the parent environment
should be explicitly preserved if desired.
For example:
.Bd -literal -offset indent
.Li .if ${.MAKE.LEVEL} == 0
PATH := ${PATH}
.Li .unexport-env
.Li .export PATH
.Li .endif
.Pp
.Ed
Would result in an environment containing only
.Ql Ev PATH ,
which is the minimal useful environment.
Actually
.Ql Ev .MAKE.LEVEL
will also be pushed into the new environment.
.It Ic .warning Ar message
The message prefixed by
.Ql Pa warning:
is printed along with the name of the makefile and line number.
.It Ic \&.if Oo \&! Oc Ns Ar expression Op Ar operator expression ...
Test the value of an expression.
.It Xo
.Ic .ifdef
.Oo \&! Oc Ns Ar variable
.Op Ar operator variable ...
.Xc
.It Ic .ifdef Oo \&! Oc Ns Ar variable Op Ar operator variable ...
Test the value of a variable.
.It Xo
.Ic .ifndef
.Oo \&! Oc Ns Ar variable
.Op Ar operator variable ...
.Xc
.It Ic .ifndef Oo \&! Oc Ns Ar variable Op Ar operator variable ...
Test the value of a variable.
.It Xo
.Ic .ifmake
.Oo \&! Oc Ns Ar target
.Op Ar operator target ...
.Xc
.It Ic .ifmake Oo \&! Oc Ns Ar target Op Ar operator target ...
Test the target being built.
.It Xo
.Ic .ifnmake
.Oo \&! Ns Oc Ar target
.Op Ar operator target ...
.Xc
.It Ic .ifnmake Oo \&! Ns Oc Ar target Op Ar operator target ...
Test the target being built.
.It Ic .else
Reverse the sense of the last conditional.
.It Xo
.Ic .elif
.Oo \&! Ns Oc Ar expression
.Op Ar operator expression ...
.Xc
.It Ic .elif Oo \&! Ns Oc Ar expression Op Ar operator expression ...
A combination of
.Ql Ic .else
followed by
.Ql Ic .if .
.It Xo
.Ic .elifdef
.Oo \&! Oc Ns Ar variable
.Op Ar operator variable ...
.Xc
.It Ic .elifdef Oo \&! Oc Ns Ar variable Op Ar operator variable ...
A combination of
.Ql Ic .else
followed by
.Ql Ic .ifdef .
.It Xo
.Ic .elifndef
.Oo \&! Oc Ns Ar variable
.Op Ar operator variable ...
.Xc
.It Ic .elifndef Oo \&! Oc Ns Ar variable Op Ar operator variable ...
A combination of
.Ql Ic .else
followed by
.Ql Ic .ifndef .
.It Xo
.Ic .elifmake
.Oo \&! Oc Ns Ar target
.Op Ar operator target ...
.Xc
.It Ic .elifmake Oo \&! Oc Ns Ar target Op Ar operator target ...
A combination of
.Ql Ic .else
followed by
.Ql Ic .ifmake .
.It Xo
.Ic .elifnmake
.Oo \&! Oc Ns Ar target
.Op Ar operator target ...
.Xc
.It Ic .elifnmake Oo \&! Oc Ns Ar target Op Ar operator target ...
A combination of
.Ql Ic .else
followed by
@ -1485,13 +1513,7 @@ For loops are typically used to apply a set of rules to a list of files.
The syntax of a for loop is:
.Pp
.Bl -tag -compact -width Ds
.It Xo
.Ic \&.for
.Ar variable
.Op Ar variable ...
.Ic in
.Ar expression
.Xc
.It Ic \&.for Ar variable Oo Ar variable ... Oc Ic in Ar expression
.It Aq make-rules
.It Ic \&.endfor
.El
@ -1641,6 +1663,13 @@ to the target's own name.
.It Ic .END
Any command lines attached to this target are executed after everything
else is done.
.It Ic .ERROR
Any command lines attached to this target are executed when another target fails.
The
.Ic .ERROR_TARGET
variable is set to the target that failed.
See also
.Ic MAKE_PRINT_VAR_ON_ERROR .
.It Ic .IGNORE
Mark each of the sources with the
.Ic .IGNORE
@ -1764,10 +1793,10 @@ character when used outside of any quoting characters.
.El
Example:
.Bd -literal
\&.SHELL: name=ksh path=/bin/ksh hasErrCtl=true \\
check="set -e" ignore="set +e" \\
echo="set -v" quiet="set +v" filter="set +v" \\
echoFlag=v errFlag=e newline="'\\n'"
\&.SHELL: name=ksh path=/bin/ksh hasErrCtl=true \e
check="set -e" ignore="set +e" \e
echo="set -v" quiet="set +v" filter="set +v" \e
echoFlag=v errFlag=e newline="'\en'"
.Ed
.It Ic .SILENT
Apply the

View file

@ -1,4 +1,4 @@
/* $NetBSD: make.c,v 1.3 2009/09/18 21:27:25 joerg Exp $ */
/* $NetBSD: make.c,v 1.4 2010/04/20 13:37:49 joerg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@ -69,14 +69,14 @@
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: make.c,v 1.3 2009/09/18 21:27:25 joerg Exp $";
static char rcsid[] = "$NetBSD: make.c,v 1.4 2010/04/20 13:37:49 joerg Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)make.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: make.c,v 1.3 2009/09/18 21:27:25 joerg Exp $");
__RCSID("$NetBSD: make.c,v 1.4 2010/04/20 13:37:49 joerg Exp $");
#endif
#endif /* not lint */
#endif
@ -958,6 +958,9 @@ MakeAddAllSrc(void *cgnp, void *pgnp)
void
Make_DoAllVar(GNode *gn)
{
if (gn->flags & DONE_ALLSRC)
return;
Lst_ForEach(gn->children, MakeUnmark, gn);
Lst_ForEach(gn->children, MakeAddAllSrc, gn);
@ -974,6 +977,7 @@ Make_DoAllVar(GNode *gn)
if (p1)
free(p1);
}
gn->flags |= DONE_ALLSRC;
}
/*-

View file

@ -1,4 +1,4 @@
/* $NetBSD: make.h,v 1.3 2009/09/18 21:27:25 joerg Exp $ */
/* $NetBSD: make.h,v 1.4 2010/04/20 13:37:49 joerg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@ -180,6 +180,7 @@ typedef struct GNode {
#define DONE_WAIT 0x8 /* Set by Make_ProcessWait() */
#define DONE_ORDER 0x10 /* Build requested by .ORDER processing */
#define FROM_DEPEND 0x20 /* Node created from .depend */
#define DONE_ALLSRC 0x40 /* We do it once only */
#define CYCLE 0x1000 /* Used by MakePrintStatus */
#define DONECYCLE 0x2000 /* Used by MakePrintStatus */
enum enum_made {
@ -408,6 +409,7 @@ extern Lst sysIncPath; /* The system include path. */
extern Lst defIncPath; /* The default include path. */
extern char *progname; /* The program name */
extern char *makeDependfile; /* .depend */
#define MAKEFLAGS ".MAKEFLAGS"
#define MAKEOVERRIDES ".MAKEOVERRIDES"
@ -415,6 +417,9 @@ extern char *progname; /* The program name */
#define MAKE_EXPORTED ".MAKE.EXPORTED" /* variables we export */
#define MAKE_MAKEFILES ".MAKE.MAKEFILES" /* all the makefiles we read */
#define MAKE_LEVEL ".MAKE.LEVEL" /* recursion level */
#define MAKEFILE_PREFERENCE ".MAKE.MAKEFILE_PREFERENCE"
#define MAKE_DEPENDFILE ".MAKE.DEPENDFILE" /* .depend */
#define MAKE_MODE ".MAKE.MODE"
/*
* debug control:
@ -458,7 +463,7 @@ void Make_DoAllVar(GNode *);
Boolean Make_Run(Lst);
char * Check_Cwd_Cmd(const char *);
void Check_Cwd(const char **);
void PrintOnError(const char *);
void PrintOnError(GNode *, const char *);
void Main_ExportMAKEFLAGS(Boolean);
Boolean Main_SetObjdir(const char *);

View file

@ -1,84 +0,0 @@
# RCSid:
# $Id: makefile.boot.in,v 1.8 2009/09/18 21:27:25 joerg Exp $
#
# modify MACHINE and MACHINE_ARCH as appropriate for your target architecture
#
prefix=@prefix@
srcdir=@srcdir@
VPATH=.:$(srcdir)
CC=@CC@
INSTALL=$(srcdir)/install-sh
MKDEP=$(srcdir)/mkdeps.sh -n -i/usr/include
MKDEP_OPTS=-A
MK=${prefix}/share/mk
MKSRC=@mksrc@
# this is what we build into bmake
DEFAULT_SYS_PATH = @default_sys_path@
# this is what we might use during bootstrap
BOOTSTRAP_SYS_PATH= `pwd`/mk:${MK}:${MKSRC}:${DEFAULT_SYS_PATH}:/usr/share/mk:/usr/local/share/mk:/opt/share/mk
CFLAGS= @CFLAGS@ -I. -I$(srcdir) @DEFS@ @CPPFLAGS@ ${XDEFS} \
-D_PATH_DEFSYSPATH=\"${DEFAULT_SYS_PATH}\"
MDEFS="-D@force_machine@MACHINE=\"@machine@\"" "-DMACHINE_ARCH=\"@machine_arch@\""
OBJ=arch.o buf.o compat.o cond.o dir.o for.o hash.o job.o main.o make.o \
parse.o str.o suff.o targ.o trace.o var.o util.o getopt.o sigcompat.o \
strlist.o make_malloc.o \
@LIBOBJS@
BMAKE_ENV= CC="$(CC)" LIBC= MAKEFLAGS= MAKESYSPATH=${BOOTSTRAP_SYS_PATH}
bootstrap: bmake.boot .mk.done
${BMAKE_ENV} ./bmake.boot -f Makefile
${BMAKE_ENV} ./bmake.boot -f Makefile bmake.1
${BMAKE_ENV} `pwd`/bmake -f Makefile test
bmake: bmake.boot
@echo you might want to try:
@echo ${MAKE} -f makefile.boot bootstrap
cp bmake.boot $@
bmake.boot: ${OBJ}
(cd lst.lib; $(MAKE) -f makefile.boot CC="$(CC)" CFLAGS="-I.. -I../${srcdir} -I${srcdir} ${CFLAGS}" )
${CC} *.o lst.lib/*.o -o $@ @LDFLAGS@ @LIBS@
rm -f *.[ado] */*.[ado]
.mk.done:
@if test -s ${MKSRC}/install-mk; then \
sh ${MKSRC}/install-mk -v -m 644 `pwd`/mk ${USE_OS}; \
elif test ! -s /usr/share/mk/sys.mk -a ! -s ${MK}/sys.mk; then \
echo need to unpack mk.tar.gz under ${srcdir} or set MKSRC or MK; false; \
fi
@touch $@
install: install-bin install-man install-mk
install-bin:
test -d ${prefix}/bin || ${INSTALL} -m 755 -d ${prefix}/bin
${INSTALL} -m 755 bmake ${prefix}/bin
install-man:
test -d ${prefix}/man/cat1 || ${INSTALL} -m 755 -d ${prefix}/man/cat1
${INSTALL} -m 444 ${srcdir}/bmake.cat1 ${prefix}/man/cat1/bmake.1
install-mk:
@if test -s ${MKSRC}/install-mk; then \
test -d ${DESTDIR}${MK} || ${INSTALL} -m 775 -d ${DESTDIR}${MK}; \
sh ${MKSRC}/install-mk -v -m 644 ${DESTDIR}${MK} ${USE_OS}; \
else \
echo need to unpack mk.tar.gz under ${srcdir} or set MKSRC; false; \
fi
depend:
VPATH=${VPATH} ${MKDEP} $(MKDEP_OPTS) -f makefile.boot ${CFLAGS} ${OBJ:.o=.c}
(cd lst.lib; $(MAKE) -f makefile.boot depend MKDEP="$(MKDEP) $(MKDEP_OPTS)" CC="$(CC)" CFLAGS="-I.. ${CFLAGS}" )
main.o: $(srcdir)/main.c
${CC} ${CFLAGS} ${MDEFS} -o $@ -c $(srcdir)/main.c
${OBJ}: config.h
clean:
rm -f bmake *.[ado] */*.[ado] .*.done .depend

View file

@ -1,4 +1,4 @@
/* $NetBSD: nonints.h,v 1.4 2009/09/18 21:27:25 joerg Exp $ */
/* $NetBSD: nonints.h,v 1.5 2010/04/20 13:37:49 joerg Exp $ */
/*-
* Copyright (c) 1988, 1989, 1990, 1993
@ -108,6 +108,7 @@ void For_Run(int);
/* main.c */
void Main_ParseArgLine(const char *);
void MakeMode(const char *);
int main(int, char **);
char *Cmd_Exec(const char *, const char **);
void Error(const char *, ...) __attribute__((__format__(__printf__, 1, 2)));
@ -193,3 +194,4 @@ void Var_End(void);
void Var_Dump(GNode *);
void Var_ExportVars(void);
void Var_Export(char *, int);
void Var_UnExport(char *);

View file

@ -17,7 +17,7 @@
# Simon J. Gerraty <sjg@crufty.net>
# RCSid:
# $Id: os.sh,v 1.3 2008/03/09 19:54:29 joerg Exp $
# $Id: os.sh,v 1.4 2010/04/20 13:37:49 joerg Exp $
#
# @(#) Copyright (c) 1994 Simon J. Gerraty
#
@ -177,6 +177,13 @@ QNX)
x86pc) MACHINE_ARCH=i386;;
esac
;;
Haiku)
case $MACHINE in
BeBox) MACHINE_ARCH=powerpc;;
BeMac) MACHINE_ARCH=powerpc;;
BePC) MACHINE_ARCH=i386;;
esac
;;
esac
HOSTNAME=${HOSTNAME:-`( hostname ) 2>/dev/null`}

View file

@ -1,4 +1,4 @@
/* $NetBSD: parse.c,v 1.5 2009/09/18 21:27:25 joerg Exp $ */
/* $NetBSD: parse.c,v 1.6 2010/04/20 13:37:49 joerg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@ -69,14 +69,14 @@
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: parse.c,v 1.5 2009/09/18 21:27:25 joerg Exp $";
static char rcsid[] = "$NetBSD: parse.c,v 1.6 2010/04/20 13:37:49 joerg 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.5 2009/09/18 21:27:25 joerg Exp $");
__RCSID("$NetBSD: parse.c,v 1.6 2010/04/20 13:37:49 joerg Exp $");
#endif
#endif /* not lint */
#endif
@ -191,6 +191,7 @@ typedef enum {
Begin, /* .BEGIN */
Default, /* .DEFAULT */
End, /* .END */
dotError, /* .ERROR */
Ignore, /* .IGNORE */
Includes, /* .INCLUDES */
Interrupt, /* .INTERRUPT */
@ -245,6 +246,7 @@ static struct {
{ ".BEGIN", Begin, 0 },
{ ".DEFAULT", Default, 0 },
{ ".END", End, 0 },
{ ".ERROR", dotError, 0 },
{ ".EXEC", Attribute, OP_EXEC },
{ ".IGNORE", Ignore, OP_IGNORE },
{ ".INCLUDES", Includes, 0 },
@ -497,6 +499,50 @@ Parse_Error(int type, const char *fmt, ...)
}
}
/*
* ParseMessage
* Parse a .info .warning or .error directive
*
* The input is the line minus the ".". We substitute
* variables, print the message and exit(1) (for .error) or just print
* a warning if the directive is malformed.
*/
static void
ParseMessage(char *line)
{
int mtype;
switch(*line) {
case 'i':
mtype = 0;
break;
case 'w':
mtype = PARSE_WARNING;
break;
case 'e':
mtype = PARSE_FATAL;
break;
default:
Parse_Error(PARSE_WARNING, "invalid syntax: \".%s\"", line);
return;
}
while (!isspace((u_char)*line))
line++;
while (isspace((u_char)*line))
line++;
line = Var_Subst(NULL, line, VAR_CMD, 0);
Parse_Error(mtype, "%s", line);
free(line);
if (mtype == PARSE_FATAL) {
/* Terminate immediately. */
exit(1);
}
}
/*-
*---------------------------------------------------------------------
* ParseLinkSrc --
@ -925,7 +971,8 @@ ParseDoDependency(char *line)
Parse_Error(PARSE_FATAL,
"Makefile appears to contain unresolved cvs/rcs/??? merge conflicts");
else
Parse_Error(PARSE_FATAL, "Need an operator");
Parse_Error(PARSE_FATAL, lstart[0] == '.' ? "Unknown directive"
: "Need an operator");
goto out;
}
*cp = '\0';
@ -972,6 +1019,7 @@ ParseDoDependency(char *line)
* .NOPATH Don't search for file in the path
* .BEGIN
* .END
* .ERROR
* .INTERRUPT Are not to be considered the
* main target.
* .NOTPARALLEL Make only one target at a time.
@ -992,6 +1040,7 @@ ParseDoDependency(char *line)
break;
case Begin:
case End:
case dotError:
case Interrupt:
gn = Targ_FindNode(line, TARG_CREATE);
gn->type |= OP_NOTMAIN|OP_SPECIAL;
@ -1121,6 +1170,7 @@ ParseDoDependency(char *line)
case Default:
case Begin:
case End:
case dotError:
case Interrupt:
/*
* These four create nodes on which to hang commands, so
@ -1148,7 +1198,8 @@ ParseDoDependency(char *line)
op = OP_DEPENDS;
}
} else {
Parse_Error(PARSE_FATAL, "Missing dependency operator");
Parse_Error(PARSE_FATAL, lstart[0] == '.' ? "Unknown directive"
: "Missing dependency operator");
goto out;
}
@ -2479,8 +2530,10 @@ Parse_File(const char *name, int fd)
curFile->lineno, line);
if (*line == '.') {
/*
* Lines that begin with the special character are either
* Lines that begin with the special character may be
* include or undef directives.
* On the other hand they can be suffix rules (.c.o: ...)
* or just dependencies for filenames that start '.'.
*/
for (cp = line + 1; isspace((unsigned char)*cp); cp++) {
continue;
@ -2506,6 +2559,14 @@ Parse_File(const char *name, int fd)
continue;
Var_Export(cp, 1);
continue;
} else if (strncmp(cp, "unexport", 8) == 0) {
Var_UnExport(cp);
continue;
} else if (strncmp(cp, "info", 4) == 0 ||
strncmp(cp, "error", 5) == 0 ||
strncmp(cp, "warning", 7) == 0) {
ParseMessage(cp);
continue;
}
}
@ -2590,16 +2651,31 @@ Parse_File(const char *name, int fd)
/*
* For some reason - probably to make the parser impossible -
* a ';' can be used to separate commands from dependencies.
* No attempt is made to avoid ';' inside substitution patterns.
* Attempt to avoid ';' inside substitution patterns.
*/
{
int level = 0;
for (cp = line; *cp != 0; cp++) {
if (*cp == '\\' && cp[1] != 0) {
cp++;
continue;
}
if (*cp == ';')
if (*cp == '$' &&
(cp[1] == '(' || cp[1] == '{')) {
level++;
continue;
}
if (level > 0) {
if (*cp == ')' || *cp == '}') {
level--;
continue;
}
} else if (*cp == ';') {
break;
}
}
}
if (*cp != 0)
/* Terminate the dependency list at the ';' */
*cp++ = 0;
@ -2639,7 +2715,7 @@ Parse_File(const char *name, int fd)
(void)fprintf(stderr,
"%s: Fatal errors encountered -- cannot continue\n",
progname);
PrintOnError(NULL);
PrintOnError(NULL, NULL);
exit(1);
}
}

View file

@ -1,6 +1,6 @@
# $Id: Makefile.in,v 1.4 2009/09/18 21:27:26 joerg Exp $
# $Id: Makefile.in,v 1.5 2010/04/20 13:37:49 joerg Exp $
#
# $NetBSD: Makefile.in,v 1.4 2009/09/18 21:27:26 joerg Exp $
# $NetBSD: Makefile.in,v 1.5 2010/04/20 13:37:49 joerg Exp $
#
# Unit tests for make(1)
# The main targets are:
@ -25,9 +25,12 @@ UNIT_TESTS:= ${srcdir}
SUBFILES= \
comment \
cond1 \
error \
export \
export-all \
doterror \
dotwait \
forsubst \
moderrs \
modmatch \
modmisc \
@ -37,15 +40,19 @@ SUBFILES= \
posix \
qequals \
ternary \
unexport \
unexport-env \
varcmd
all: ${SUBFILES}
flags.doterror=
# the tests are actually done with sub-makes.
.PHONY: ${SUBFILES}
.PRECIOUS: ${SUBFILES}
${SUBFILES}:
-@${.MAKE} -k -f ${UNIT_TESTS}/$@
-@${.MAKE} ${flags.$@:U-k} -f ${UNIT_TESTS}/$@
clean:
rm -f *.out *.fail *.core

View file

@ -24,6 +24,9 @@ make: warning: String comparison operator should be either == or !=
make: Bad conditional expression `"0" > 0' in "0" > 0?OK:No
OK
make: "error" line 3: just FYI
make: "error" line 4: warning: this could be serious
make: "error" line 5: this is fatal
UT_DOLLAR=This is $UT_FU
UT_FOO=foobar is fubar
UT_FU=fubar
@ -38,6 +41,14 @@ UT_NO=all
UT_OK=good
UT_TEST=export-all
UT_ZOO=hoopie
At first, I am
happy
and now: sad
.ERROR: Looks like 'sad' is upset.
*** Error code 1
Stop.
make: stopped in unit-tests
simple.1
simple.1
simple.2
@ -67,6 +78,7 @@ make: Graph cycles through `cycle.2.98'
make: Graph cycles through `cycle.2.97'
cycle.1.99
cycle.1.99
.for with :S;... OK
Expect: Unknown modifier 'Z'
make: Unknown modifier 'Z'
VAR:Z=
@ -301,6 +313,10 @@ The answer is empty
The answer is known
The answer is 42
The answer is 42
UT_DOLLAR=This is $UT_FU
UT_FU=fubar
UT_TEST=unexport
UT_TEST=unexport-env
default FU=<v>fu</v> FOO=<v>foo</v> VAR=<v></v>
two FU=<v>bar</v> FOO=<v>goo</v> VAR=<v></v>
three FU=<v>bar</v> FOO=<v>goo</v> VAR=<v></v>
@ -309,3 +325,5 @@ five FU=<v>bar</v> FOO=<v>goo</v> VAR=<v>Internal</v>
five v=is x k=is x
six v=is y k=is y
show-v v=override k=override
*** Error code 1 (ignored)
*** Error code 1 (ignored)

View file

@ -1,18 +1,18 @@
/* $NetBSD: util.c,v 1.5 2009/09/18 21:27:25 joerg Exp $ */
/* $NetBSD: util.c,v 1.6 2010/04/20 13:37:49 joerg Exp $ */
/*
* Missing stuff from OS's
*
* $Id: util.c,v 1.5 2009/09/18 21:27:25 joerg Exp $
* $Id: util.c,v 1.6 2010/04/20 13:37:49 joerg Exp $
*/
#include "make.h"
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: util.c,v 1.5 2009/09/18 21:27:25 joerg Exp $";
static char rcsid[] = "$NetBSD: util.c,v 1.6 2010/04/20 13:37:49 joerg Exp $";
#else
#ifndef lint
__RCSID("$NetBSD: util.c,v 1.5 2009/09/18 21:27:25 joerg Exp $");
__RCSID("$NetBSD: util.c,v 1.6 2010/04/20 13:37:49 joerg Exp $");
#endif
#endif
@ -385,7 +385,7 @@ getcwd(path, sz)
}
#endif
#if defined(sun) && defined(__svr4__)
#if defined(sun) && defined(__svr4__) && !defined(FORCE_POSIX_SIGNALS)
#include <signal.h>
/* turn into bsd signals */

View file

@ -1,4 +1,4 @@
/* $NetBSD: var.c,v 1.5 2009/09/18 21:27:25 joerg Exp $ */
/* $NetBSD: var.c,v 1.6 2010/04/20 13:37:49 joerg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@ -69,14 +69,14 @@
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: var.c,v 1.5 2009/09/18 21:27:25 joerg Exp $";
static char rcsid[] = "$NetBSD: var.c,v 1.6 2010/04/20 13:37:49 joerg 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.5 2009/09/18 21:27:25 joerg Exp $");
__RCSID("$NetBSD: var.c,v 1.6 2010/04/20 13:37:49 joerg Exp $");
#endif
#endif /* not lint */
#endif
@ -527,6 +527,9 @@ Var_Delete(const char *name, GNode *ctxt)
if ((v->flags & VAR_EXPORTED)) {
unsetenv(v->name);
}
if (strcmp(MAKE_EXPORTED, v->name) == 0) {
var_exportedVars = VAR_EXPORTED_NONE;
}
if (v->name != ln->name)
free(v->name);
Hash_DeleteEntry(&ctxt->context, ln);
@ -711,6 +714,107 @@ Var_Export(char *str, int isExport)
free(av);
}
/*
* This is called when .unexport[-env] is seen.
*/
void
Var_UnExport(char *str)
{
char tmp[BUFSIZ];
char *vlist;
char *cp;
Boolean unexport_env;
int n;
if (!str || !str[0]) {
return; /* assert? */
}
vlist = NULL;
str += 8;
unexport_env = (strncmp(str, "-env", 4) == 0);
if (unexport_env) {
extern char **environ;
static char **savenv;
char **newenv;
cp = getenv(MAKE_LEVEL); /* we should preserve this */
if (environ == savenv) {
/* we have been here before! */
newenv = bmake_realloc(environ, 2 * sizeof(char *));
} else {
if (savenv) {
free(savenv);
savenv = NULL;
}
newenv = bmake_malloc(2 * sizeof(char *));
}
if (!newenv)
return;
/* Note: we cannot safely free() the original environ. */
environ = savenv = newenv;
newenv[0] = NULL;
newenv[1] = NULL;
setenv(MAKE_LEVEL, cp, 1);
} else {
for (; *str != '\n' && isspace((unsigned char) *str); str++)
continue;
if (str[0] && str[0] != '\n') {
vlist = str;
}
}
if (!vlist) {
/* Using .MAKE.EXPORTED */
n = snprintf(tmp, sizeof(tmp), "${" MAKE_EXPORTED ":O:u}");
if (n < (int)sizeof(tmp)) {
vlist = Var_Subst(NULL, tmp, VAR_GLOBAL, 0);
}
}
if (vlist) {
Var *v;
char **av;
char *as;
int ac;
int i;
av = brk_string(vlist, &ac, FALSE, &as);
for (i = 0; i < ac; i++) {
v = VarFind(av[i], VAR_GLOBAL, 0);
if (!v)
continue;
if (!unexport_env &&
(v->flags & (VAR_EXPORTED|VAR_REEXPORT)) == VAR_EXPORTED) {
unsetenv(v->name);
}
v->flags &= ~(VAR_EXPORTED|VAR_REEXPORT);
/*
* If we are unexporting a list,
* remove each one from .MAKE.EXPORTED.
* If we are removing them all,
* just delete .MAKE.EXPORTED below.
*/
if (vlist == str) {
n = snprintf(tmp, sizeof(tmp),
"${" MAKE_EXPORTED ":N%s}", v->name);
if (n < (int)sizeof(tmp)) {
cp = Var_Subst(NULL, tmp, VAR_GLOBAL, 0);
Var_Set(MAKE_EXPORTED, cp, VAR_GLOBAL, 0);
free(cp);
}
}
}
free(as);
free(av);
if (vlist != str) {
Var_Delete(MAKE_EXPORTED, VAR_GLOBAL);
free(vlist);
}
}
}
/*-
*-----------------------------------------------------------------------
* Var_Set --
@ -1755,6 +1859,32 @@ VarSelectWords(GNode *ctx __unused, Var_Parse_State *vpstate,
return Buf_Destroy(&buf, FALSE);
}
/*-
* VarRealpath --
* Replace each word with the result of realpath()
* if successful.
*/
static Boolean
VarRealpath(GNode *ctx __unused, Var_Parse_State *vpstate,
char *word, Boolean addSpace, Buffer *buf,
void *patternp __unused)
{
char rbuf[MAXPATHLEN];
char *rp;
if (addSpace && vpstate->varSpace) {
Buf_AddByte(buf, vpstate->varSpace);
}
addSpace = TRUE;
rp = realpath(word, rbuf);
if (rp && *rp == '/')
word = rp;
Buf_AddBytes(buf, strlen(word), word);
return(addSpace);
}
/*-
*-----------------------------------------------------------------------
* VarModify --
@ -2745,7 +2875,12 @@ ApplyModifiers(char *nstr, const char *tstr,
* Check for two-character options:
* ":tu", ":tl"
*/
if (tstr[1] == 'u' || tstr[1] == 'l') {
if (tstr[1] == 'A') { /* absolute path */
newStr = VarModify(ctxt, &parsestate, nstr,
VarRealpath, NULL);
cp = tstr + 2;
termc = *cp;
} else if (tstr[1] == 'u' || tstr[1] == 'l') {
newStr = VarChangeCase(nstr, (tstr[1] == 'u'));
cp = tstr + 2;
termc = *cp;