diff --git a/ChangeLog b/ChangeLog index 46c563fb2efc..49ce971d4934 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +2017-03-01 Simon J. Gerraty + + * Makefile (_MAKE_VERSION): 20170301 + Merge with NetBSD make, pick up + o main.c: use -C arg as is rather than getcwd() + if they identify the same directory. + o parse.c: ensure loadfile buffer is \n terminated in non-mmap case + +2017-02-01 Simon J. Gerraty + + * Makefile (_MAKE_VERSION): 20170201 + Merge with NetBSD make, pick up + o var.c: allow :_=var and avoid use of special context. + +2017-01-30 Simon J. Gerraty + + * Makefile (_MAKE_VERSION): 20170130 + Merge with NetBSD make, pick up + o var.c: add :range and :_ + o main.c: partially initialize Dir_* before MainParseArgs() + can be called. + If -V, skip Main_ExportMAKEFLAGS() + +2017-01-14 Simon J. Gerraty + + * Makefile (_MAKE_VERSION): 20170114 + Merge with NetBSD make, pick up + o var.c: allow specifying the utc value used by :{gm,local}time + 2016-12-12 Simon J. Gerraty * Makefile (_MAKE_VERSION): 20161212 diff --git a/Makefile b/Makefile index 7f6066bc57da..34493789133f 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ -# $Id: Makefile,v 1.77 2016/12/12 07:34:19 sjg Exp $ +# $Id: Makefile,v 1.81 2017/03/01 17:01:23 sjg Exp $ # Base version on src date -_MAKE_VERSION= 20161212 +_MAKE_VERSION= 20170301 PROG= bmake diff --git a/PSD.doc/tutorial.ms b/PSD.doc/tutorial.ms index d5c8a7d54f96..814a09a62146 100644 --- a/PSD.doc/tutorial.ms +++ b/PSD.doc/tutorial.ms @@ -1,4 +1,4 @@ -.\" $NetBSD: tutorial.ms,v 1.12 2014/09/30 21:33:14 christos Exp $ +.\" $NetBSD: tutorial.ms,v 1.13 2017/03/01 13:05:11 kre Exp $ .\" Copyright (c) 1988, 1989, 1993 .\" The Regents of the University of California. All rights reserved. .\" @@ -117,6 +117,15 @@ .de No .br .ne 0.5i +.ie n \{\ +.nr g3 \w'NOTE ' +.po -\\n(g3u +.br +NOTE +.br +.po +\\n(g3u +.\} +.el \{\ .po -0.5i .br .mk @@ -148,12 +157,14 @@ .rt .ft \\n(g3 .ps \\n(g4 +.\} .. .de Bp .ie !\\n(.$ .IP \(bu 2 .el .IP "\&" 2 .. -.po +.3i +.ie n .po +\w'NOTE 'u +.el .po +.3i .TL PMake \*- A Tutorial .AU diff --git a/bmake.1 b/bmake.1 index 4f8f3372ca0f..3bad1e7316a0 100644 --- a/bmake.1 +++ b/bmake.1 @@ -1,4 +1,4 @@ -.\" $NetBSD: make.1,v 1.263 2016/08/26 23:37:54 dholland Exp $ +.\" $NetBSD: make.1,v 1.266 2017/02/01 18:39:27 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 August 26, 2016 +.Dd February 1, 2017 .Dt BMAKE 1 .Os .Sh NAME @@ -1205,18 +1205,28 @@ safely through recursive invocations of .Nm . .It Cm \&:R Replaces each word in the variable with everything but its suffix. -.It Cm \&:gmtime +.It Cm \&:range[=count] +The value is an integer sequence representing the words of the original +value, or the supplied +.Va count . +.It Cm \&:gmtime[=utc] The value is a format string for .Xr strftime 3 , -using the current +using .Xr gmtime 3 . +If a +.Va utc +value is not provided or is 0, the current time is used. .It Cm \&:hash Compute a 32-bit hash of the value and encode it as hex digits. -.It Cm \&:localtime +.It Cm \&:localtime[=utc] The value is a format string for .Xr strftime 3 , -using the current +using .Xr localtime 3 . +If a +.Va utc +value is not provided or is 0, the current time is used. .It Cm \&:tA Attempt to convert variable to an absolute path using .Xr realpath 3 , @@ -1416,6 +1426,27 @@ For example. .Pp However a single character variable is often more readable: .Dl ${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@} +.It Cm \&:_[=var] +Save the current variable value in +.Ql $_ +or the named +.Va var +for later reference. +Example usage: +.Bd -literal -offset indent +M_cmpv.units = 1 1000 1000000 +M_cmpv = S,., ,g:_:range:@i@+ $${_:[-$$i]} \&\\ +\\* $${M_cmpv.units:[$$i]}@:S,^,expr 0 ,1:sh + +.Dv .if ${VERSION:${M_cmpv}} < ${3.1.12:L:${M_cmpv}} + +.Ed +Here +.Ql $_ +is used to save the result of the +.Ql :S +modifier which is later referenced using the index values from +.Ql :range . .It Cm \&:U Ns Ar newval If the variable is undefined .Ar newval diff --git a/bmake.cat1 b/bmake.cat1 index 2aec542ac785..bd98e5b3b245 100644 --- a/bmake.cat1 +++ b/bmake.cat1 @@ -789,16 +789,20 @@ VVAARRIIAABBLLEE AASSSSIIGGNNMMEENNTTSS ::RR Replaces each word in the variable with everything but its suffix. - ::ggmmttiimmee - The value is a format string for strftime(3), using the current - gmtime(3). + ::rraannggee[[==ccoouunntt]] + The value is an integer sequence representing the words of the orig- + inal value, or the supplied _c_o_u_n_t. + + ::ggmmttiimmee[[==uuttcc]] + The value is a format string for strftime(3), using gmtime(3). If a + _u_t_c value is not provided or is 0, the current time is used. ::hhaasshh Compute a 32-bit hash of the value and encode it as hex digits. - ::llooccaallttiimmee - The value is a format string for strftime(3), using the current - localtime(3). + ::llooccaallttiimmee[[==uuttcc]] + The value is a format string for strftime(3), using localtime(3). + If a _u_t_c value is not provided or is 0, the current time is used. ::ttAA Attempt to convert variable to an absolute path using realpath(3), if that fails, the value is unchanged. @@ -899,6 +903,19 @@ VVAARRIIAABBLLEE AASSSSIIGGNNMMEENNTTSS However a single character variable is often more readable: ${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@} + ::__[[==vvaarr]] + Save the current variable value in `$_' or the named _v_a_r for later + reference. Example usage: + + M_cmpv.units = 1 1000 1000000 + M_cmpv = S,., ,g:_:range:@i@+ $${_:[-$$i]} \ + \* $${M_cmpv.units:[$$i]}@:S,^,expr 0 ,1:sh + + .if ${VERSION:${M_cmpv}} < ${3.1.12:L:${M_cmpv}} + + Here `$_' is used to save the result of the `:S' modifier which is + later referenced using the index values from `:range'. + ::UU_n_e_w_v_a_l If the variable is undefined _n_e_w_v_a_l is the value. If the variable is defined, the existing value is returned. This is another ODE @@ -1506,4 +1523,4 @@ BBUUGGSS There is no way of escaping a space character in a filename. -NetBSD 5.1 August 26, 2016 NetBSD 5.1 +NetBSD 7.1_RC1 February 1, 2017 NetBSD 7.1_RC1 diff --git a/dir.c b/dir.c index 4667e3cdb677..2494da513ee2 100644 --- a/dir.c +++ b/dir.c @@ -1,4 +1,4 @@ -/* $NetBSD: dir.c,v 1.68 2016/06/07 00:40:00 sjg Exp $ */ +/* $NetBSD: dir.c,v 1.69 2017/01/31 06:54:23 sjg 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.68 2016/06/07 00:40:00 sjg Exp $"; +static char rcsid[] = "$NetBSD: dir.c,v 1.69 2017/01/31 06:54:23 sjg Exp $"; #else #include #ifndef lint #if 0 static char sccsid[] = "@(#)dir.c 8.2 (Berkeley) 1/2/94"; #else -__RCSID("$NetBSD: dir.c,v 1.68 2016/06/07 00:40:00 sjg Exp $"); +__RCSID("$NetBSD: dir.c,v 1.69 2017/01/31 06:54:23 sjg Exp $"); #endif #endif /* not lint */ #endif @@ -346,11 +346,13 @@ cached_lstat(const char *pathname, void *st) void Dir_Init(const char *cdname) { - dirSearchPath = Lst_Init(FALSE); - openDirectories = Lst_Init(FALSE); - Hash_InitTable(&mtimes, 0); - Hash_InitTable(&lmtimes, 0); - + if (!cdname) { + dirSearchPath = Lst_Init(FALSE); + openDirectories = Lst_Init(FALSE); + Hash_InitTable(&mtimes, 0); + Hash_InitTable(&lmtimes, 0); + return; + } Dir_InitCur(cdname); dotLast = bmake_malloc(sizeof(Path)); diff --git a/main.c b/main.c index 087438927355..870eefd6e591 100644 --- a/main.c +++ b/main.c @@ -1,4 +1,4 @@ -/* $NetBSD: main.c,v 1.254 2016/12/10 23:12:39 christos Exp $ */ +/* $NetBSD: main.c,v 1.257 2017/02/08 17:47:36 christos Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -69,7 +69,7 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: main.c,v 1.254 2016/12/10 23:12:39 christos Exp $"; +static char rcsid[] = "$NetBSD: main.c,v 1.257 2017/02/08 17:47:36 christos Exp $"; #else #include #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.254 2016/12/10 23:12:39 christos Exp $"); +__RCSID("$NetBSD: main.c,v 1.257 2017/02/08 17:47:36 christos Exp $"); #endif #endif /* not lint */ #endif @@ -389,6 +389,7 @@ MainParseArgs(int argc, char **argv) int arginc; char *argvalue; const char *getopt_def; + struct stat sa, sb; char *optscan; Boolean inOption, dashDash = FALSE; char found_path[MAXPATHLEN + 1]; /* for searching for sys.mk */ @@ -457,6 +458,11 @@ MainParseArgs(int argc, char **argv) (void)fprintf(stderr, "%s: %s.\n", progname, strerror(errno)); exit(2); } + if (stat(argvalue, &sa) != -1 && + stat(curdir, &sb) != -1 && + sa.st_ino == sb.st_ino && + sa.st_dev == sb.st_dev) + strncpy(curdir, argvalue, MAXPATHLEN); ignorePWD = TRUE; break; case 'D': @@ -1073,6 +1079,8 @@ main(int argc, char **argv) #ifdef USE_META meta_init(); #endif + Dir_Init(NULL); /* Dir_* safe to call from MainParseArgs */ + /* * First snag any flags out of the MAKE environment variable. * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's @@ -1314,8 +1322,9 @@ main(int argc, char **argv) fprintf(debug_file, "job_pipe %d %d, maxjobs %d, tokens %d, compat %d\n", jp_0, jp_1, maxJobs, maxJobTokens, compatMake); - Main_ExportMAKEFLAGS(TRUE); /* initial export */ - + if (!printVars) + Main_ExportMAKEFLAGS(TRUE); /* initial export */ + /* * For compatibility, look at the directories in the VPATH variable * and add them to the search path, if the variable is defined. The @@ -1933,7 +1942,7 @@ PrintAddr(void *a, void *b) static int -addErrorCMD(void *cmdp, void *gnp) +addErrorCMD(void *cmdp, void *gnp MAKE_ATTR_UNUSED) { if (cmdp == NULL) return 1; /* stop */ diff --git a/make.1 b/make.1 index c74988716f23..a461909e87ee 100644 --- a/make.1 +++ b/make.1 @@ -1,4 +1,4 @@ -.\" $NetBSD: make.1,v 1.263 2016/08/26 23:37:54 dholland Exp $ +.\" $NetBSD: make.1,v 1.266 2017/02/01 18:39:27 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 August 26, 2016 +.Dd February 1, 2017 .Dt MAKE 1 .Os .Sh NAME @@ -1205,18 +1205,28 @@ safely through recursive invocations of .Nm . .It Cm \&:R Replaces each word in the variable with everything but its suffix. -.It Cm \&:gmtime +.It Cm \&:range[=count] +The value is an integer sequence representing the words of the original +value, or the supplied +.Va count . +.It Cm \&:gmtime[=utc] The value is a format string for .Xr strftime 3 , -using the current +using .Xr gmtime 3 . +If a +.Va utc +value is not provided or is 0, the current time is used. .It Cm \&:hash Compute a 32-bit hash of the value and encode it as hex digits. -.It Cm \&:localtime +.It Cm \&:localtime[=utc] The value is a format string for .Xr strftime 3 , -using the current +using .Xr localtime 3 . +If a +.Va utc +value is not provided or is 0, the current time is used. .It Cm \&:tA Attempt to convert variable to an absolute path using .Xr realpath 3 , @@ -1416,6 +1426,27 @@ For example. .Pp However a single character variable is often more readable: .Dl ${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@} +.It Cm \&:_[=var] +Save the current variable value in +.Ql $_ +or the named +.Va var +for later reference. +Example usage: +.Bd -literal -offset indent +M_cmpv.units = 1 1000 1000000 +M_cmpv = S,., ,g:_:range:@i@+ $${_:[-$$i]} \&\\ +\\* $${M_cmpv.units:[$$i]}@:S,^,expr 0 ,1:sh + +.Dv .if ${VERSION:${M_cmpv}} < ${3.1.12:L:${M_cmpv}} + +.Ed +Here +.Ql $_ +is used to save the result of the +.Ql :S +modifier which is later referenced using the index values from +.Ql :range . .It Cm \&:U Ns Ar newval If the variable is undefined .Ar newval diff --git a/meta.c b/meta.c index 0ea41f643f3a..33c2dd8d5e3d 100644 --- a/meta.c +++ b/meta.c @@ -241,7 +241,7 @@ eat_dots(char *buf, size_t bufsz, int dots) } static char * -meta_name(struct GNode *gn, char *mname, size_t mnamelen, +meta_name(char *mname, size_t mnamelen, const char *dname, const char *tname, const char *cwd) @@ -396,7 +396,7 @@ printCMD(void *cmdp, void *mfpp) * Do we need/want a .meta file ? */ static Boolean -meta_needed(GNode *gn, const char *dname, const char *tname, +meta_needed(GNode *gn, const char *dname, char *objdir, int verbose) { struct stat fs; @@ -476,7 +476,7 @@ meta_create(BuildMon *pbm, GNode *gn) tname = Var_Value(TARGET, gn, &p[i++]); /* if this succeeds objdir is realpath of dname */ - if (!meta_needed(gn, dname, tname, objdir, TRUE)) + if (!meta_needed(gn, dname, objdir, TRUE)) goto out; dname = objdir; @@ -502,7 +502,7 @@ meta_create(BuildMon *pbm, GNode *gn) /* Don't create meta data. */ goto out; - fname = meta_name(gn, pbm->meta_fname, sizeof(pbm->meta_fname), + fname = meta_name(pbm->meta_fname, sizeof(pbm->meta_fname), dname, tname, objdir); #ifdef DEBUG_META_MODE @@ -1049,7 +1049,7 @@ meta_oodate(GNode *gn, Boolean oodate) tname = Var_Value(TARGET, gn, &pa[i++]); /* if this succeeds fname3 is realpath of dname */ - if (!meta_needed(gn, dname, tname, fname3, FALSE)) + if (!meta_needed(gn, dname, fname3, FALSE)) goto oodate_out; dname = fname3; @@ -1063,7 +1063,7 @@ meta_oodate(GNode *gn, Boolean oodate) */ Make_DoAllVar(gn); - meta_name(gn, fname, sizeof(fname), dname, tname, dname); + meta_name(fname, sizeof(fname), dname, tname, dname); #ifdef DEBUG_META_MODE if (DEBUG(META)) diff --git a/mk/ChangeLog b/mk/ChangeLog index 4df06cd22897..ef0bd3793fba 100644 --- a/mk/ChangeLog +++ b/mk/ChangeLog @@ -1,3 +1,34 @@ +2017-03-01 Simon J. Gerraty + + * install-mk (MK_VERSION): 20170301 + + * dirdeps.mk (_build_all_dirs): update this outside test for empty + DIRDEPS. + + * meta.stage.mk: allow multiple inclusion to the extent it makes + sense. + +2017-02-14 Simon J. Gerraty + + * prog.mk (install_links): depends on realinstall + +2017-02-12 Simon J. Gerraty + + * install-mk (MK_VERSION): 20170212 + + * dpadd.mk: avoid applying :T:R twice to DPLIBS entries + +2017-01-30 Simon J. Gerraty + + * install-mk (MK_VERSION): 20170130 + + * dirdeps.mk: use :range if we can. + + * sys.vars.mk: provide M_cmpv if MAKE_VERSION >= 20170130 + + * meta2deps.py: clean paths without using realpath() where possible. + fix sort_unique. + 2016-12-12 Simon J. Gerraty * install-mk (MK_VERSION): 20161212 diff --git a/mk/dirdeps.mk b/mk/dirdeps.mk index 179122e96f79..6b2952057d72 100644 --- a/mk/dirdeps.mk +++ b/mk/dirdeps.mk @@ -1,4 +1,4 @@ -# $Id: dirdeps.mk,v 1.84 2016/11/27 02:44:34 sjg Exp $ +# $Id: dirdeps.mk,v 1.86 2017/03/01 20:26:51 sjg Exp $ # Copyright (c) 2010-2013, Juniper Networks, Inc. # All rights reserved. @@ -197,7 +197,9 @@ DEP_$v ?= ${$v} # 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. -.if ${TARGET_SPEC_VARS:[#]} > 10 +.if ${MAKE_VERSION} >= 20170130 +_tspec_x := ${TARGET_SPEC_VARS:range} +.elif ${TARGET_SPEC_VARS:[#]} > 10 # seriously? better have jot(1) or equivalent to produce suitable sequence _tspec_x := ${${JOT:Ujot} ${TARGET_SPEC_VARS:[#]}:L:sh} .else @@ -612,11 +614,11 @@ _build_dirs += \ # qualify everything now _build_dirs := ${_build_dirs:${M_dep_qual_fixes:ts:}:O:u} +.endif # empty DIRDEPS + _build_all_dirs += ${_build_dirs} _build_all_dirs := ${_build_all_dirs:O:u} -.endif # empty DIRDEPS - # Normally if doing make -V something, # we do not want to waste time chasing DIRDEPS # but if we want to count the number of Makefile.depend* read, we do. diff --git a/mk/dpadd.mk b/mk/dpadd.mk index c789acfb9904..650d61bf9a80 100644 --- a/mk/dpadd.mk +++ b/mk/dpadd.mk @@ -1,4 +1,4 @@ -# $Id: dpadd.mk,v 1.22 2016/05/31 23:30:59 sjg Exp $ +# $Id: dpadd.mk,v 1.23 2017/02/13 16:46:01 sjg Exp $ # # @(#) Copyright (c) 2004, Simon J. Gerraty # @@ -49,11 +49,11 @@ CXXFLAGS_LAST += ${CXXFLAGS_DEBUG_XTRA} # DPLIBS helps us ensure we keep DPADD and LDADD in sync DPLIBS+= ${DPLIBS_LAST} DPADD+= ${DPLIBS:N-*} -.for __lib in ${DPLIBS:T:R} +.for __lib in ${DPLIBS} .if "${_lib:M-*}" != "" LDADD += ${__lib} .else -LDADD += ${LDADD_${__lib}:U${__lib:T:R:S/lib/-l/:C/\.so.*//}} +LDADD += ${LDADD_${__lib:T:R}:U${__lib:T:R:S/lib/-l/:C/\.so.*//}} .endif .endfor diff --git a/mk/install-mk b/mk/install-mk index 8d09f8462bc0..158f74cf6d06 100644 --- a/mk/install-mk +++ b/mk/install-mk @@ -55,7 +55,7 @@ # Simon J. Gerraty # RCSid: -# $Id: install-mk,v 1.135 2016/12/12 19:07:42 sjg Exp $ +# $Id: install-mk,v 1.138 2017/03/01 20:26:51 sjg Exp $ # # @(#) Copyright (c) 1994 Simon J. Gerraty # @@ -70,7 +70,7 @@ # sjg@crufty.net # -MK_VERSION=20161212 +MK_VERSION=20170301 OWNER= GROUP= MODE=444 diff --git a/mk/meta.stage.mk b/mk/meta.stage.mk index a0f30e31885c..223421a51ece 100644 --- a/mk/meta.stage.mk +++ b/mk/meta.stage.mk @@ -1,6 +1,6 @@ -# $Id: meta.stage.mk,v 1.47 2016/12/07 23:07:49 sjg Exp $ +# $Id: meta.stage.mk,v 1.48 2017/03/01 22:48:07 sjg Exp $ # -# @(#) Copyright (c) 2011, Simon J. Gerraty +# @(#) Copyright (c) 2011-2017, Simon J. Gerraty # # This file is provided in the hope that it will # be of use. There is absolutely NO WARRANTY. @@ -14,7 +14,7 @@ # .if !target(__${.PARSEFILE}__) -__${.PARSEFILE}__: +# the guard target is defined later .if ${.MAKE.DEPENDFILE_PREFERENCE:U${.MAKE.DEPENDFILE}:M*.${MACHINE}} != "" # this is generally safer anyway @@ -127,26 +127,17 @@ STAGE_AS_SCRIPT = ${STAGE_DIRDEP_SCRIPT}; StageAs() { \ done; :; } # this is simple, a list of the "staged" files depends on this, -_STAGE_BASENAME_USE: .USE ${.TARGET:T} +_STAGE_BASENAME_USE: .USE .dirdep ${.TARGET:T} @${STAGE_FILE_SCRIPT}; StageFiles ${.TARGET:H:${STAGE_DIR_FILTER}} ${.TARGET:T} -_STAGE_AS_BASENAME_USE: .USE ${.TARGET:T} +_STAGE_AS_BASENAME_USE: .USE .dirdep ${.TARGET:T} @${STAGE_AS_SCRIPT}; StageAs ${.TARGET:H:${STAGE_DIR_FILTER}} ${.TARGET:T} ${STAGE_AS_${.TARGET:T}:U${.TARGET:T}} -.if !empty(STAGE_INCSDIR) -STAGE_TARGETS += stage_incs -STAGE_INCS ?= ${.ALLSRC:N.dirdep:Nstage_*} stage_includes: stage_incs stage_incs: .dirdep @${STAGE_FILE_SCRIPT}; StageFiles ${STAGE_INCSDIR:${STAGE_DIR_FILTER}} ${STAGE_INCS} @touch $@ -.endif - -.if !empty(STAGE_LIBDIR) -STAGE_TARGETS += stage_libs - -STAGE_LIBS ?= ${.ALLSRC:N.dirdep:Nstage_*} stage_libs: .dirdep @${STAGE_FILE_SCRIPT}; StageFiles ${STAGE_LIBDIR:${STAGE_DIR_FILTER}} ${STAGE_LIBS} @@ -159,6 +150,18 @@ stage_libs: .dirdep .endif .endif @touch $@ + +.endif # first time + + +.if !empty(STAGE_INCSDIR) +STAGE_TARGETS += stage_incs +STAGE_INCS ?= ${.ALLSRC:N.dirdep:Nstage_*} +.endif + +.if !empty(STAGE_LIBDIR) +STAGE_TARGETS += stage_libs +STAGE_LIBS ?= ${.ALLSRC:N.dirdep:Nstage_*} .endif .if !empty(STAGE_DIR) @@ -184,6 +187,8 @@ STAGE_LINKS_DIR.$s ?= ${STAGE_OBJTOP} STAGE_SYMLINKS_DIR.$s ?= ${STAGE_OBJTOP} STAGE_TARGETS += stage_files +.if !target(.stage_files.$s) +.stage_files.$s: .if $s != "_default" stage_files: stage_files.$s stage_files.$s: .dirdep @@ -192,8 +197,11 @@ stage_files: .dirdep .endif @${STAGE_FILE_SCRIPT}; StageFiles ${FLAGS.$@} ${STAGE_FILES_DIR.$s:U${STAGE_DIR.$s}:${STAGE_DIR_FILTER}} ${STAGE_FILES.$s} @touch $@ +.endif STAGE_TARGETS += stage_links +.if !target(.stage_links.$s) +.stage_links.$s: .if $s != "_default" stage_links: stage_links.$s stage_links.$s: .dirdep @@ -202,8 +210,11 @@ stage_links: .dirdep .endif @${STAGE_LINKS_SCRIPT}; StageLinks ${STAGE_LINKS_DIR.$s:U${STAGE_DIR.$s}:${STAGE_DIR_FILTER}} ${STAGE_LINKS.$s} @touch $@ +.endif STAGE_TARGETS += stage_symlinks +.if !target(.stage_symlinks.$s) +.stage_symlinks.$s: .if $s != "_default" stage_symlinks: stage_symlinks.$s stage_symlinks.$s: .dirdep @@ -212,6 +223,7 @@ stage_symlinks: .dirdep .endif @${STAGE_LINKS_SCRIPT}; StageLinks -s ${STAGE_SYMLINKS_DIR.$s:U${STAGE_DIR.$s}:${STAGE_DIR_FILTER}} ${STAGE_SYMLINKS.$s} @touch $@ +.endif .endfor .endif @@ -231,22 +243,32 @@ STAGE_TARGETS += stage_as stage_as_and_symlink STAGE_AS.$s ?= ${.ALLSRC:N.dirdep:Nstage_*} STAGE_AS_AND_SYMLINK.$s ?= ${.ALLSRC:N.dirdep:Nstage_*} +.if !target(.stage_as.$s) +.stage_as.$s: stage_as: stage_as.$s stage_as.$s: .dirdep @${STAGE_AS_SCRIPT}; StageAs ${FLAGS.$@} ${STAGE_FILES_DIR.$s:U${STAGE_DIR.$s}:${STAGE_DIR_FILTER}} ${STAGE_AS.$s:@f@$f ${STAGE_AS_${f:tA}:U${STAGE_AS_${f:T}:U${f:T}}}@} @touch $@ +.endif +.if !target(.stage_as_and_symlink.$s) +.stage_as_and_symlink.$s: stage_as_and_symlink: stage_as_and_symlink.$s stage_as_and_symlink.$s: .dirdep @${STAGE_AS_SCRIPT}; StageAs ${FLAGS.$@} ${STAGE_FILES_DIR.$s:U${STAGE_DIR.$s}:${STAGE_DIR_FILTER}} ${STAGE_AS_AND_SYMLINK.$s:@f@$f ${STAGE_AS_${f:tA}:U${STAGE_AS_${f:T}:U${f:T}}}@} @${STAGE_LINKS_SCRIPT}; StageLinks -s ${STAGE_FILES_DIR.$s:U${STAGE_DIR.$s}:${STAGE_DIR_FILTER}} ${STAGE_AS_AND_SYMLINK.$s:@f@${STAGE_AS_${f:tA}:U${STAGE_AS_${f:T}:U${f:T}}} $f@} @touch $@ +.endif .endfor .endif CLEANFILES += ${STAGE_TARGETS} stage_incs stage_includes +# this lot also only makes sense the first time... +.if !target(__${.PARSEFILE}__) +__${.PARSEFILE}__: + # stage_*links usually needs to follow any others. # for non-jobs mode the order here matters staging: ${STAGE_TARGETS:N*_links} ${STAGE_TARGETS:M*_links} diff --git a/mk/meta2deps.py b/mk/meta2deps.py index 8d0b044a185c..8688213d75d3 100755 --- a/mk/meta2deps.py +++ b/mk/meta2deps.py @@ -37,7 +37,7 @@ """ RCSid: - $Id: meta2deps.py,v 1.22 2016/12/12 19:07:42 sjg Exp $ + $Id: meta2deps.py,v 1.24 2017/02/08 22:17:10 sjg Exp $ Copyright (c) 2011-2013, Juniper Networks, Inc. All rights reserved. @@ -103,20 +103,36 @@ def resolve(path, cwd, last_dir=None, debug=0, debug_out=sys.stderr): return p return None +def cleanpath(path): + """cleanup path without using realpath(3)""" + if path.startswith('/'): + r = '/' + else: + r = '' + p = [] + w = path.split('/') + for d in w: + if not d or d == '.': + continue + if d == '..': + p.pop() + continue + p.append(d) + + return r + '/'.join(p) + def abspath(path, cwd, last_dir=None, debug=0, debug_out=sys.stderr): """ Return an absolute path, resolving via cwd or last_dir if needed. - this gets called a lot, so we try to avoid calling realpath - until we know we have something. + this gets called a lot, so we try to avoid calling realpath. """ rpath = resolve(path, cwd, last_dir, debug, debug_out) if rpath: path = rpath if (path.find('/') < 0 or path.find('./') > 0 or - path.endswith('/..') or - os.path.islink(path)): - return os.path.realpath(path) + path.endswith('/..')): + path = cleanpath(path) return path def sort_unique(list, cmp=None, key=None, reverse=False): @@ -126,6 +142,7 @@ def sort_unique(list, cmp=None, key=None, reverse=False): for e in list: if e == le: continue + le = e nl.append(e) return nl @@ -504,6 +521,8 @@ def parse_path(self, path, cwd, op=None, w=[]): dir = abspath(dir, cwd, self.last_dir, self.debug, self.debug_out) if rdir == dir or rdir.find('./') > 0: rdir = None + if os.path.islink(dir): + rdir = os.path.realpath(dir) # now put path back together path = '/'.join([dir,base]) if self.debug > 1: diff --git a/mk/prog.mk b/mk/prog.mk index 2a4160af1422..ba87a974bc8c 100644 --- a/mk/prog.mk +++ b/mk/prog.mk @@ -1,4 +1,4 @@ -# $Id: prog.mk,v 1.27 2016/08/02 20:52:17 sjg Exp $ +# $Id: prog.mk,v 1.28 2017/02/14 21:26:13 sjg Exp $ .if !target(__${.PARSEFILE}__) __${.PARSEFILE}__: @@ -191,6 +191,7 @@ install_links: maninstall: afterinstall afterinstall: realinstall +install_links: realinstall proginstall: beforeinstall realinstall: beforeinstall .endif diff --git a/mk/subdir.mk b/mk/subdir.mk index 2511d1037503..1d5001acd2a2 100644 --- a/mk/subdir.mk +++ b/mk/subdir.mk @@ -1,4 +1,4 @@ -# $Id: subdir.mk,v 1.15 2016/04/05 15:58:37 sjg Exp $ +# $Id: subdir.mk,v 1.16 2017/02/08 22:16:59 sjg Exp $ # skip missing directories... # $NetBSD: bsd.subdir.mk,v 1.11 1996/04/04 02:05:06 jtc Exp $ @@ -45,13 +45,18 @@ _SUBDIRUSE: .USE done ${SUBDIR}:: - @set -e; if test -d ${.CURDIR}/${.TARGET}.${MACHINE}; then \ - _newdir_=${.TARGET}.${MACHINE}; \ + @set -e; _r=${.CURDIR}/; \ + if test -z "${.TARGET:M/*}"; then \ + if test -d ${.CURDIR}/${.TARGET}.${MACHINE}; then \ + _newdir_=${.TARGET}.${MACHINE}; \ + else \ + _newdir_=${.TARGET}; \ + fi; \ else \ - _newdir_=${.TARGET}; \ + _r= _newdir_=${.TARGET}; \ fi; \ ${ECHO_DIR} "===> $${_newdir_}"; \ - cd ${.CURDIR}/$${_newdir_}; \ + cd $${_r}$${_newdir_}; \ ${.MAKE} _THISDIR_="$${_newdir_}" all .endif diff --git a/mk/sys.mk b/mk/sys.mk index 832dfc81f8c9..55f615d1d8ef 100644 --- a/mk/sys.mk +++ b/mk/sys.mk @@ -1,4 +1,4 @@ -# $Id: sys.mk,v 1.44 2016/10/01 19:11:55 sjg Exp $ +# $Id: sys.mk,v 1.45 2017/02/05 01:26:13 sjg Exp $ # # @(#) Copyright (c) 2003-2009, Simon J. Gerraty # @@ -71,11 +71,11 @@ SYS_OS_MK := ${_sys_mk} # some options we need to know early OPTIONS_DEFAULT_NO += \ DIRDEPS_BUILD \ - DIRDEPS_CACHE \ - META_MODE + DIRDEPS_CACHE OPTIONS_DEFAULT_DEPENDENT += \ AUTO_OBJ/DIRDEPS_BUILD \ + META_MODE/DIRDEPS_BUILD \ STAGING/DIRDEPS_BUILD \ .-include diff --git a/mk/sys.vars.mk b/mk/sys.vars.mk index 2438499581c6..f2cb00e90bc2 100644 --- a/mk/sys.vars.mk +++ b/mk/sys.vars.mk @@ -1,4 +1,4 @@ -# $Id: sys.vars.mk,v 1.1 2016/10/01 19:11:55 sjg Exp $ +# $Id: sys.vars.mk,v 1.2 2017/01/31 07:44:45 sjg Exp $ # # @(#) Copyright (c) 2003-2009, Simon J. Gerraty # @@ -67,5 +67,14 @@ M_tA = tA M_tA = C,.*,('cd' & \&\& 'pwd') 2> /dev/null || echo &,:sh .endif +.if ${MAKE_VERSION:U0} >= 20170130 +# M_cmpv allows comparing dotted versions like 3.1.2 +# ${3.1.2:L:${M_cmpv}} -> 3001002 +# we use big jumps to handle 3 digits per dot: +# ${123.456.789:L:${M_cmpv}} -> 123456789 +M_cmpv.units = 1 1000 1000000 +M_cmpv = S,., ,g:_:range:@i@+ $${_:[-$$i]} \* $${M_cmpv.units:[$$i]}@:S,^,expr 0 ,1:sh +.endif + # absoulte path to what we are reading. _PARSEDIR = ${.PARSEDIR:${M_tA}} diff --git a/os.sh b/os.sh index aba9bbdd8a80..8468ba1b3e7d 100755 --- a/os.sh +++ b/os.sh @@ -17,7 +17,7 @@ # Simon J. Gerraty # RCSid: -# $Id: os.sh,v 1.52 2016/06/17 05:15:14 sjg Exp $ +# $Id: os.sh,v 1.53 2017/01/11 20:01:09 sjg Exp $ # # @(#) Copyright (c) 1994 Simon J. Gerraty # @@ -206,7 +206,13 @@ esac TMP_DIRS=${TMP_DIRS:-"/tmp /var/tmp"} MACHINE_ARCH=${MACHINE_ARCH:-$MACHINE} +case "$MACHINE_ARCH" in +x86*64|amd64) MACHINE32_ARCH=i386;; +*64) MACHINE32_ARCH=`echo $MACHINE_ARCH | sed 's,64,32,'`;; +*) MACHINE32_ARCH=$MACHINE_ARCH;; +esac HOST_ARCH=${HOST_ARCH:-$MACHINE_ARCH} +HOST_ARCH32=${HOST_ARCH32:-$MACHINE32_ARCH} # we mount server:/share/arch/$SHARE_ARCH as /usr/local SHARE_ARCH_DEFAULT=$OS/$OSMAJOR.X/$HOST_ARCH SHARE_ARCH=${SHARE_ARCH:-$SHARE_ARCH_DEFAULT} @@ -215,7 +221,8 @@ TR=${TR:-tr} # Some people like have /share/$HOST_TARGET/bin etc. HOST_TARGET=`echo ${OS}${OSMAJOR}-$HOST_ARCH | tr -d / | toLower` -export HOST_TARGET +HOST_TARGET32=`echo ${OS}${OSMAJOR}-$HOST_ARCH32 | tr -d / | toLower` +export HOST_TARGET HOST_TARGET32 case `echo -n .` in -n*) N=; C="\c";; *) N=-n; C=;; esac diff --git a/parse.c b/parse.c index bbc43bd1a529..e84cae17ffe6 100644 --- a/parse.c +++ b/parse.c @@ -1,4 +1,4 @@ -/* $NetBSD: parse.c,v 1.217 2016/12/09 22:56:21 sjg Exp $ */ +/* $NetBSD: parse.c,v 1.218 2017/03/01 16:39:49 sjg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -69,14 +69,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: parse.c,v 1.217 2016/12/09 22:56:21 sjg Exp $"; +static char rcsid[] = "$NetBSD: parse.c,v 1.218 2017/03/01 16:39:49 sjg Exp $"; #else #include #ifndef lint #if 0 static char sccsid[] = "@(#)parse.c 8.3 (Berkeley) 3/19/94"; #else -__RCSID("$NetBSD: parse.c,v 1.217 2016/12/09 22:56:21 sjg Exp $"); +__RCSID("$NetBSD: parse.c,v 1.218 2017/03/01 16:39:49 sjg Exp $"); #endif #endif /* not lint */ #endif @@ -578,7 +578,11 @@ loadfile(const char *path, int fd) /* truncate malloc region to actual length (maybe not useful) */ if (lf->len > 0) { + /* as for mmap case, ensure trailing \n */ + if (lf->buf[lf->len - 1] != '\n') + lf->len++; lf->buf = bmake_realloc(lf->buf, lf->len); + lf->buf[lf->len - 1] = '\n'; } #ifdef HAVE_MMAP diff --git a/unit-tests/varmisc.exp b/unit-tests/varmisc.exp index e2af496afabe..ffe8f8b867c8 100644 --- a/unit-tests/varmisc.exp +++ b/unit-tests/varmisc.exp @@ -17,4 +17,9 @@ false FALSE do not evaluate or expand :? if discarding is set +year=2016 month=04 day=01 +date=20160401 +Version=123.456.789 == 123456789 +Literal=3.4.5 == 3004005 +We have target specific vars exit status 0 diff --git a/unit-tests/varmisc.mk b/unit-tests/varmisc.mk index 14b52d22c3e6..a0b8f2dc84f4 100644 --- a/unit-tests/varmisc.mk +++ b/unit-tests/varmisc.mk @@ -1,8 +1,9 @@ -# $Id: varmisc.mk,v 1.5 2015/10/12 17:10:48 sjg Exp $ +# $Id: varmisc.mk,v 1.9 2017/02/01 18:44:54 sjg Exp $ # # Miscellaneous variable tests. -all: unmatched_var_paren D_true U_true D_false U_false Q_lhs Q_rhs NQ_none +all: unmatched_var_paren D_true U_true D_false U_false Q_lhs Q_rhs NQ_none \ + strftime cmpv unmatched_var_paren: @echo ${foo::=foo-text} @@ -40,3 +41,22 @@ Q_rhs: NQ_none: @echo do not evaluate or expand :? if discarding @echo ${VSET:U${1:L:?${True}:${False}}} + +April1= 1459494000 + +# slightly contorted syntax to use utc via variable +strftime: + @echo ${year=%Y month=%m day=%d:L:gmtime=1459494000} + @echo date=${%Y%m%d:L:${gmtime=${April1}:L}} + +# big jumps to handle 3 digits per step +M_cmpv.units = 1 1000 1000000 +M_cmpv = S,., ,g:_:range:@i@+ $${_:[-$$i]} \* $${M_cmpv.units:[$$i]}@:S,^,expr 0 ,1:sh + +Version = 123.456.789 +cmpv.only = target specific vars + +cmpv: + @echo Version=${Version} == ${Version:${M_cmpv}} + @echo Literal=3.4.5 == ${3.4.5:L:${M_cmpv}} + @echo We have ${${.TARGET:T}.only} diff --git a/var.c b/var.c index 81e9daff7060..91c11a8e2981 100644 --- a/var.c +++ b/var.c @@ -1,4 +1,4 @@ -/* $NetBSD: var.c,v 1.208 2016/06/03 01:21:59 sjg Exp $ */ +/* $NetBSD: var.c,v 1.213 2017/02/01 18:39:27 sjg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -69,14 +69,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: var.c,v 1.208 2016/06/03 01:21:59 sjg Exp $"; +static char rcsid[] = "$NetBSD: var.c,v 1.213 2017/02/01 18:39:27 sjg Exp $"; #else #include #ifndef lint #if 0 static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94"; #else -__RCSID("$NetBSD: var.c,v 1.208 2016/06/03 01:21:59 sjg Exp $"); +__RCSID("$NetBSD: var.c,v 1.213 2017/02/01 18:39:27 sjg Exp $"); #endif #endif /* not lint */ #endif @@ -2139,6 +2139,51 @@ VarUniq(const char *str) return Buf_Destroy(&buf, FALSE); } +/*- + *----------------------------------------------------------------------- + * VarRange -- + * Return an integer sequence + * + * Input: + * str String whose words provide default range + * ac range length, if 0 use str words + * + * Side Effects: + * None. + * + *----------------------------------------------------------------------- + */ +static char * +VarRange(const char *str, int ac) +{ + Buffer buf; /* Buffer for new string */ + char tmp[32]; /* each element */ + char **av; /* List of words to affect */ + char *as; /* Word list memory */ + int i, n; + + Buf_Init(&buf, 0); + if (ac > 0) { + as = NULL; + av = NULL; + } else { + av = brk_string(str, &ac, FALSE, &as); + } + for (i = 0; i < ac; i++) { + n = snprintf(tmp, sizeof(tmp), "%d", 1 + i); + if (n >= (int)sizeof(tmp)) + break; + Buf_AddBytes(&buf, n, tmp); + if (i != ac - 1) + Buf_AddByte(&buf, ' '); + } + + free(as); + free(av); + + return Buf_Destroy(&buf, FALSE); +} + /*- *----------------------------------------------------------------------- @@ -2380,12 +2425,12 @@ VarHash(char *str) } static char * -VarStrftime(const char *fmt, int zulu) +VarStrftime(const char *fmt, int zulu, time_t utc) { char buf[BUFSIZ]; - time_t utc; - time(&utc); + if (!utc) + time(&utc); if (!*fmt) fmt = "%c"; strftime(buf, sizeof(buf), fmt, zulu ? gmtime(&utc) : localtime(&utc)); @@ -2482,6 +2527,9 @@ VarStrftime(const char *fmt, int zulu) /* we now have some modifiers with long names */ #define STRMOD_MATCH(s, want, n) \ (strncmp(s, want, n) == 0 && (s[n] == endc || s[n] == ':')) +#define STRMOD_MATCHX(s, want, n) \ + (strncmp(s, want, n) == 0 && (s[n] == endc || s[n] == ':' || s[n] == '=')) +#define CHARMOD_MATCH(c) (c == endc || c == ':') static char * ApplyModifiers(char *nstr, const char *tstr, @@ -2493,12 +2541,14 @@ ApplyModifiers(char *nstr, const char *tstr, const char *cp; /* Secondary pointer into str (place marker * for tstr) */ char *newStr; /* New value to return */ + char *ep; char termc; /* Character which terminated scan */ int cnt; /* Used to count brace pairs when variable in * in parens or braces */ char delim; int modifier; /* that we are processing */ Var_Parse_State parsestate; /* Flags passed to helper functions */ + time_t utc; /* for VarStrftime */ delim = '\0'; parsestate.oneBigWord = FALSE; @@ -2690,6 +2740,28 @@ ApplyModifiers(char *nstr, const char *tstr, free(loop.str); break; } + case '_': /* remember current value */ + cp = tstr + 1; /* make sure it is set */ + if (STRMOD_MATCHX(tstr, "_", 1)) { + if (tstr[1] == '=') { + char *np; + int n; + + cp++; + n = strcspn(cp, ":)}"); + np = bmake_strndup(cp, n+1); + np[n] = '\0'; + cp = tstr + 2 + n; + Var_Set(np, nstr, ctxt, 0); + free(np); + } else { + Var_Set("_", nstr, ctxt, 0); + } + newStr = nstr; + termc = *cp; + break; + } + goto default_case; case 'D': case 'U': { @@ -2895,8 +2967,6 @@ ApplyModifiers(char *nstr, const char *tstr, * integer for :[N], or two integers * separated by ".." for :[start..end]. */ - char *ep; - VarSelectWords_t seldata = { 0, 0 }; seldata.start = strtol(estr, &ep, 0); @@ -2955,9 +3025,15 @@ ApplyModifiers(char *nstr, const char *tstr, } case 'g': cp = tstr + 1; /* make sure it is set */ - if (STRMOD_MATCH(tstr, "gmtime", 6)) { - newStr = VarStrftime(nstr, 1); - cp = tstr + 6; + if (STRMOD_MATCHX(tstr, "gmtime", 6)) { + if (tstr[6] == '=') { + utc = strtoul(&tstr[7], &ep, 10); + cp = ep; + } else { + utc = 0; + cp = tstr + 6; + } + newStr = VarStrftime(nstr, 1, utc); termc = *cp; } else { goto default_case; @@ -2975,9 +3051,15 @@ ApplyModifiers(char *nstr, const char *tstr, break; case 'l': cp = tstr + 1; /* make sure it is set */ - if (STRMOD_MATCH(tstr, "localtime", 9)) { - newStr = VarStrftime(nstr, 0); - cp = tstr + 9; + if (STRMOD_MATCHX(tstr, "localtime", 9)) { + if (tstr[9] == '=') { + utc = strtoul(&tstr[10], &ep, 10); + cp = ep; + } else { + utc = 0; + cp = tstr + 9; + } + newStr = VarStrftime(nstr, 0, utc); termc = *cp; } else { goto default_case; @@ -3026,7 +3108,6 @@ ApplyModifiers(char *nstr, const char *tstr, goto get_numeric; default: if (isdigit((unsigned char)tstr[3])) { - char *ep; get_numeric: parsestate.varSpace = @@ -3447,6 +3528,23 @@ ApplyModifiers(char *nstr, const char *tstr, break; } goto default_case; + case 'r': + cp = tstr + 1; /* make sure it is set */ + if (STRMOD_MATCHX(tstr, "range", 5)) { + int n; + + if (tstr[5] == '=') { + n = strtoul(&tstr[6], &ep, 10); + cp = ep; + } else { + n = 0; + cp = tstr + 5; + } + newStr = VarRange(nstr, n); + termc = *cp; + break; + } + goto default_case; case 'O': { char otype;