Merge bmake-20200517
Changes since 20181221 are mostly portability related hence the large gap in versions imported. There are however some bug fixes, and a rework of filemon handling. In NetBSD make/filemon/filemon_ktrace.c allows use of fktrace and elimination of filemon(4) which has not had the TLC it needs. FreeBSD filemon(4) is in much better shape, so bmake/filemon/filemon_dev.c allows use of that, with a bit less overhead than the ktrace model. Summary of changes from ChangeLog o str.c: empty string does not match % pattern plus unit-test changes o var.c: import handling of old sysV style modifier using '%' o str.c: refactor brk_string o meta.c: meta_oodate, CHECK_VALID_META is too aggressive for CMD a blank command is perfectly valid. o meta.c: meta_oodate, check for corrupted meta file earlier and more often. * meta.c: meta_compat_parent check for USE_FILEMON patch from Soeren Tempel o meta.c: fix compat mode, need to call meta_job_output() o job.c: extra fds for meta mode not needed if using filemon_dev o meta.c: avoid passing NULL to filemon_*() when meta_needed() returns FALSE. o filemon/filemon_{dev,ktrace}.c: allow selection of filemon implementation. filemon_dev.c uses the kernel module while filemon_ktrace.c leverages the fktrace api available in NetBSD. filemon_ktrace.c can hopefully form the basis for adding support for other tracing mechanisms such as strace on Linux. o meta.c: when target is out-of-date per normal make rules record value of .OODATE in meta file. o parse.c: don't pass NULL to realpath(3) some versions cannot handle it. o parse.c: ParseDoDependency: free paths rather than assert plus more unit-tests
This commit is contained in:
commit
49caa483b3
@ -1,3 +1,138 @@
|
||||
2020-05-17 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20200517
|
||||
Merge with NetBSD make, pick up
|
||||
o modified dollar tests to avoid shell dependencies
|
||||
o new tests for .INCLUDEFROM
|
||||
|
||||
2020-05-16 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* unit-tests/dollar.mk: tweak '1 dollar literal' test
|
||||
to not depend so much on shell behavior
|
||||
|
||||
2020-05-10 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20200510
|
||||
Merge with NetBSD make, pick up
|
||||
o unit test for dollar handling
|
||||
|
||||
2020-05-06 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20200506
|
||||
Merge with NetBSD make, pick up
|
||||
o str.c: empty string does not match % pattern
|
||||
plus unit-test changes
|
||||
|
||||
2020-05-04 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20200504
|
||||
May the 4th be with you
|
||||
Merge with NetBSD make, pick up
|
||||
o var.c: import handling of old sysV style modifier using '%'
|
||||
o str.c: refactor brk_string
|
||||
o unit-tests: add test case for lazy conditions
|
||||
|
||||
2020-04-18 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20200418
|
||||
|
||||
* configure.in: use_makefile=no for cygwin et al.
|
||||
case insensitive filesystems just don't work if both
|
||||
makefile and Makefile exist.
|
||||
NOTE: bmake does not support cygwin and likely never will,
|
||||
but if brave souls want to try it - help them out.
|
||||
|
||||
2020-04-02 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20200402
|
||||
Merge with NetBSD make, pick up
|
||||
o meta.c: meta_oodate, CHECK_VALID_META is too aggressive for CMD
|
||||
a blank command is perfectly valid.
|
||||
|
||||
2020-03-30 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20200330
|
||||
Merge with NetBSD make, pick up
|
||||
o make.h: extern debug_file
|
||||
|
||||
2020-03-18 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20200318
|
||||
Merge with NetBSD make, pick up
|
||||
o meta.c: meta_oodate, check for corrupted meta file
|
||||
earlier and more often.
|
||||
|
||||
2020-02-20 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20200220
|
||||
|
||||
2020-02-19 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* boot-strap: unset MAKEFLAGS
|
||||
|
||||
2020-02-12 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20200212
|
||||
* meta.c: meta_compat_parent check for USE_FILEMON
|
||||
patch from Soeren Tempel
|
||||
|
||||
2020-02-05 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION: 20200205
|
||||
Merge with NetBSD make, pick up
|
||||
o meta.c: fix compat mode, need to call meta_job_output()
|
||||
o job.c: extra fds for meta mode not needed if using filemon_dev
|
||||
|
||||
2020-01-22 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION: 20200122
|
||||
Merge with NetBSD make, pick up
|
||||
o meta.c: avoid passing NULL to filemon_*() when meta_needed()
|
||||
returns FALSE.
|
||||
|
||||
2020-01-21 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION: 20200121
|
||||
Merge with NetBSD make, pick up
|
||||
o filemon/filemon_{dev,ktrace}.c: allow selection of
|
||||
filemon implementation. filemon_dev.c uses the kernel module
|
||||
while filemon_ktrace.c leverages the fktrace api available in
|
||||
NetBSD. filemon_ktrace.c can hopefully form the basis for
|
||||
adding support for other tracing mechanisms such as strace on
|
||||
Linux.
|
||||
o meta.c: when target is out-of-date per normal make rules
|
||||
record value of .OODATE in meta file.
|
||||
|
||||
2019-09-26 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION: 20190926
|
||||
Merge with NetBSD make, pick up
|
||||
o parse.c: don't pass NULL to realpath(3)
|
||||
some versions cannot handle it.
|
||||
|
||||
2019-04-09 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION: 20190409
|
||||
Merge with NetBSD make, pick up
|
||||
o parse.c: ParseDoDependency: free paths rather than assert
|
||||
|
||||
2018-12-22 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION: 20181222
|
||||
|
||||
* configure.in: add --without-makefile to avoid generating
|
||||
makefile and make-bootstrap.sh
|
||||
|
||||
* include Makefile.inc if it exists
|
||||
|
||||
* Use Makefile and Makefile.config.in in unit-tests
|
||||
so we can use just: make obj && make && make test
|
||||
when bmake is already available.
|
||||
We add --without-makefile to CONFIGURE_ARGS in this case.
|
||||
|
||||
* tweak bsd.after-import.mk (captures Makefile.config etc
|
||||
after import to FreeBSD for example) to cope with all the above.
|
||||
|
||||
2018-12-21 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION: 20181221
|
||||
|
@ -22,6 +22,9 @@ configure.in
|
||||
dir.c
|
||||
dir.h
|
||||
dirname.c
|
||||
filemon/filemon.h
|
||||
filemon/filemon_dev.c
|
||||
filemon/filemon_ktrace.c
|
||||
find_lib.sh
|
||||
for.c
|
||||
getopt.c
|
||||
@ -94,13 +97,18 @@ suff.c
|
||||
targ.c
|
||||
trace.c
|
||||
trace.h
|
||||
unit-tests/Makefile.in
|
||||
unit-tests/Makefile
|
||||
unit-tests/Makefile.config.in
|
||||
unit-tests/comment.exp
|
||||
unit-tests/comment.mk
|
||||
unit-tests/cond1.exp
|
||||
unit-tests/cond1.mk
|
||||
unit-tests/cond2.exp
|
||||
unit-tests/cond2.mk
|
||||
unit-tests/cond-late.mk
|
||||
unit-tests/cond-late.exp
|
||||
unit-tests/dollar.exp
|
||||
unit-tests/dollar.mk
|
||||
unit-tests/doterror.exp
|
||||
unit-tests/doterror.mk
|
||||
unit-tests/dotwait.exp
|
||||
@ -123,6 +131,10 @@ unit-tests/hash.exp
|
||||
unit-tests/hash.mk
|
||||
unit-tests/impsrc.exp
|
||||
unit-tests/impsrc.mk
|
||||
unit-tests/include-main.exp
|
||||
unit-tests/include-main.mk
|
||||
unit-tests/include-sub.mk
|
||||
unit-tests/include-subsub.mk
|
||||
unit-tests/misc.exp
|
||||
unit-tests/misc.mk
|
||||
unit-tests/moderrs.exp
|
||||
@ -163,6 +175,8 @@ unit-tests/varcmd.exp
|
||||
unit-tests/varcmd.mk
|
||||
unit-tests/varmisc.exp
|
||||
unit-tests/varmisc.mk
|
||||
unit-tests/varmod-edge.exp
|
||||
unit-tests/varmod-edge.mk
|
||||
unit-tests/varquote.exp
|
||||
unit-tests/varquote.mk
|
||||
unit-tests/varshell.exp
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: Makefile,v 1.99 2017/08/13 20:12:53 sjg Exp $
|
||||
# $Id: Makefile,v 1.104 2020/02/06 01:33:54 sjg Exp $
|
||||
|
||||
PROG= bmake
|
||||
|
||||
@ -56,6 +56,7 @@ SRCS+= \
|
||||
lstSucc.c
|
||||
|
||||
.-include "VERSION"
|
||||
.-include "Makefile.inc"
|
||||
|
||||
# this file gets generated by configure
|
||||
.-include "Makefile.config"
|
||||
@ -78,10 +79,22 @@ CFLAGS+= ${COPTS.${.ALLSRC:M*.c:T:u}}
|
||||
COPTS.main.c+= "-DMAKE_VERSION=\"${_MAKE_VERSION}\""
|
||||
|
||||
# meta mode can be useful even without filemon
|
||||
# should be set by now
|
||||
USE_FILEMON ?= no
|
||||
.if ${USE_FILEMON:tl} != "no"
|
||||
.PATH: ${.CURDIR}/filemon
|
||||
SRCS+= filemon_${USE_FILEMON}.c
|
||||
COPTS.meta.c+= -DUSE_FILEMON -DUSE_FILEMON_${USE_FILEMON:tu}
|
||||
COPTS.job.c+= ${COPTS.meta.c}
|
||||
|
||||
.if ${USE_FILEMON} == "dev"
|
||||
FILEMON_H ?= /usr/include/dev/filemon/filemon.h
|
||||
.if exists(${FILEMON_H}) && ${FILEMON_H:T} == "filemon.h"
|
||||
COPTS.meta.c += -DHAVE_FILEMON_H -I${FILEMON_H:H}
|
||||
COPTS.filemon_dev.c += -DHAVE_FILEMON_H -I${FILEMON_H:H}
|
||||
.endif
|
||||
.endif # USE_FILEMON == dev
|
||||
|
||||
.endif # USE_FILEMON
|
||||
|
||||
.PATH: ${srcdir}
|
||||
.PATH: ${srcdir}/lst.lib
|
||||
@ -198,6 +211,8 @@ main.o: ${SRCS} ${.CURDIR}/VERSION
|
||||
|
||||
.if ${MK_AUTOCONF_MK} == "yes"
|
||||
CONFIGURE_DEPS += ${.CURDIR}/VERSION
|
||||
# we do not need or want the generated makefile
|
||||
CONFIGURE_ARGS += --without-makefile
|
||||
.include <autoconf.mk>
|
||||
.endif
|
||||
SHARE_MK?=${SHAREDIR}/mk
|
||||
|
@ -14,7 +14,8 @@ CFLAGS+= ${CPPFLAGS} @DEFS@
|
||||
LDFLAGS+= @LDFLAGS@
|
||||
LIBOBJS+= @LIBOBJS@
|
||||
LDADD+= @LIBS@
|
||||
USE_META= @use_meta@
|
||||
USE_META?= @use_meta@
|
||||
USE_FILEMON?= @use_filemon@
|
||||
FILEMON_H?= @filemon_h@
|
||||
BMAKE_PATH_MAX?= @bmake_path_max@
|
||||
# used if MAXPATHLEN not defined
|
||||
|
@ -1,2 +1,2 @@
|
||||
# keep this compatible with sh and make
|
||||
_MAKE_VERSION=20181221
|
||||
_MAKE_VERSION=20200517
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: arch.c,v 1.70 2017/04/16 20:49:09 riastradh Exp $ */
|
||||
/* $NetBSD: arch.c,v 1.71 2019/10/05 23:35:57 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1993
|
||||
@ -69,14 +69,14 @@
|
||||
*/
|
||||
|
||||
#ifndef MAKE_NATIVE
|
||||
static char rcsid[] = "$NetBSD: arch.c,v 1.70 2017/04/16 20:49:09 riastradh Exp $";
|
||||
static char rcsid[] = "$NetBSD: arch.c,v 1.71 2019/10/05 23:35:57 mrg 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.70 2017/04/16 20:49:09 riastradh Exp $");
|
||||
__RCSID("$NetBSD: arch.c,v 1.71 2019/10/05 23:35:57 mrg Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
@ -682,7 +682,7 @@ ArchStatMember(char *archive, char *member, Boolean hash)
|
||||
arh.AR_SIZE[sizeof(arh.AR_SIZE)-1] = '\0';
|
||||
size = (int)strtol(arh.AR_SIZE, NULL, 10);
|
||||
|
||||
(void)strncpy(memName, arh.AR_NAME, sizeof(arh.AR_NAME));
|
||||
memcpy(memName, arh.AR_NAME, sizeof(arh.AR_NAME));
|
||||
for (cp = &memName[AR_MAX_NAME_LEN]; *cp == ' '; cp--) {
|
||||
continue;
|
||||
}
|
||||
|
@ -89,6 +89,10 @@
|
||||
# disable use of filemon(9) which is currently only
|
||||
# available for NetBSD and FreeBSD.
|
||||
#
|
||||
# --with-filemon=ktrace
|
||||
# on NetBSD or others with fktrace(2), use ktrace
|
||||
# version of filemon.
|
||||
#
|
||||
# --with-filemon="path/to/filemon.h"
|
||||
# enables use of filemon(9) by meta mode.
|
||||
#
|
||||
@ -111,7 +115,7 @@
|
||||
# Simon J. Gerraty <sjg@crufty.net>
|
||||
|
||||
# RCSid:
|
||||
# $Id: boot-strap,v 1.49 2016/05/29 00:09:14 sjg Exp $
|
||||
# $Id: boot-strap,v 1.51 2020/02/19 16:46:23 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2001 Simon J. Gerraty
|
||||
#
|
||||
@ -161,6 +165,8 @@ cmd_args="$@"
|
||||
|
||||
# clear some things from the environment that we care about
|
||||
unset MAKEOBJDIR MAKEOBJDIRPREFIX
|
||||
# or that might be incompatible
|
||||
unset MAKE MAKEFLAGS
|
||||
|
||||
# --install[-host-target] will set this
|
||||
INSTALL_PREFIX=
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: bsd.after-import.mk,v 1.13 2017/08/13 00:56:10 sjg Exp $
|
||||
# $Id: bsd.after-import.mk,v 1.15 2018/12/30 17:14:24 sjg Exp $
|
||||
|
||||
# This makefile is for use when integrating bmake into a BSD build
|
||||
# system. Use this makefile after importing bmake.
|
||||
@ -63,7 +63,7 @@ MAKEFILE_SED = sed -e '/^MACHINE/d' \
|
||||
-e 's,${SRCTOP},$${SRCTOP},g'
|
||||
|
||||
# These are the simple files we want to capture
|
||||
configured_files= config.h Makefile.config unit-tests/Makefile
|
||||
configured_files= config.h Makefile.config unit-tests/Makefile.config
|
||||
|
||||
after-import: bootstrap ${MAKEFILE}
|
||||
.for f in ${configured_files:M*.[ch]}
|
||||
@ -87,7 +87,6 @@ _makefile: bootstrap ${MAKEFILE}
|
||||
@(echo '# This is a generated file, do NOT edit!'; \
|
||||
echo '# See ${_this:S,${SRCTOP}/,,}'; \
|
||||
echo '#'; echo '# $$${HOST_OS}$$'; \
|
||||
echo; echo '.sinclude "Makefile.inc"'; \
|
||||
echo; echo 'SRCTOP?= $${.CURDIR:${.CURDIR:S,${SRCTOP}/,,:C,[^/]+,H,g:S,/,:,g}}'; \
|
||||
echo; echo '# look here first for config.h'; \
|
||||
echo 'CFLAGS+= -I$${.CURDIR}'; echo; \
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: compat.c,v 1.107 2017/07/20 19:29:54 sjg Exp $ */
|
||||
/* $NetBSD: compat.c,v 1.110 2020/01/19 19:42:32 riastradh 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.107 2017/07/20 19:29:54 sjg Exp $";
|
||||
static char rcsid[] = "$NetBSD: compat.c,v 1.110 2020/01/19 19:42:32 riastradh 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.107 2017/07/20 19:29:54 sjg Exp $");
|
||||
__RCSID("$NetBSD: compat.c,v 1.110 2020/01/19 19:42:32 riastradh Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
@ -407,7 +407,7 @@ CompatRunCommand(void *cmdp, void *gnp)
|
||||
|
||||
#ifdef USE_META
|
||||
if (useMeta) {
|
||||
meta_compat_parent();
|
||||
meta_compat_parent(cpid);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -143,7 +143,7 @@
|
||||
/* Define to 1 if you have the `strtol' function. */
|
||||
#undef HAVE_STRTOL
|
||||
|
||||
/* Define to 1 if `struct stat' is a member of `st_rdev'. */
|
||||
/* Define to 1 if `st_rdev' is a member of `struct stat'. */
|
||||
#undef HAVE_STRUCT_STAT_ST_RDEV
|
||||
|
||||
/* Define to 1 if your `struct stat' has `st_rdev'. Deprecated, use
|
||||
|
1105
contrib/bmake/configure
vendored
1105
contrib/bmake/configure
vendored
File diff suppressed because it is too large
Load Diff
@ -1,11 +1,11 @@
|
||||
dnl
|
||||
dnl RCSid:
|
||||
dnl $Id: configure.in,v 1.59 2017/11/26 22:39:20 sjg Exp $
|
||||
dnl $Id: configure.in,v 1.63 2020/04/19 05:17:57 sjg Exp $
|
||||
dnl
|
||||
dnl Process this file with autoconf to produce a configure script
|
||||
dnl
|
||||
AC_PREREQ(2.50)
|
||||
AC_INIT([bmake], [20171126], [sjg@NetBSD.org])
|
||||
AC_INIT([bmake], [20200418], [sjg@NetBSD.org])
|
||||
AC_CONFIG_HEADERS(config.h)
|
||||
|
||||
dnl make srcdir absolute
|
||||
@ -16,6 +16,7 @@ esac
|
||||
|
||||
dnl get _MAKE_VERSION
|
||||
. $srcdir/VERSION
|
||||
OS=`uname -s`
|
||||
|
||||
dnl
|
||||
AC_ARG_WITH(defshell,
|
||||
@ -32,6 +33,17 @@ no) ;;
|
||||
;;
|
||||
esac])
|
||||
dnl
|
||||
case "$OS" in
|
||||
CYGWIN*|MINGW*) use_makefile=no;;
|
||||
*) use_makefile=yes;;
|
||||
esac
|
||||
AC_ARG_WITH(makefile,
|
||||
[ --without-makefile dissable use of generated makefile],
|
||||
[case "${withval}" in
|
||||
yes|no) use_makefile=${withval};;
|
||||
*) AC_MSG_ERROR(bad value ${withval} given for makefile) ;;
|
||||
esac])
|
||||
dnl
|
||||
use_meta=yes
|
||||
AC_ARG_WITH(meta,
|
||||
[ --without-meta dissable use of meta-mode],
|
||||
@ -41,30 +53,41 @@ yes|no) use_meta=${withval};;
|
||||
esac])
|
||||
dnl
|
||||
AC_ARG_WITH(filemon,
|
||||
[ --with-filemon=path/filemon.h indicate path to filemon.h for meta-mode],
|
||||
[ --with-filemon={no,dev,ktrace,path/filemon.h} indicate filemon method for meta-mode. Path to filemon.h implies dev],
|
||||
[ case "/${withval}" in
|
||||
/no|*/filemon.h) filemon_h="${withval}";;
|
||||
/no) use_filemon=no;;
|
||||
/*trace) filemon_h=no use_filemon="${withval}";;
|
||||
*/filemon.h) filemon_h="${withval}";;
|
||||
*/filemon*) filemon_h="${withval}/filemon.h";;
|
||||
*) AC_MSG_ERROR(bad value ${withval} given for filemon) ;;
|
||||
esac],
|
||||
[
|
||||
OS=`uname -s`
|
||||
for d in "/usr/include/dev/filemon" "$prefix/include/dev/filemon" "$srcdir/filemon" "$srcdir/../filemon" "$srcdir/../../sys/dev/filemon"
|
||||
do
|
||||
for x in "/$OS" ""
|
||||
do
|
||||
filemon_h="$d$x/filemon.h"
|
||||
test -s "$filemon_h" && break
|
||||
done
|
||||
test -s "$filemon_h" && break
|
||||
done
|
||||
test -s "${filemon_h:-/dev/null}" || filemon_h=no
|
||||
case "$OS" in
|
||||
NetBSD) filemon_h=no use_filemon=ktrace;;
|
||||
*)
|
||||
for d in "/usr/include/dev/filemon" "$prefix/include/dev/filemon" "$srcdir/../../sys/dev/filemon"
|
||||
do
|
||||
for x in "/$OS" ""
|
||||
do
|
||||
filemon_h="$d$x/filemon.h"
|
||||
test -s "$filemon_h" && break
|
||||
done
|
||||
test -s "$filemon_h" && { use_filemon=dev; break; }
|
||||
done
|
||||
;;
|
||||
esac
|
||||
use_filemon=${use_filemon:-no}
|
||||
case "$use_filemon" in
|
||||
dev) ;;
|
||||
*) filemon_h=no;;
|
||||
esac
|
||||
])
|
||||
dnl echo "Note: use_meta=$use_meta filemon_h=$filemon_h" >&6
|
||||
dnl echo "Note: use_meta=$use_meta use_filemon=$use_filemon filemon_h=$filemon_h" >&6
|
||||
case "$use_meta" in
|
||||
yes)
|
||||
case "$filemon_h" in
|
||||
*.h) echo "Using: filemon=$filemon_h" >&6;;
|
||||
case "$use_filemon" in
|
||||
no) ;;
|
||||
*) echo "Using: filemon_${use_filemon}.c" >&6;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
@ -388,10 +411,14 @@ AC_SUBST(INSTALL)
|
||||
AC_SUBST(GCC)
|
||||
AC_SUBST(diff_u)
|
||||
AC_SUBST(use_meta)
|
||||
AC_SUBST(use_filemon)
|
||||
AC_SUBST(filemon_h)
|
||||
AC_SUBST(_MAKE_VERSION)
|
||||
AC_OUTPUT(makefile Makefile.config make-bootstrap.sh unit-tests/Makefile)
|
||||
|
||||
bm_outfiles="Makefile.config unit-tests/Makefile.config make-bootstrap.sh"
|
||||
if test $use_makefile = yes; then
|
||||
bm_outfiles="makefile $bm_outfiles"
|
||||
fi
|
||||
AC_OUTPUT($bm_outfiles)
|
||||
cat <<EOF
|
||||
|
||||
You can now run
|
||||
|
53
contrib/bmake/filemon/filemon.h
Normal file
53
contrib/bmake/filemon/filemon.h
Normal file
@ -0,0 +1,53 @@
|
||||
/* $NetBSD: filemon.h,v 1.2 2020/01/22 22:10:36 sjg Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2019 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Taylor R. Campbell.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FILEMON_H_
|
||||
#define FILEMON_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
struct filemon;
|
||||
|
||||
const char *
|
||||
filemon_path(void);
|
||||
|
||||
struct filemon *
|
||||
filemon_open(void);
|
||||
int filemon_close(struct filemon *);
|
||||
|
||||
int filemon_setfd(struct filemon *, int);
|
||||
void filemon_setpid_parent(struct filemon *, pid_t);
|
||||
int filemon_setpid_child(const struct filemon *, pid_t);
|
||||
|
||||
int filemon_readfd(const struct filemon *);
|
||||
int filemon_process(struct filemon *);
|
||||
|
||||
#endif /* FILEMON_H_ */
|
151
contrib/bmake/filemon/filemon_dev.c
Normal file
151
contrib/bmake/filemon/filemon_dev.c
Normal file
@ -0,0 +1,151 @@
|
||||
/* $NetBSD: filemon_dev.c,v 1.1 2020/01/19 19:49:37 riastradh Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2020 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Taylor R. Campbell.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "filemon.h"
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef HAVE_FILEMON_H
|
||||
# include <filemon.h>
|
||||
#endif
|
||||
|
||||
#ifndef _PATH_FILEMON
|
||||
#define _PATH_FILEMON "/dev/filemon"
|
||||
#endif
|
||||
|
||||
struct filemon {
|
||||
int fd;
|
||||
};
|
||||
|
||||
const char *
|
||||
filemon_path(void)
|
||||
{
|
||||
|
||||
return _PATH_FILEMON;
|
||||
}
|
||||
|
||||
struct filemon *
|
||||
filemon_open(void)
|
||||
{
|
||||
struct filemon *F;
|
||||
unsigned i;
|
||||
int error;
|
||||
|
||||
/* Allocate and zero a struct filemon object. */
|
||||
F = calloc(1, sizeof(*F));
|
||||
if (F == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Try opening /dev/filemon, up to six times (cargo cult!). */
|
||||
for (i = 0; (F->fd = open(_PATH_FILEMON, O_RDWR)) == -1; i++) {
|
||||
if (i == 5) {
|
||||
error = errno;
|
||||
goto fail0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Success! */
|
||||
return F;
|
||||
|
||||
fail0: free(F);
|
||||
errno = error;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
filemon_setfd(struct filemon *F, int fd)
|
||||
{
|
||||
|
||||
/* Point the kernel at this file descriptor. */
|
||||
if (ioctl(F->fd, FILEMON_SET_FD, &fd) == -1)
|
||||
return -1;
|
||||
|
||||
/* No need for it in userland any more; close it. */
|
||||
(void)close(fd);
|
||||
|
||||
/* Success! */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
filemon_setpid_parent(struct filemon *F, pid_t pid)
|
||||
{
|
||||
/* Nothing to do! */
|
||||
}
|
||||
|
||||
int
|
||||
filemon_setpid_child(const struct filemon *F, pid_t pid)
|
||||
{
|
||||
|
||||
/* Just pass it on to the kernel. */
|
||||
return ioctl(F->fd, FILEMON_SET_PID, &pid);
|
||||
}
|
||||
|
||||
int
|
||||
filemon_close(struct filemon *F)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
/* Close the filemon device fd. */
|
||||
if (close(F->fd) == -1 && error == 0)
|
||||
error = errno;
|
||||
|
||||
/* Free the filemon descriptor. */
|
||||
free(F);
|
||||
|
||||
/* Set errno and return -1 if anything went wrong. */
|
||||
if (error) {
|
||||
errno = error;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Success! */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
filemon_readfd(const struct filemon *F)
|
||||
{
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
filemon_process(struct filemon *F)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
878
contrib/bmake/filemon/filemon_ktrace.c
Normal file
878
contrib/bmake/filemon/filemon_ktrace.c
Normal file
@ -0,0 +1,878 @@
|
||||
/* $NetBSD: filemon_ktrace.c,v 1.2 2020/01/19 20:22:57 riastradh Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2019 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Taylor R. Campbell.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#define _KERNTYPES /* register_t */
|
||||
|
||||
#include "filemon.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/rbtree.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <sys/ktrace.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef AT_CWD
|
||||
#define AT_CWD -1
|
||||
#endif
|
||||
|
||||
struct filemon;
|
||||
struct filemon_key;
|
||||
struct filemon_state;
|
||||
|
||||
typedef struct filemon_state *filemon_syscall_t(struct filemon *,
|
||||
const struct filemon_key *, const struct ktr_syscall *);
|
||||
|
||||
static filemon_syscall_t filemon_sys_chdir;
|
||||
static filemon_syscall_t filemon_sys_execve;
|
||||
static filemon_syscall_t filemon_sys_exit;
|
||||
static filemon_syscall_t filemon_sys_fork;
|
||||
static filemon_syscall_t filemon_sys_link;
|
||||
static filemon_syscall_t filemon_sys_open;
|
||||
static filemon_syscall_t filemon_sys_openat;
|
||||
static filemon_syscall_t filemon_sys_symlink;
|
||||
static filemon_syscall_t filemon_sys_unlink;
|
||||
static filemon_syscall_t filemon_sys_rename;
|
||||
|
||||
static filemon_syscall_t *const filemon_syscalls[] = {
|
||||
[SYS_chdir] = &filemon_sys_chdir,
|
||||
[SYS_execve] = &filemon_sys_execve,
|
||||
[SYS_exit] = &filemon_sys_exit,
|
||||
[SYS_fork] = &filemon_sys_fork,
|
||||
[SYS_link] = &filemon_sys_link,
|
||||
[SYS_open] = &filemon_sys_open,
|
||||
[SYS_openat] = &filemon_sys_openat,
|
||||
[SYS_symlink] = &filemon_sys_symlink,
|
||||
[SYS_unlink] = &filemon_sys_unlink,
|
||||
[SYS_rename] = &filemon_sys_rename,
|
||||
};
|
||||
|
||||
struct filemon {
|
||||
int ktrfd; /* kernel writes ktrace events here */
|
||||
FILE *in; /* we read ktrace events from here */
|
||||
FILE *out; /* we write filemon events to here */
|
||||
rb_tree_t active;
|
||||
pid_t child;
|
||||
|
||||
/* I/O state machine. */
|
||||
enum {
|
||||
FILEMON_START = 0,
|
||||
FILEMON_HEADER,
|
||||
FILEMON_PAYLOAD,
|
||||
FILEMON_ERROR,
|
||||
} state;
|
||||
unsigned char *p;
|
||||
size_t resid;
|
||||
|
||||
/* I/O buffer. */
|
||||
struct ktr_header hdr;
|
||||
union {
|
||||
struct ktr_syscall syscall;
|
||||
struct ktr_sysret sysret;
|
||||
char namei[PATH_MAX];
|
||||
unsigned char buf[4096];
|
||||
} payload;
|
||||
};
|
||||
|
||||
struct filemon_state {
|
||||
struct filemon_key {
|
||||
pid_t pid;
|
||||
lwpid_t lid;
|
||||
} key;
|
||||
struct rb_node node;
|
||||
int syscode;
|
||||
void (*show)(struct filemon *, const struct filemon_state *,
|
||||
const struct ktr_sysret *);
|
||||
unsigned i;
|
||||
unsigned npath;
|
||||
char *path[/*npath*/];
|
||||
};
|
||||
|
||||
static int
|
||||
compare_filemon_states(void *cookie, const void *na, const void *nb)
|
||||
{
|
||||
const struct filemon_state *Sa = na;
|
||||
const struct filemon_state *Sb = nb;
|
||||
|
||||
if (Sa->key.pid < Sb->key.pid)
|
||||
return -1;
|
||||
if (Sa->key.pid > Sb->key.pid)
|
||||
return +1;
|
||||
if (Sa->key.lid < Sb->key.lid)
|
||||
return -1;
|
||||
if (Sa->key.lid > Sb->key.lid)
|
||||
return +1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
compare_filemon_key(void *cookie, const void *n, const void *k)
|
||||
{
|
||||
const struct filemon_state *S = n;
|
||||
const struct filemon_key *key = k;
|
||||
|
||||
if (S->key.pid < key->pid)
|
||||
return -1;
|
||||
if (S->key.pid > key->pid)
|
||||
return +1;
|
||||
if (S->key.lid < key->lid)
|
||||
return -1;
|
||||
if (S->key.lid > key->lid)
|
||||
return +1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const rb_tree_ops_t filemon_rb_ops = {
|
||||
.rbto_compare_nodes = &compare_filemon_states,
|
||||
.rbto_compare_key = &compare_filemon_key,
|
||||
.rbto_node_offset = offsetof(struct filemon_state, node),
|
||||
.rbto_context = NULL,
|
||||
};
|
||||
|
||||
/*
|
||||
* filemon_path()
|
||||
*
|
||||
* Return a pointer to a constant string denoting the `path' of
|
||||
* the filemon.
|
||||
*/
|
||||
const char *
|
||||
filemon_path(void)
|
||||
{
|
||||
|
||||
return "ktrace";
|
||||
}
|
||||
|
||||
/*
|
||||
* filemon_open()
|
||||
*
|
||||
* Allocate a filemon descriptor. Returns NULL and sets errno on
|
||||
* failure.
|
||||
*/
|
||||
struct filemon *
|
||||
filemon_open(void)
|
||||
{
|
||||
struct filemon *F;
|
||||
int ktrpipe[2];
|
||||
int error;
|
||||
|
||||
/* Allocate and zero a struct filemon object. */
|
||||
F = calloc(1, sizeof(*F));
|
||||
if (F == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Create a pipe for ktrace events. */
|
||||
if (pipe2(ktrpipe, O_CLOEXEC|O_NONBLOCK) == -1) {
|
||||
error = errno;
|
||||
goto fail0;
|
||||
}
|
||||
|
||||
/* Create a file stream for reading the ktrace events. */
|
||||
if ((F->in = fdopen(ktrpipe[0], "r")) == NULL) {
|
||||
error = errno;
|
||||
goto fail1;
|
||||
}
|
||||
ktrpipe[0] = -1; /* claimed by fdopen */
|
||||
|
||||
/*
|
||||
* Set the fd for writing ktrace events and initialize the
|
||||
* rbtree. The rest can be safely initialized to zero.
|
||||
*/
|
||||
F->ktrfd = ktrpipe[1];
|
||||
rb_tree_init(&F->active, &filemon_rb_ops);
|
||||
|
||||
/* Success! */
|
||||
return F;
|
||||
|
||||
fail2: __unused
|
||||
(void)fclose(F->in);
|
||||
fail1: (void)close(ktrpipe[0]);
|
||||
(void)close(ktrpipe[1]);
|
||||
fail0: free(F);
|
||||
errno = error;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* filemon_closefd(F)
|
||||
*
|
||||
* Internal subroutine to try to flush and close the output file.
|
||||
* If F is not open for output, do nothing. Never leaves F open
|
||||
* for output even on failure. Returns 0 on success; sets errno
|
||||
* and return -1 on failure.
|
||||
*/
|
||||
static int
|
||||
filemon_closefd(struct filemon *F)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
/* If we're not open, nothing to do. */
|
||||
if (F->out == NULL)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Flush it, close it, and null it unconditionally, but be
|
||||
* careful to return the earliest error in errno.
|
||||
*/
|
||||
if (fflush(F->out) == EOF && error == 0)
|
||||
error = errno;
|
||||
if (fclose(F->out) == EOF && error == 0)
|
||||
error = errno;
|
||||
F->out = NULL;
|
||||
|
||||
/* Set errno and return -1 if anything went wrong. */
|
||||
if (error) {
|
||||
errno = error;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Success! */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* filemon_setfd(F, fd)
|
||||
*
|
||||
* Cause filemon activity on F to be sent to fd. Claims ownership
|
||||
* of fd; caller should not use fd afterward, and any duplicates
|
||||
* of fd may see their file positions changed.
|
||||
*/
|
||||
int
|
||||
filemon_setfd(struct filemon *F, int fd)
|
||||
{
|
||||
|
||||
/*
|
||||
* Close an existing output file if done. Fail now if there's
|
||||
* an error closing.
|
||||
*/
|
||||
if ((filemon_closefd(F)) == -1)
|
||||
return -1;
|
||||
assert(F->out == NULL);
|
||||
|
||||
/* Open a file stream and claim ownership of the fd. */
|
||||
if ((F->out = fdopen(fd, "a")) == NULL)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* Print the opening output. Any failure will be deferred
|
||||
* until closing. For hysterical raisins, we show the parent
|
||||
* pid, not the child pid.
|
||||
*/
|
||||
fprintf(F->out, "# filemon version 4\n");
|
||||
fprintf(F->out, "# Target pid %jd\n", (intmax_t)getpid());
|
||||
fprintf(F->out, "V 4\n");
|
||||
|
||||
/* Success! */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* filemon_setpid_parent(F, pid)
|
||||
*
|
||||
* Set the traced pid, from the parent. Never fails.
|
||||
*/
|
||||
void
|
||||
filemon_setpid_parent(struct filemon *F, pid_t pid)
|
||||
{
|
||||
|
||||
F->child = pid;
|
||||
}
|
||||
|
||||
/*
|
||||
* filemon_setpid_child(F, pid)
|
||||
*
|
||||
* Set the traced pid, from the child. Returns 0 on success; sets
|
||||
* errno and returns -1 on failure.
|
||||
*/
|
||||
int
|
||||
filemon_setpid_child(const struct filemon *F, pid_t pid)
|
||||
{
|
||||
int ops, trpoints;
|
||||
|
||||
ops = KTROP_SET|KTRFLAG_DESCEND;
|
||||
trpoints = KTRFACv2;
|
||||
trpoints |= KTRFAC_SYSCALL|KTRFAC_NAMEI|KTRFAC_SYSRET;
|
||||
trpoints |= KTRFAC_INHERIT;
|
||||
if (fktrace(F->ktrfd, ops, trpoints, pid) == -1)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* filemon_close(F)
|
||||
*
|
||||
* Close F for output if necessary, and free a filemon descriptor.
|
||||
* Returns 0 on success; sets errno and returns -1 on failure, but
|
||||
* frees the filemon descriptor either way;
|
||||
*/
|
||||
int
|
||||
filemon_close(struct filemon *F)
|
||||
{
|
||||
struct filemon_state *S;
|
||||
int error = 0;
|
||||
|
||||
/* Close for output. */
|
||||
if (filemon_closefd(F) == -1 && error == 0)
|
||||
error = errno;
|
||||
|
||||
/* Close the ktrace pipe. */
|
||||
if (fclose(F->in) == EOF && error == 0)
|
||||
error = errno;
|
||||
if (close(F->ktrfd) == -1 && error == 0)
|
||||
error = errno;
|
||||
|
||||
/* Free any active records. */
|
||||
while ((S = RB_TREE_MIN(&F->active)) != NULL) {
|
||||
rb_tree_remove_node(&F->active, S);
|
||||
free(S);
|
||||
}
|
||||
|
||||
/* Free the filemon descriptor. */
|
||||
free(F);
|
||||
|
||||
/* Set errno and return -1 if anything went wrong. */
|
||||
if (error) {
|
||||
errno = error;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Success! */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* filemon_readfd(F)
|
||||
*
|
||||
* Returns a file descriptor which will select/poll ready for read
|
||||
* when there are filemon events to be processed by
|
||||
* filemon_process, or -1 if anything has gone wrong.
|
||||
*/
|
||||
int
|
||||
filemon_readfd(const struct filemon *F)
|
||||
{
|
||||
|
||||
if (F->state == FILEMON_ERROR)
|
||||
return -1;
|
||||
return fileno(F->in);
|
||||
}
|
||||
|
||||
/*
|
||||
* filemon_dispatch(F)
|
||||
*
|
||||
* Internal subroutine to dispatch a filemon ktrace event.
|
||||
* Silently ignore events that we don't recognize.
|
||||
*/
|
||||
static void
|
||||
filemon_dispatch(struct filemon *F)
|
||||
{
|
||||
const struct filemon_key key = {
|
||||
.pid = F->hdr.ktr_pid,
|
||||
.lid = F->hdr.ktr_lid,
|
||||
};
|
||||
struct filemon_state *S;
|
||||
|
||||
switch (F->hdr.ktr_type) {
|
||||
case KTR_SYSCALL: {
|
||||
struct ktr_syscall *call = &F->payload.syscall;
|
||||
struct filemon_state *S1;
|
||||
|
||||
/* Validate the syscall code. */
|
||||
if (call->ktr_code < 0 ||
|
||||
(size_t)call->ktr_code >= __arraycount(filemon_syscalls) ||
|
||||
filemon_syscalls[call->ktr_code] == NULL)
|
||||
break;
|
||||
|
||||
/*
|
||||
* Invoke the syscall-specific logic to create a new
|
||||
* active state.
|
||||
*/
|
||||
S = (*filemon_syscalls[call->ktr_code])(F, &key, call);
|
||||
if (S == NULL)
|
||||
break;
|
||||
|
||||
/*
|
||||
* Insert the active state, or ignore it if there
|
||||
* already is one.
|
||||
*
|
||||
* Collisions shouldn't happen because the states are
|
||||
* keyed by <pid,lid>, in which syscalls should happen
|
||||
* sequentially in CALL/RET pairs, but let's be
|
||||
* defensive.
|
||||
*/
|
||||
S1 = rb_tree_insert_node(&F->active, S);
|
||||
if (S1 != S) {
|
||||
/* XXX Which one to drop? */
|
||||
free(S);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case KTR_NAMEI:
|
||||
/* Find an active syscall state, or drop it. */
|
||||
S = rb_tree_find_node(&F->active, &key);
|
||||
if (S == NULL)
|
||||
break;
|
||||
/* Find the position of the next path, or drop it. */
|
||||
if (S->i >= S->npath)
|
||||
break;
|
||||
/* Record the path. */
|
||||
S->path[S->i++] = strndup(F->payload.namei,
|
||||
sizeof F->payload.namei);
|
||||
break;
|
||||
case KTR_SYSRET: {
|
||||
struct ktr_sysret *ret = &F->payload.sysret;
|
||||
unsigned i;
|
||||
|
||||
/* Find and remove an active syscall state, or drop it. */
|
||||
S = rb_tree_find_node(&F->active, &key);
|
||||
if (S == NULL)
|
||||
break;
|
||||
rb_tree_remove_node(&F->active, S);
|
||||
|
||||
/*
|
||||
* If the active syscall state matches this return,
|
||||
* invoke the syscall-specific logic to show a filemon
|
||||
* event.
|
||||
*/
|
||||
/* XXX What to do if syscall code doesn't match? */
|
||||
if (S->i == S->npath && S->syscode == ret->ktr_code)
|
||||
(*S->show)(F, S, ret);
|
||||
|
||||
/* Free the state now that it is no longer active. */
|
||||
for (i = 0; i < S->i; i++)
|
||||
free(S->path[i]);
|
||||
free(S);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
/* Ignore all other ktrace events. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* filemon_process(F)
|
||||
*
|
||||
* Process all pending events after filemon_readfd(F) has
|
||||
* selected/polled ready for read.
|
||||
*
|
||||
* Returns -1 on failure, 0 on end of events, and anything else if
|
||||
* there may be more events.
|
||||
*
|
||||
* XXX What about fairness to other activities in the event loop?
|
||||
* If we stop while there's events buffered in F->in, then select
|
||||
* or poll may not return ready even though there's work queued up
|
||||
* in the buffer of F->in, but if we don't stop then ktrace events
|
||||
* may overwhelm all other activity in the event loop.
|
||||
*/
|
||||
int
|
||||
filemon_process(struct filemon *F)
|
||||
{
|
||||
size_t nread;
|
||||
|
||||
top: /* If the child has exited, nothing to do. */
|
||||
/* XXX What if one thread calls exit while another is running? */
|
||||
if (F->child == 0)
|
||||
return 0;
|
||||
|
||||
/* If we're waiting for input, read some. */
|
||||
if (F->resid) {
|
||||
nread = fread(F->p, 1, F->resid, F->in);
|
||||
if (nread == 0) {
|
||||
if (feof(F->in))
|
||||
return 0;
|
||||
assert(ferror(F->in));
|
||||
/*
|
||||
* If interrupted or would block, there may be
|
||||
* more events. Otherwise fail.
|
||||
*/
|
||||
if (errno == EAGAIN || errno == EINTR)
|
||||
return 1;
|
||||
F->state = FILEMON_ERROR;
|
||||
F->p = NULL;
|
||||
F->resid = 0;
|
||||
return -1;
|
||||
}
|
||||
assert(nread <= F->resid);
|
||||
F->p += nread;
|
||||
F->resid -= nread;
|
||||
if (F->resid) /* may be more events */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Process a state transition now that we've read a buffer. */
|
||||
switch (F->state) {
|
||||
case FILEMON_START: /* just started filemon; read header next */
|
||||
F->state = FILEMON_HEADER;
|
||||
F->p = (void *)&F->hdr;
|
||||
F->resid = sizeof F->hdr;
|
||||
goto top;
|
||||
case FILEMON_HEADER: /* read header */
|
||||
/* Sanity-check ktrace header; then read payload. */
|
||||
if (F->hdr.ktr_len < 0 ||
|
||||
(size_t)F->hdr.ktr_len > sizeof F->payload) {
|
||||
F->state = FILEMON_ERROR;
|
||||
F->p = NULL;
|
||||
F->resid = 0;
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
F->state = FILEMON_PAYLOAD;
|
||||
F->p = (void *)&F->payload;
|
||||
F->resid = (size_t)F->hdr.ktr_len;
|
||||
goto top;
|
||||
case FILEMON_PAYLOAD: /* read header and payload */
|
||||
/* Dispatch ktrace event; then read next header. */
|
||||
filemon_dispatch(F);
|
||||
F->state = FILEMON_HEADER;
|
||||
F->p = (void *)&F->hdr;
|
||||
F->resid = sizeof F->hdr;
|
||||
goto top;
|
||||
default: /* paranoia */
|
||||
F->state = FILEMON_ERROR;
|
||||
/*FALLTHROUGH*/
|
||||
case FILEMON_ERROR: /* persistent error indicator */
|
||||
F->p = NULL;
|
||||
F->resid = 0;
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static struct filemon_state *
|
||||
syscall_enter(struct filemon *F,
|
||||
const struct filemon_key *key, const struct ktr_syscall *call,
|
||||
unsigned npath,
|
||||
void (*show)(struct filemon *, const struct filemon_state *,
|
||||
const struct ktr_sysret *))
|
||||
{
|
||||
struct filemon_state *S;
|
||||
unsigned i;
|
||||
|
||||
S = calloc(1, offsetof(struct filemon_state, path[npath]));
|
||||
if (S == NULL)
|
||||
return NULL;
|
||||
S->key = *key;
|
||||
S->show = show;
|
||||
S->syscode = call->ktr_code;
|
||||
S->i = 0;
|
||||
S->npath = npath;
|
||||
for (i = 0; i < npath; i++)
|
||||
S->path[i] = NULL; /* paranoia */
|
||||
|
||||
return S;
|
||||
}
|
||||
|
||||
static void
|
||||
show_paths(struct filemon *F, const struct filemon_state *S,
|
||||
const struct ktr_sysret *ret, const char *prefix)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
/* Caller must ensure all paths have been specified. */
|
||||
assert(S->i == S->npath);
|
||||
|
||||
/*
|
||||
* Ignore it if it failed or yielded EJUSTRETURN (-2), or if
|
||||
* we're not producing output.
|
||||
*/
|
||||
if (ret->ktr_error && ret->ktr_error != -2)
|
||||
return;
|
||||
if (F->out == NULL)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Print the prefix, pid, and paths -- with the paths quoted if
|
||||
* there's more than one.
|
||||
*/
|
||||
fprintf(F->out, "%s %jd", prefix, (intmax_t)S->key.pid);
|
||||
for (i = 0; i < S->npath; i++) {
|
||||
const char *q = S->npath > 1 ? "'" : "";
|
||||
fprintf(F->out, " %s%s%s", q, S->path[i], q);
|
||||
}
|
||||
fprintf(F->out, "\n");
|
||||
}
|
||||
|
||||
static void
|
||||
show_retval(struct filemon *F, const struct filemon_state *S,
|
||||
const struct ktr_sysret *ret, const char *prefix)
|
||||
{
|
||||
|
||||
/*
|
||||
* Ignore it if it failed or yielded EJUSTRETURN (-2), or if
|
||||
* we're not producing output.
|
||||
*/
|
||||
if (ret->ktr_error && ret->ktr_error != -2)
|
||||
return;
|
||||
if (F->out == NULL)
|
||||
return;
|
||||
|
||||
fprintf(F->out, "%s %jd %jd\n", prefix, (intmax_t)S->key.pid,
|
||||
(intmax_t)ret->ktr_retval);
|
||||
}
|
||||
|
||||
static void
|
||||
show_chdir(struct filemon *F, const struct filemon_state *S,
|
||||
const struct ktr_sysret *ret)
|
||||
{
|
||||
show_paths(F, S, ret, "C");
|
||||
}
|
||||
|
||||
static void
|
||||
show_execve(struct filemon *F, const struct filemon_state *S,
|
||||
const struct ktr_sysret *ret)
|
||||
{
|
||||
return show_paths(F, S, ret, "E");
|
||||
}
|
||||
|
||||
static void
|
||||
show_fork(struct filemon *F, const struct filemon_state *S,
|
||||
const struct ktr_sysret *ret)
|
||||
{
|
||||
show_retval(F, S, ret, "F");
|
||||
}
|
||||
|
||||
static void
|
||||
show_link(struct filemon *F, const struct filemon_state *S,
|
||||
const struct ktr_sysret *ret)
|
||||
{
|
||||
show_paths(F, S, ret, "L"); /* XXX same as symlink */
|
||||
}
|
||||
|
||||
static void
|
||||
show_open_read(struct filemon *F, const struct filemon_state *S,
|
||||
const struct ktr_sysret *ret)
|
||||
{
|
||||
show_paths(F, S, ret, "R");
|
||||
}
|
||||
|
||||
static void
|
||||
show_open_write(struct filemon *F, const struct filemon_state *S,
|
||||
const struct ktr_sysret *ret)
|
||||
{
|
||||
show_paths(F, S, ret, "W");
|
||||
}
|
||||
|
||||
static void
|
||||
show_open_readwrite(struct filemon *F, const struct filemon_state *S,
|
||||
const struct ktr_sysret *ret)
|
||||
{
|
||||
show_paths(F, S, ret, "R");
|
||||
show_paths(F, S, ret, "W");
|
||||
}
|
||||
|
||||
static void
|
||||
show_openat_read(struct filemon *F, const struct filemon_state *S,
|
||||
const struct ktr_sysret *ret)
|
||||
{
|
||||
if (S->path[0][0] != '/')
|
||||
show_paths(F, S, ret, "A");
|
||||
show_paths(F, S, ret, "R");
|
||||
}
|
||||
|
||||
static void
|
||||
show_openat_write(struct filemon *F, const struct filemon_state *S,
|
||||
const struct ktr_sysret *ret)
|
||||
{
|
||||
if (S->path[0][0] != '/')
|
||||
show_paths(F, S, ret, "A");
|
||||
show_paths(F, S, ret, "W");
|
||||
}
|
||||
|
||||
static void
|
||||
show_openat_readwrite(struct filemon *F, const struct filemon_state *S,
|
||||
const struct ktr_sysret *ret)
|
||||
{
|
||||
if (S->path[0][0] != '/')
|
||||
show_paths(F, S, ret, "A");
|
||||
show_paths(F, S, ret, "R");
|
||||
show_paths(F, S, ret, "W");
|
||||
}
|
||||
|
||||
static void
|
||||
show_symlink(struct filemon *F, const struct filemon_state *S,
|
||||
const struct ktr_sysret *ret)
|
||||
{
|
||||
show_paths(F, S, ret, "L"); /* XXX same as link */
|
||||
}
|
||||
|
||||
static void
|
||||
show_unlink(struct filemon *F, const struct filemon_state *S,
|
||||
const struct ktr_sysret *ret)
|
||||
{
|
||||
show_paths(F, S, ret, "D");
|
||||
}
|
||||
|
||||
static void
|
||||
show_rename(struct filemon *F, const struct filemon_state *S,
|
||||
const struct ktr_sysret *ret)
|
||||
{
|
||||
show_paths(F, S, ret, "M");
|
||||
}
|
||||
|
||||
static struct filemon_state *
|
||||
filemon_sys_chdir(struct filemon *F, const struct filemon_key *key,
|
||||
const struct ktr_syscall *call)
|
||||
{
|
||||
return syscall_enter(F, key, call, 1, &show_chdir);
|
||||
}
|
||||
|
||||
static struct filemon_state *
|
||||
filemon_sys_execve(struct filemon *F, const struct filemon_key *key,
|
||||
const struct ktr_syscall *call)
|
||||
{
|
||||
return syscall_enter(F, key, call, 1, &show_execve);
|
||||
}
|
||||
|
||||
static struct filemon_state *
|
||||
filemon_sys_exit(struct filemon *F, const struct filemon_key *key,
|
||||
const struct ktr_syscall *call)
|
||||
{
|
||||
const register_t *args = (const void *)&call[1];
|
||||
int status = args[0];
|
||||
|
||||
if (F->out) {
|
||||
fprintf(F->out, "X %jd %d\n", (intmax_t)key->pid, status);
|
||||
if (key->pid == F->child) {
|
||||
fprintf(F->out, "# Bye bye\n");
|
||||
F->child = 0;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct filemon_state *
|
||||
filemon_sys_fork(struct filemon *F, const struct filemon_key *key,
|
||||
const struct ktr_syscall *call)
|
||||
{
|
||||
return syscall_enter(F, key, call, 0, &show_fork);
|
||||
}
|
||||
|
||||
static struct filemon_state *
|
||||
filemon_sys_link(struct filemon *F, const struct filemon_key *key,
|
||||
const struct ktr_syscall *call)
|
||||
{
|
||||
return syscall_enter(F, key, call, 2, &show_link);
|
||||
}
|
||||
|
||||
static struct filemon_state *
|
||||
filemon_sys_open(struct filemon *F, const struct filemon_key *key,
|
||||
const struct ktr_syscall *call)
|
||||
{
|
||||
const register_t *args = (const void *)&call[1];
|
||||
int flags;
|
||||
|
||||
if (call->ktr_argsize < 2)
|
||||
return NULL;
|
||||
flags = args[1];
|
||||
|
||||
if ((flags & O_RDWR) == O_RDWR)
|
||||
return syscall_enter(F, key, call, 1, &show_open_readwrite);
|
||||
else if ((flags & O_WRONLY) == O_WRONLY)
|
||||
return syscall_enter(F, key, call, 1, &show_open_write);
|
||||
else if ((flags & O_RDONLY) == O_RDONLY)
|
||||
return syscall_enter(F, key, call, 1, &show_open_read);
|
||||
else
|
||||
return NULL; /* XXX Do we care if no read or write? */
|
||||
}
|
||||
|
||||
static struct filemon_state *
|
||||
filemon_sys_openat(struct filemon *F, const struct filemon_key *key,
|
||||
const struct ktr_syscall *call)
|
||||
{
|
||||
const register_t *args = (const void *)&call[1];
|
||||
int flags, fd;
|
||||
|
||||
if (call->ktr_argsize < 3)
|
||||
return NULL;
|
||||
fd = args[0];
|
||||
flags = args[2];
|
||||
|
||||
if (fd == AT_CWD) {
|
||||
if ((flags & O_RDWR) == O_RDWR)
|
||||
return syscall_enter(F, key, call, 1,
|
||||
&show_open_readwrite);
|
||||
else if ((flags & O_WRONLY) == O_WRONLY)
|
||||
return syscall_enter(F, key, call, 1,
|
||||
&show_open_write);
|
||||
else if ((flags & O_RDONLY) == O_RDONLY)
|
||||
return syscall_enter(F, key, call, 1, &show_open_read);
|
||||
else
|
||||
return NULL;
|
||||
} else {
|
||||
if ((flags & O_RDWR) == O_RDWR)
|
||||
return syscall_enter(F, key, call, 1,
|
||||
&show_openat_readwrite);
|
||||
else if ((flags & O_WRONLY) == O_WRONLY)
|
||||
return syscall_enter(F, key, call, 1,
|
||||
&show_openat_write);
|
||||
else if ((flags & O_RDONLY) == O_RDONLY)
|
||||
return syscall_enter(F, key, call, 1,
|
||||
&show_openat_read);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static struct filemon_state *
|
||||
filemon_sys_symlink(struct filemon *F, const struct filemon_key *key,
|
||||
const struct ktr_syscall *call)
|
||||
{
|
||||
return syscall_enter(F, key, call, 2, &show_symlink);
|
||||
}
|
||||
|
||||
static struct filemon_state *
|
||||
filemon_sys_unlink(struct filemon *F, const struct filemon_key *key,
|
||||
const struct ktr_syscall *call)
|
||||
{
|
||||
return syscall_enter(F, key, call, 1, &show_unlink);
|
||||
}
|
||||
|
||||
static struct filemon_state *
|
||||
filemon_sys_rename(struct filemon *F, const struct filemon_key *key,
|
||||
const struct ktr_syscall *call)
|
||||
{
|
||||
return syscall_enter(F, key, call, 2, &show_rename);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: job.c,v 1.195 2018/05/13 22:13:28 sjg Exp $ */
|
||||
/* $NetBSD: job.c,v 1.197 2020/02/06 01:13:19 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: job.c,v 1.195 2018/05/13 22:13:28 sjg Exp $";
|
||||
static char rcsid[] = "$NetBSD: job.c,v 1.197 2020/02/06 01:13:19 sjg 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.195 2018/05/13 22:13:28 sjg Exp $");
|
||||
__RCSID("$NetBSD: job.c,v 1.197 2020/02/06 01:13:19 sjg Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
@ -358,6 +358,8 @@ static Job childExitJob; /* child exit pseudo-job */
|
||||
#define CHILD_EXIT "."
|
||||
#define DO_JOB_RESUME "R"
|
||||
|
||||
static const int npseudojobs = 2; /* number of pseudo-jobs */
|
||||
|
||||
#define TARG_FMT "%s %s ---\n" /* Default format */
|
||||
#define MESSAGE(fp, gn) \
|
||||
if (maxJobs != 1 && targPrefix && *targPrefix) \
|
||||
@ -389,6 +391,16 @@ static void JobSigReset(void);
|
||||
#endif
|
||||
const char *malloc_options= MALLOC_OPTIONS;
|
||||
|
||||
static unsigned
|
||||
nfds_per_job(void)
|
||||
{
|
||||
#if defined(USE_FILEMON) && !defined(USE_FILEMON_DEV)
|
||||
if (useMeta)
|
||||
return 2;
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
job_table_dump(const char *where)
|
||||
{
|
||||
@ -1475,6 +1487,12 @@ JobExec(Job *job, char **argv)
|
||||
|
||||
Trace_Log(JOBSTART, job);
|
||||
|
||||
#ifdef USE_META
|
||||
if (useMeta) {
|
||||
meta_job_parent(job, cpid);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set the current position in the buffer to the beginning
|
||||
* and mark another stream to watch in the outputs mask
|
||||
@ -2157,12 +2175,24 @@ Job_CatchOutput(void)
|
||||
if (nready == 0)
|
||||
return;
|
||||
|
||||
for (i = 2; i < nfds; i++) {
|
||||
for (i = npseudojobs*nfds_per_job(); i < nfds; i++) {
|
||||
if (!fds[i].revents)
|
||||
continue;
|
||||
job = jobfds[i];
|
||||
if (job->job_state == JOB_ST_RUNNING)
|
||||
JobDoOutput(job, FALSE);
|
||||
#if defined(USE_FILEMON) && !defined(USE_FILEMON_DEV)
|
||||
/*
|
||||
* With meta mode, we may have activity on the job's filemon
|
||||
* descriptor too, which at the moment is any pollfd other than
|
||||
* job->inPollfd.
|
||||
*/
|
||||
if (useMeta && job->inPollfd != &fds[i]) {
|
||||
if (meta_job_event(job) <= 0) {
|
||||
fds[i].events = 0; /* never mind */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (--nready == 0)
|
||||
return;
|
||||
}
|
||||
@ -2313,9 +2343,11 @@ Job_Init(void)
|
||||
|
||||
JobCreatePipe(&childExitJob, 3);
|
||||
|
||||
/* We can only need to wait for tokens, children and output from each job */
|
||||
fds = bmake_malloc(sizeof (*fds) * (2 + maxJobs));
|
||||
jobfds = bmake_malloc(sizeof (*jobfds) * (2 + maxJobs));
|
||||
/* Preallocate enough for the maximum number of jobs. */
|
||||
fds = bmake_malloc(sizeof(*fds) *
|
||||
(npseudojobs + maxJobs) * nfds_per_job());
|
||||
jobfds = bmake_malloc(sizeof(*jobfds) *
|
||||
(npseudojobs + maxJobs) * nfds_per_job());
|
||||
|
||||
/* These are permanent entries and take slots 0 and 1 */
|
||||
watchfd(&tokenWaitJob);
|
||||
@ -2834,6 +2866,14 @@ watchfd(Job *job)
|
||||
jobfds[nfds] = job;
|
||||
job->inPollfd = &fds[nfds];
|
||||
nfds++;
|
||||
#if defined(USE_FILEMON) && !defined(USE_FILEMON_DEV)
|
||||
if (useMeta) {
|
||||
fds[nfds].fd = meta_job_fd(job);
|
||||
fds[nfds].events = fds[nfds].fd == -1 ? 0 : POLLIN;
|
||||
jobfds[nfds] = job;
|
||||
nfds++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2844,6 +2884,18 @@ clearfd(Job *job)
|
||||
Punt("Unwatching unwatched job");
|
||||
i = job->inPollfd - fds;
|
||||
nfds--;
|
||||
#if defined(USE_FILEMON) && !defined(USE_FILEMON_DEV)
|
||||
if (useMeta) {
|
||||
/*
|
||||
* Sanity check: there should be two fds per job, so the job's
|
||||
* pollfd number should be even.
|
||||
*/
|
||||
assert(nfds_per_job() == 2);
|
||||
if (i % 2)
|
||||
Punt("odd-numbered fd with meta");
|
||||
nfds--;
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* Move last job in table into hole made by dead job.
|
||||
*/
|
||||
@ -2851,6 +2903,12 @@ clearfd(Job *job)
|
||||
fds[i] = fds[nfds];
|
||||
jobfds[i] = jobfds[nfds];
|
||||
jobfds[i]->inPollfd = &fds[i];
|
||||
#if defined(USE_FILEMON) && !defined(USE_FILEMON_DEV)
|
||||
if (useMeta) {
|
||||
fds[i + 1] = fds[nfds + 1];
|
||||
jobfds[i + 1] = jobfds[nfds + 1];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
job->inPollfd = NULL;
|
||||
}
|
||||
|
@ -23,6 +23,10 @@ MDEFS="-DMAKE_VERSION=\"$MAKE_VERSION\" \
|
||||
LDFLAGS="@LDFLAGS@"
|
||||
LIBS="@LIBS@"
|
||||
|
||||
toUpper() {
|
||||
${TR:-tr} abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
|
||||
}
|
||||
|
||||
do_compile2() {
|
||||
obj="$1"; shift
|
||||
src="$1"; shift
|
||||
@ -32,7 +36,10 @@ do_compile2() {
|
||||
|
||||
do_compile() {
|
||||
obj="$1"; shift
|
||||
src=`basename "$obj" .o`.c
|
||||
case "$1" in
|
||||
*.c) src=$1; shift;;
|
||||
*) src=`basename "$obj" .o`.c;;
|
||||
esac
|
||||
|
||||
for d in "$srcdir" "$srcdir/lst.lib"
|
||||
do
|
||||
@ -52,7 +59,7 @@ do_link() {
|
||||
}
|
||||
|
||||
BASE_OBJECTS="arch.o buf.o compat.o cond.o dir.o for.o getopt hash.o \
|
||||
job.o make.o make_malloc.o metachar.o parse.o sigcompat.o str.o strlist.o \
|
||||
make.o make_malloc.o metachar.o parse.o sigcompat.o str.o strlist.o \
|
||||
suff.o targ.o trace.o var.o util.o"
|
||||
|
||||
LST_OBJECTS="lstAppend.o lstDupl.o lstInit.o lstOpen.o \
|
||||
@ -73,12 +80,22 @@ done
|
||||
|
||||
case "@use_meta@" in
|
||||
yes)
|
||||
case "@filemon_h@" in
|
||||
*/filemon.h) FDEFS="-DHAVE_FILEMON_H -I`dirname @filemon_h@`";;
|
||||
case "@use_filemon@" in
|
||||
no) MDEFS=;;
|
||||
*)
|
||||
MDEFS="-DUSE_FILEMON -DUSE_FILEMON_`echo @use_filemon@ | toUpper`"
|
||||
case "@use_filemon@,@filemon_h@" in
|
||||
dev,*/filemon.h) FDEFS="-DHAVE_FILEMON_H -I`dirname @filemon_h@`";;
|
||||
*) FDEFS=;;
|
||||
esac
|
||||
do_compile filemon_@use_filemon@.o filemon/filemon_@use_filemon@.c ${FDEFS}
|
||||
BASE_OBJECTS="filemon_@use_filemon@.o $BASE_OBJECTS"
|
||||
;;
|
||||
esac
|
||||
do_compile meta.o ${FDEFS}
|
||||
BASE_OBJECTS="meta.o ${BASE_OBJECTS}"
|
||||
;;
|
||||
do_compile meta.o ${MDEFS}
|
||||
BASE_OBJECTS="meta.o ${BASE_OBJECTS}"
|
||||
;;
|
||||
esac
|
||||
do_compile job.o ${MDEFS}
|
||||
|
||||
do_link bmake main.o ${BASE_OBJECTS} ${LST_OBJECTS} ${LIB_OBJECTS}
|
||||
do_link bmake main.o job.o ${BASE_OBJECTS} ${LST_OBJECTS} ${LIB_OBJECTS}
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $NetBSD: make.1,v 1.273 2018/05/27 01:14:51 christos Exp $
|
||||
.\" $NetBSD: make.1,v 1.280 2020/04/27 20:03:08 christos 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 December 5, 2018
|
||||
.Dd April 27, 2020
|
||||
.Dt MAKE 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -272,7 +272,7 @@ that do not depend on the target whose creation caused the error.
|
||||
.It Fl m Ar directory
|
||||
Specify a directory in which to search for sys.mk and makefiles included
|
||||
via the
|
||||
.Ao Ar file Ac Ns -style
|
||||
.Li \&< Ns Ar file Ns Li \&> Ns -style
|
||||
include statement.
|
||||
The
|
||||
.Fl m
|
||||
@ -280,7 +280,7 @@ option can be used multiple times to form a search path.
|
||||
This path will override the default system include path: /usr/share/mk.
|
||||
Furthermore the system include path will be appended to the search path used
|
||||
for
|
||||
.Qo Ar file Qc Ns -style
|
||||
.Li \*q Ns Ar file Ns Li \*q Ns -style
|
||||
include statements (see the
|
||||
.Fl I
|
||||
option).
|
||||
@ -1440,6 +1440,29 @@ is the substring of
|
||||
.Ar old_string
|
||||
to be replaced in
|
||||
.Ar new_string .
|
||||
If only
|
||||
.Ar old_string
|
||||
contains the pattern matching character
|
||||
.Ar % ,
|
||||
and
|
||||
.Ar old_string
|
||||
matches, then the result is the
|
||||
.Ar new_string .
|
||||
If only the
|
||||
.Ar new_string
|
||||
contains the pattern matching character
|
||||
.Ar % ,
|
||||
then it is not treated specially and it is printed as a literal
|
||||
.Ar %
|
||||
on match.
|
||||
If there is more than one pattern matching character
|
||||
.Ar ( % )
|
||||
in either the
|
||||
.Ar new_string
|
||||
or
|
||||
.Ar old_string ,
|
||||
only the first instance is treated specially (as the pattern character);
|
||||
all subsequent instances are treated as regular characters
|
||||
.Pp
|
||||
Variable expansion occurs in the normal fashion inside both
|
||||
.Ar old_string
|
||||
@ -1634,9 +1657,9 @@ dot
|
||||
.Pq Ql \&.
|
||||
character.
|
||||
Files are included with either
|
||||
.Cm \&.include Aq Ar file
|
||||
.Cm \&.include \&< Ns Ar file Ns Cm \&>
|
||||
or
|
||||
.Cm \&.include Pf \*q Ar file Ns \*q .
|
||||
.Cm \&.include \&\*q Ns Ar file Ns Cm \&\*q .
|
||||
Variables between the angle brackets or double quotes are expanded
|
||||
to form the file name.
|
||||
If angle brackets are used, the included makefile is expected to be in
|
||||
@ -2416,9 +2439,9 @@ file).
|
||||
.Sh BUGS
|
||||
The
|
||||
.Nm
|
||||
syntax is difficult to parse without actually acting of the data.
|
||||
For instance finding the end of a variable use should involve scanning each
|
||||
the modifiers using the correct terminator for each field.
|
||||
syntax is difficult to parse without actually acting on the data.
|
||||
For instance, finding the end of a variable's use should involve scanning
|
||||
each of the modifiers, using the correct terminator for each field.
|
||||
In many places
|
||||
.Nm
|
||||
just counts {} and () in order to find the end of a variable expansion.
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: make.h,v 1.105 2020/03/30 02:41:06 sjg Exp $ */
|
||||
/* $NetBSD: make.h,v 1.107 2020/04/03 03:35:16 sjg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1993
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: meta.c,v 1.70 2018/02/13 19:37:30 sjg Exp $ */
|
||||
/* $NetBSD: meta.c,v 1.81 2020/04/03 03:32:28 sjg Exp $ */
|
||||
|
||||
/*
|
||||
* Implement 'meta' mode.
|
||||
@ -36,7 +36,6 @@
|
||||
# include "config.h"
|
||||
#endif
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#ifdef HAVE_LIBGEN_H
|
||||
#include <libgen.h>
|
||||
#elif !defined(HAVE_DIRNAME)
|
||||
@ -50,11 +49,8 @@ char * dirname(char *);
|
||||
#include "make.h"
|
||||
#include "job.h"
|
||||
|
||||
#ifdef HAVE_FILEMON_H
|
||||
# include <filemon.h>
|
||||
#endif
|
||||
#if !defined(USE_FILEMON) && defined(FILEMON_SET_FD)
|
||||
# define USE_FILEMON
|
||||
#ifdef USE_FILEMON
|
||||
#include "filemon/filemon.h"
|
||||
#endif
|
||||
|
||||
static BuildMon Mybm; /* for compat */
|
||||
@ -121,30 +117,24 @@ extern char **environ;
|
||||
* the benefits are more limited.
|
||||
*/
|
||||
#ifdef USE_FILEMON
|
||||
# ifndef _PATH_FILEMON
|
||||
# define _PATH_FILEMON "/dev/filemon"
|
||||
# endif
|
||||
|
||||
/*
|
||||
* Open the filemon device.
|
||||
*/
|
||||
static void
|
||||
filemon_open(BuildMon *pbm)
|
||||
meta_open_filemon(BuildMon *pbm)
|
||||
{
|
||||
int retry;
|
||||
int dupfd;
|
||||
|
||||
pbm->mon_fd = pbm->filemon_fd = -1;
|
||||
if (!useFilemon)
|
||||
pbm->mon_fd = -1;
|
||||
pbm->filemon = NULL;
|
||||
if (!useFilemon || !pbm->mfp)
|
||||
return;
|
||||
|
||||
for (retry = 5; retry >= 0; retry--) {
|
||||
if ((pbm->filemon_fd = open(_PATH_FILEMON, O_RDWR)) >= 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (pbm->filemon_fd < 0) {
|
||||
pbm->filemon = filemon_open();
|
||||
if (pbm->filemon == NULL) {
|
||||
useFilemon = FALSE;
|
||||
warn("Could not open %s", _PATH_FILEMON);
|
||||
warn("Could not open filemon %s", filemon_path());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -155,12 +145,15 @@ filemon_open(BuildMon *pbm)
|
||||
* We only care about the descriptor.
|
||||
*/
|
||||
pbm->mon_fd = mkTempFile("filemon.XXXXXX", NULL);
|
||||
if (ioctl(pbm->filemon_fd, FILEMON_SET_FD, &pbm->mon_fd) < 0) {
|
||||
if ((dupfd = dup(pbm->mon_fd)) == -1) {
|
||||
err(1, "Could not dup filemon output!");
|
||||
}
|
||||
(void)fcntl(dupfd, F_SETFD, FD_CLOEXEC);
|
||||
if (filemon_setfd(pbm->filemon, dupfd) == -1) {
|
||||
err(1, "Could not set filemon file descriptor!");
|
||||
}
|
||||
/* we don't need these once we exec */
|
||||
(void)fcntl(pbm->mon_fd, F_SETFD, FD_CLOEXEC);
|
||||
(void)fcntl(pbm->filemon_fd, F_SETFD, FD_CLOEXEC);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -473,7 +466,7 @@ meta_create(BuildMon *pbm, GNode *gn)
|
||||
const char *tname;
|
||||
char *fname;
|
||||
const char *cp;
|
||||
char *p[4]; /* >= possible uses */
|
||||
char *p[5]; /* >= possible uses */
|
||||
int i;
|
||||
|
||||
mf.fp = NULL;
|
||||
@ -528,7 +521,10 @@ meta_create(BuildMon *pbm, GNode *gn)
|
||||
|
||||
fprintf(mf.fp, "CWD %s\n", getcwd(buf, sizeof(buf)));
|
||||
fprintf(mf.fp, "TARGET %s\n", tname);
|
||||
|
||||
cp = Var_Value(".OODATE", gn, &p[i++]);
|
||||
if (cp && *cp) {
|
||||
fprintf(mf.fp, "OODATE %s\n", cp);
|
||||
}
|
||||
if (metaEnv) {
|
||||
for (ptr = environ; *ptr != NULL; ptr++)
|
||||
fprintf(mf.fp, "ENV %s\n", *ptr);
|
||||
@ -574,7 +570,7 @@ meta_init(void)
|
||||
{
|
||||
#ifdef USE_FILEMON
|
||||
/* this allows makefiles to test if we have filemon support */
|
||||
Var_Set(".MAKE.PATH_FILEMON", _PATH_FILEMON, VAR_GLOBAL, 0);
|
||||
Var_Set(".MAKE.PATH_FILEMON", filemon_path(), VAR_GLOBAL, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -684,9 +680,10 @@ meta_job_start(Job *job, GNode *gn)
|
||||
#endif
|
||||
#ifdef USE_FILEMON
|
||||
if (pbm->mfp != NULL && useFilemon) {
|
||||
filemon_open(pbm);
|
||||
meta_open_filemon(pbm);
|
||||
} else {
|
||||
pbm->mon_fd = pbm->filemon_fd = -1;
|
||||
pbm->mon_fd = -1;
|
||||
pbm->filemon = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -708,11 +705,11 @@ meta_job_child(Job *job)
|
||||
}
|
||||
if (pbm->mfp != NULL) {
|
||||
close(fileno(pbm->mfp));
|
||||
if (useFilemon) {
|
||||
if (useFilemon && pbm->filemon) {
|
||||
pid_t pid;
|
||||
|
||||
pid = getpid();
|
||||
if (ioctl(pbm->filemon_fd, FILEMON_SET_PID, &pid) < 0) {
|
||||
if (filemon_setpid_child(pbm->filemon, pid) == -1) {
|
||||
err(1, "Could not set filemon pid!");
|
||||
}
|
||||
}
|
||||
@ -720,6 +717,59 @@ meta_job_child(Job *job)
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
meta_job_parent(Job *job, pid_t pid)
|
||||
{
|
||||
#if defined(USE_FILEMON) && !defined(USE_FILEMON_DEV)
|
||||
BuildMon *pbm;
|
||||
|
||||
if (job != NULL) {
|
||||
pbm = &job->bm;
|
||||
} else {
|
||||
pbm = &Mybm;
|
||||
}
|
||||
if (useFilemon && pbm->filemon) {
|
||||
filemon_setpid_parent(pbm->filemon, pid);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
meta_job_fd(Job *job)
|
||||
{
|
||||
#if defined(USE_FILEMON) && !defined(USE_FILEMON_DEV)
|
||||
BuildMon *pbm;
|
||||
|
||||
if (job != NULL) {
|
||||
pbm = &job->bm;
|
||||
} else {
|
||||
pbm = &Mybm;
|
||||
}
|
||||
if (useFilemon && pbm->filemon) {
|
||||
return filemon_readfd(pbm->filemon);
|
||||
}
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
meta_job_event(Job *job)
|
||||
{
|
||||
#if defined(USE_FILEMON) && !defined(USE_FILEMON_DEV)
|
||||
BuildMon *pbm;
|
||||
|
||||
if (job != NULL) {
|
||||
pbm = &job->bm;
|
||||
} else {
|
||||
pbm = &Mybm;
|
||||
}
|
||||
if (useFilemon && pbm->filemon) {
|
||||
return filemon_process(pbm->filemon);
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
meta_job_error(Job *job, GNode *gn, int flags, int status)
|
||||
{
|
||||
@ -798,13 +848,16 @@ meta_cmd_finish(void *pbmp)
|
||||
pbm = &Mybm;
|
||||
|
||||
#ifdef USE_FILEMON
|
||||
if (pbm->filemon_fd >= 0) {
|
||||
if (close(pbm->filemon_fd) < 0)
|
||||
if (pbm->filemon) {
|
||||
while (filemon_process(pbm->filemon) > 0)
|
||||
continue;
|
||||
if (filemon_close(pbm->filemon) == -1)
|
||||
error = errno;
|
||||
x = filemon_read(pbm->mfp, pbm->mon_fd);
|
||||
if (error == 0 && x != 0)
|
||||
error = x;
|
||||
pbm->filemon_fd = pbm->mon_fd = -1;
|
||||
pbm->mon_fd = -1;
|
||||
pbm->filemon = NULL;
|
||||
} else
|
||||
#endif
|
||||
fprintf(pbm->mfp, "\n"); /* ensure end with newline */
|
||||
@ -1509,7 +1562,8 @@ meta_oodate(GNode *gn, Boolean oodate)
|
||||
if (buf[x - 1] == '\n')
|
||||
buf[x - 1] = '\0';
|
||||
}
|
||||
if (!hasOODATE &&
|
||||
if (p &&
|
||||
!hasOODATE &&
|
||||
!(gn->type & OP_NOMETA_CMP) &&
|
||||
strcmp(p, cmd) != 0) {
|
||||
if (DEBUG(META))
|
||||
@ -1530,6 +1584,7 @@ meta_oodate(GNode *gn, Boolean oodate)
|
||||
fprintf(debug_file, "%s: %d: there are extra build commands now that weren't in the meta data file\n", fname, lineno);
|
||||
oodate = TRUE;
|
||||
}
|
||||
CHECK_VALID_META(p);
|
||||
if (strcmp(p, cwd) != 0) {
|
||||
if (DEBUG(META))
|
||||
fprintf(debug_file, "%s: %d: the current working directory has changed from '%s' to '%s'\n", fname, lineno, p, curdir);
|
||||
@ -1603,9 +1658,10 @@ meta_compat_start(void)
|
||||
BuildMon *pbm = &Mybm;
|
||||
|
||||
if (pbm->mfp != NULL && useFilemon) {
|
||||
filemon_open(pbm);
|
||||
meta_open_filemon(pbm);
|
||||
} else {
|
||||
pbm->mon_fd = pbm->filemon_fd = -1;
|
||||
pbm->mon_fd = -1;
|
||||
pbm->filemon = NULL;
|
||||
}
|
||||
#endif
|
||||
if (pipe(childPipe) < 0)
|
||||
@ -1627,19 +1683,61 @@ meta_compat_child(void)
|
||||
}
|
||||
|
||||
void
|
||||
meta_compat_parent(void)
|
||||
meta_compat_parent(pid_t child)
|
||||
{
|
||||
FILE *fp;
|
||||
char buf[BUFSIZ];
|
||||
int outfd, metafd, maxfd, nfds;
|
||||
char buf[BUFSIZ+1];
|
||||
fd_set readfds;
|
||||
|
||||
meta_job_parent(NULL, child);
|
||||
close(childPipe[1]); /* child side */
|
||||
fp = fdopen(childPipe[0], "r");
|
||||
while (fgets(buf, sizeof(buf), fp)) {
|
||||
meta_job_output(NULL, buf, "");
|
||||
printf("%s", buf);
|
||||
fflush(stdout);
|
||||
outfd = childPipe[0];
|
||||
#ifdef USE_FILEMON
|
||||
metafd = Mybm.filemon ? filemon_readfd(Mybm.filemon) : -1;
|
||||
#else
|
||||
metafd = -1;
|
||||
#endif
|
||||
maxfd = -1;
|
||||
if (outfd > maxfd)
|
||||
maxfd = outfd;
|
||||
if (metafd > maxfd)
|
||||
maxfd = metafd;
|
||||
|
||||
while (outfd != -1 || metafd != -1) {
|
||||
FD_ZERO(&readfds);
|
||||
if (outfd != -1) {
|
||||
FD_SET(outfd, &readfds);
|
||||
}
|
||||
if (metafd != -1) {
|
||||
FD_SET(metafd, &readfds);
|
||||
}
|
||||
nfds = select(maxfd + 1, &readfds, NULL, NULL, NULL);
|
||||
if (nfds == -1) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
err(1, "select");
|
||||
}
|
||||
|
||||
if (outfd != -1 && FD_ISSET(outfd, &readfds)) do {
|
||||
/* XXX this is not line-buffered */
|
||||
ssize_t nread = read(outfd, buf, sizeof(buf) - 1);
|
||||
if (nread == -1)
|
||||
err(1, "read");
|
||||
if (nread == 0) {
|
||||
close(outfd);
|
||||
outfd = -1;
|
||||
break;
|
||||
}
|
||||
fwrite(buf, 1, (size_t)nread, stdout);
|
||||
fflush(stdout);
|
||||
buf[nread] = '\0';
|
||||
meta_job_output(NULL, buf, "");
|
||||
} while (0);
|
||||
if (metafd != -1 && FD_ISSET(metafd, &readfds)) {
|
||||
if (meta_job_event(NULL) <= 0)
|
||||
metafd = -1;
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
#endif /* USE_META */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: meta.h,v 1.5 2016/05/12 20:28:34 sjg Exp $ */
|
||||
/* $NetBSD: meta.h,v 1.6 2020/01/19 19:42:32 riastradh Exp $ */
|
||||
|
||||
/*
|
||||
* Things needed for 'meta' mode.
|
||||
@ -33,7 +33,7 @@
|
||||
|
||||
typedef struct BuildMon {
|
||||
char meta_fname[MAXPATHLEN];
|
||||
int filemon_fd;
|
||||
struct filemon *filemon;
|
||||
int mon_fd;
|
||||
FILE *mfp;
|
||||
} BuildMon;
|
||||
@ -46,6 +46,9 @@ void meta_finish(void);
|
||||
void meta_mode_init(const char *);
|
||||
void meta_job_start(struct Job *, GNode *);
|
||||
void meta_job_child(struct Job *);
|
||||
void meta_job_parent(struct Job *, pid_t);
|
||||
int meta_job_fd(struct Job *);
|
||||
int meta_job_event(struct Job *);
|
||||
void meta_job_error(struct Job *, GNode *, int, int);
|
||||
void meta_job_output(struct Job *, char *, const char *);
|
||||
int meta_cmd_finish(void *);
|
||||
@ -53,4 +56,4 @@ int meta_job_finish(struct Job *);
|
||||
Boolean meta_oodate(GNode *, Boolean);
|
||||
void meta_compat_start(void);
|
||||
void meta_compat_child(void);
|
||||
void meta_compat_parent(void);
|
||||
void meta_compat_parent(pid_t);
|
||||
|
@ -1,3 +1,86 @@
|
||||
2020-05-15 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20200515
|
||||
|
||||
* dirdeps.mk: set _debug_* earlier and allow passing -d*
|
||||
flags to submake when building DIRDEPS_CACHE
|
||||
|
||||
2020-05-09 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* whats.mk: more easily extensible
|
||||
|
||||
2020-05-02 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* whats.mk: greatly simplify by adding what.c to SRCS
|
||||
|
||||
2020-05-01 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* whats.mk: for libs take care how we add to *OBJS
|
||||
|
||||
* lib.mk: : works better with whats.mk
|
||||
|
||||
2020-04-25 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20200420
|
||||
|
||||
* meta.stage.mk: it is not a STAGE_CONFLICT if some-target.dirdep
|
||||
contains the same ${RELDIR} and a prefix match for our ${TARGET_SPEC}
|
||||
|
||||
2020-04-16 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20200416
|
||||
|
||||
* sys/*.mk: set MAKE_SHELL rather than SHELL so as not to
|
||||
interfere with user env.
|
||||
|
||||
* sys.mk: default MAKE_SHELL to sh and SHELL to MAKE_SHELL
|
||||
|
||||
* autodep.mk: use MAKE_SHELL.
|
||||
|
||||
2019-11-21 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* gendirdeps.mk: clear .SUFFIXES to avoid a lot of
|
||||
wasted effort, and unexport _meta_files when no longer needed as
|
||||
it consumes space we need for command line.
|
||||
|
||||
2019-11-11 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* dirdeps.mk _DIRDEP_USE: use DIRDEP_DIR and add
|
||||
DIRDEP_USE_PRELUDE at start - facilitates job distribution
|
||||
|
||||
2019-10-04 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* dirdeps-targets.mk: Use TARGET_SPEC_LAST_LIST
|
||||
defaults to ${${TARGET_SPEC_VARS:[-1]}_LIST} to match valid
|
||||
TARGET_SPEC qualified depend files.
|
||||
|
||||
2019-10-02 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* dirdeps-targets.mk: encapsulate logic for finding top-level
|
||||
targets to set initial DIRDEPS for DIRDEPS_BUILD
|
||||
|
||||
2019-09-27 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20190911
|
||||
|
||||
* compiler.mk: set COMPILER_TYPE
|
||||
|
||||
2019-07-17 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20190704
|
||||
|
||||
* sys/Darwin.mk: support for Objective-C and clang
|
||||
|
||||
2019-05-30 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* dirdeps.mk: avoid insanely long command line when generating cache
|
||||
|
||||
2019-05-23 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20190505
|
||||
|
||||
* whats.mk: handle corner case SHLIB defined but not LIB
|
||||
|
||||
2018-09-19 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20180919
|
||||
|
@ -5,6 +5,7 @@ auto.obj.mk
|
||||
autoconf.mk
|
||||
autodep.mk
|
||||
auto.dep.mk
|
||||
compiler.mk
|
||||
cython.mk
|
||||
dep.mk
|
||||
doc.mk
|
||||
@ -60,6 +61,7 @@ whats.mk
|
||||
yacc.mk
|
||||
dirdeps.mk
|
||||
dirdeps-options.mk
|
||||
dirdeps-targets.mk
|
||||
gendirdeps.mk
|
||||
install-new.mk
|
||||
meta2deps.py
|
||||
|
@ -1,6 +1,6 @@
|
||||
#
|
||||
# RCSid:
|
||||
# $Id: autodep.mk,v 1.36 2016/04/05 15:58:37 sjg Exp $
|
||||
# $Id: autodep.mk,v 1.37 2020/04/17 21:08:17 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 1999-2010, Simon J. Gerraty
|
||||
#
|
||||
@ -70,6 +70,7 @@ CFLAGS_MD?=-MD
|
||||
CFLAGS_MF?=-MF ${.TARGET:T:R}.d -MT ${.TARGET:T:R}.o
|
||||
CFLAGS+= ${CFLAGS_MD} ${CFLAGS_MF}
|
||||
RM?= rm
|
||||
MAKE_SHELL?= sh
|
||||
|
||||
# watch out for people who don't use CPPFLAGS
|
||||
CPPFLAGS_MD=${CFLAGS:M-[IUD]*} ${CPPFLAGS}
|
||||
@ -90,26 +91,26 @@ CXX_SUFFIXES?= .cc .cpp .cxx .C
|
||||
.y.d:
|
||||
@echo updating dependencies for $<
|
||||
@${YACC} ${YFLAGS} $<
|
||||
@${SHELL} -ec "${CC_MD} -M ${CPPFLAGS_MD} y.tab.c | sed '/:/s/^/$@ /' > $@" || { ${RM} -f y.tab.c $@; false; }
|
||||
@${MAKE_SHELL} -ec "${CC_MD} -M ${CPPFLAGS_MD} y.tab.c | sed '/:/s/^/$@ /' > $@" || { ${RM} -f y.tab.c $@; false; }
|
||||
@${RM} -f y.tab.c
|
||||
|
||||
.l.d:
|
||||
@echo updating dependencies for $<
|
||||
${LEX} ${LFLAGS} $<
|
||||
@${SHELL} -ec "${CC_MD} -M ${CPPFLAGS_MD} lex.yy.c | sed '/:/s/^/$@ /' > $@" || { ${RM} -f lex.yy.c $@; false; }
|
||||
@${MAKE_SHELL} -ec "${CC_MD} -M ${CPPFLAGS_MD} lex.yy.c | sed '/:/s/^/$@ /' > $@" || { ${RM} -f lex.yy.c $@; false; }
|
||||
@${RM} -f lex.yy.c
|
||||
|
||||
.c.d:
|
||||
@echo updating dependencies for $<
|
||||
@${SHELL} -ec "${CC_MD} -M ${CPPFLAGS_MD} $< | sed '/:/s/^/$@ /' > $@" || { ${RM} -f $@; false; }
|
||||
@${MAKE_SHELL} -ec "${CC_MD} -M ${CPPFLAGS_MD} $< | sed '/:/s/^/$@ /' > $@" || { ${RM} -f $@; false; }
|
||||
|
||||
.s.d .S.d:
|
||||
@echo updating dependencies for $<
|
||||
@${SHELL} -ec "${CC_MD} -M ${CPPFLAGS_MD} ${AINC} $< | sed '/:/s/^/$@ /' > $@" || { ${RM} -f $@; false; }
|
||||
@${MAKE_SHELL} -ec "${CC_MD} -M ${CPPFLAGS_MD} ${AINC} $< | sed '/:/s/^/$@ /' > $@" || { ${RM} -f $@; false; }
|
||||
|
||||
${CXX_SUFFIXES:%=%.d}:
|
||||
@echo updating dependencies for $<
|
||||
@${SHELL} -ec "${CXX_MD} -M ${CXXFLAGS_MD} $< | sed '/:/s/^/$@ /' > $@" || { ${RM} -f $@; false; }
|
||||
@${MAKE_SHELL} -ec "${CXX_MD} -M ${CXXFLAGS_MD} $< | sed '/:/s/^/$@ /' > $@" || { ${RM} -f $@; false; }
|
||||
.else
|
||||
.y.d:
|
||||
${YACC} ${YFLAGS} $<
|
||||
|
43
contrib/bmake/mk/compiler.mk
Normal file
43
contrib/bmake/mk/compiler.mk
Normal file
@ -0,0 +1,43 @@
|
||||
# $Id: compiler.mk,v 1.6 2019/09/28 17:12:00 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2019, Simon J. Gerraty
|
||||
#
|
||||
# This file is provided in the hope that it will
|
||||
# be of use. There is absolutely NO WARRANTY.
|
||||
# Permission to copy, redistribute or otherwise
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
||||
.if !target(__${.PARSEFILE}__)
|
||||
__${.PARSEFILE}__:
|
||||
|
||||
.if ${MACHINE} == "common"
|
||||
COMPILER_TYPE = none
|
||||
COMPILER_VERSION = 0
|
||||
.endif
|
||||
.if empty(COMPILER_TYPE) || empty(COMPILER_VERSION)
|
||||
# gcc does not always say gcc
|
||||
_v != ${CC} --version 2> /dev/null | \
|
||||
egrep -i 'clang|cc|[1-9]\.[0-9]|Free Software Foundation'
|
||||
.if empty(COMPILER_TYPE)
|
||||
.if ${_v:Mclang} != ""
|
||||
COMPILER_TYPE = clang
|
||||
.elif ${_v:M[Gg][Cc][Cc]} != "" || ${_v:MFoundation*} != ""
|
||||
COMPILER_TYPE = gcc
|
||||
.endif
|
||||
.endif
|
||||
.if empty(COMPILER_VERSION)
|
||||
COMPILER_VERSION != echo "${_v:M[1-9].[0-9]*}:[1]" | \
|
||||
awk -F. '{print $$1 * 10000 + $$2 * 100 + $$3;}'
|
||||
.endif
|
||||
.undef _v
|
||||
.endif
|
||||
# just in case we don't recognize compiler
|
||||
COMPILER_TYPE ?= unknown
|
||||
COMPILER_VERSION ?= 0
|
||||
.endif
|
133
contrib/bmake/mk/dirdeps-targets.mk
Normal file
133
contrib/bmake/mk/dirdeps-targets.mk
Normal file
@ -0,0 +1,133 @@
|
||||
# RCSid:
|
||||
# $Id: dirdeps-targets.mk,v 1.9 2019/10/06 20:07:50 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2019 Simon J. Gerraty
|
||||
#
|
||||
# This file is provided in the hope that it will
|
||||
# be of use. There is absolutely NO WARRANTY.
|
||||
# Permission to copy, redistribute or otherwise
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
||||
##
|
||||
# This makefile is used to set initial DIRDEPS for top-level build
|
||||
# targets.
|
||||
#
|
||||
# The basic idea is that we have a list of directories in
|
||||
# DIRDEPS_TARGETS_DIRS which are relative to SRCTOP.
|
||||
# When asked to make 'foo' we look for any directory named 'foo'
|
||||
# under DIRDEPS_TARGETS_DIRS.
|
||||
# We then search those dirs for any Makefile.depend*
|
||||
# Finally we select any that match conditions like REQUESTED_MACHINE
|
||||
# or TARGET_SPEC and initialize DIRDEPS accordingly.
|
||||
#
|
||||
|
||||
.if ${.MAKE.LEVEL} == 0
|
||||
# pickup customizations
|
||||
.-include <local.dirdeps-targets.mk>
|
||||
|
||||
# for DIRDEPS_BUILD this is how we prime the pump
|
||||
DIRDEPS_TARGETS_DIRS ?= targets targets/pseudo
|
||||
# these prefixes can modify how we behave
|
||||
# they need to be stripped when looking for target dirs
|
||||
DIRDEPS_TARGETS_PREFIX_LIST ?= pkg- build-
|
||||
|
||||
# matching target dirs if any
|
||||
tdirs := ${.TARGETS:Nall:${DIRDEPS_TARGETS_PREFIX_LIST:@p@S,^$p,,@:ts:}:@t@${DIRDEPS_TARGETS_DIRS:@d@$d/$t@}@:@d@${exists(${SRCTOP}/$d):?$d:}@}
|
||||
|
||||
.if !empty(DEBUG_DIRDEPS_TARGETS)
|
||||
.info tdirs=${tdirs}
|
||||
.endif
|
||||
|
||||
.if !empty(tdirs)
|
||||
# some things we know we want to ignore
|
||||
DIRDEPS_TARGETS_SKIP_LIST += \
|
||||
*~ \
|
||||
*.bak \
|
||||
*.inc \
|
||||
*.old \
|
||||
*.options \
|
||||
*.orig \
|
||||
*.rej \
|
||||
|
||||
# the list of MACHINEs we consider
|
||||
DIRDEPS_TARGETS_MACHINE_LIST += \
|
||||
${ALL_MACHINE_LIST:U} \
|
||||
${PSEUDO_MACHINE_LIST:Ucommon host host32} \
|
||||
${TARGET_MACHINE_LIST}
|
||||
|
||||
DIRDEPS_TARGETS_MACHINE_LIST := ${DIRDEPS_TARGETS_MACHINE_LIST:O:u}
|
||||
|
||||
# raw Makefile.depend* list
|
||||
tdeps != 'cd' ${SRCTOP} && 'ls' -1 ${tdirs:O:u:@d@$d/${.MAKE.DEPENDFILE_PREFIX}*@} 2> /dev/null; echo
|
||||
.if ${DEBUG_DIRDEPS_TARGETS:U:Mdep*} != ""
|
||||
.info tdeps=${tdeps}
|
||||
.endif
|
||||
# remove things we know we don't want
|
||||
tdeps := ${tdeps:${DIRDEPS_TARGETS_SKIP_LIST:${M_ListToSkip}}}
|
||||
.if ${DEBUG_DIRDEPS_TARGETS:U:Mdep*} != ""
|
||||
.info tdeps=${tdeps}
|
||||
.endif
|
||||
|
||||
# plain entries (no qualifiers) these apply to any TARGET_SPEC
|
||||
ptdeps := ${tdeps:M*${.MAKE.DEPENDFILE_PREFIX}:S,/${.MAKE.DEPENDFILE_PREFIX},,}
|
||||
|
||||
# MACHINE qualified entries
|
||||
mqtdeps := ${DIRDEPS_TARGETS_MACHINE_LIST:@m@${tdeps:M*.$m}@:S,/${.MAKE.DEPENDFILE_PREFIX},,}
|
||||
|
||||
tqtdeps =
|
||||
.if ${TARGET_SPEC_VARS:[#]} > 1
|
||||
# TARGET_SPEC qualified entries
|
||||
.if !empty(TARGET_SPEC_LIST)
|
||||
# we have a list of valid TARGET_SPECS; use it
|
||||
tqtdeps := ${TARGET_SPEC_LIST:U:O:u:@t@${tdeps:M*.$t}@:S,/${.MAKE.DEPENDFILE_PREFIX},,}
|
||||
.else
|
||||
# do we have a list of valid tuple members for at least
|
||||
# the last tupple element? if so match on that
|
||||
TARGET_SPEC_LAST_LIST ?= ${${TARGET_SPEC_VARS:[-1]}_LIST}
|
||||
.if !empty(TARGET_SPEC_LAST_LIST)
|
||||
tqtdeps := ${TARGET_SPEC_LAST_LIST:U:O:u:@t@${tdeps:M*,$t}@:S,/${.MAKE.DEPENDFILE_PREFIX},,}
|
||||
.else
|
||||
# this is sub-optimal match MACHINE,
|
||||
tqtdeps := ${DIRDEPS_TARGETS_MACHINE_LIST:@m@${tdeps:M*.$m,*}@:S,/${.MAKE.DEPENDFILE_PREFIX},,}
|
||||
.endif
|
||||
.endif
|
||||
.endif
|
||||
|
||||
# now work out what we want in DIRDEPS
|
||||
.if empty(REQUESTED_MACHINE)
|
||||
# we want them all just as found
|
||||
DIRDEPS = ${ptdeps} ${mqtdeps} ${tqtdeps}
|
||||
.else
|
||||
# we only want those that match REQUESTED_MACHINE/REQUESTED_TARGET_SPEC
|
||||
# or REQUESTED_TARGET_SPEC (TARGET_SPEC)
|
||||
DIRDEPS = \
|
||||
${ptdeps:@d@$d.${REQUESTED_TARGET_SPEC:U${TARGET_SPEC:U${REQUESTED_MACHINE}}}@} \
|
||||
${mqtdeps:M*.${REQUESTED_MACHINE}} \
|
||||
${tqtdeps:M*.${REQUESTED_TARGET_SPEC:U${TARGET_SPEC}}}
|
||||
.endif
|
||||
# clean up
|
||||
DIRDEPS := ${DIRDEPS:O:u}
|
||||
|
||||
.if !empty(DEBUG_DIRDEPS_TARGETS)
|
||||
.for x in tdeps ptdeps mqtdeps tqtdeps DIRDEPS
|
||||
.info $x=${$x}
|
||||
.endfor
|
||||
.endif
|
||||
.endif
|
||||
# if we got DIRDEPS get to work
|
||||
.if !empty(DIRDEPS)
|
||||
.include <dirdeps.mk>
|
||||
|
||||
DIRDEPS_TARGETS_SKIP += all clean* destroy*
|
||||
|
||||
.for t in ${.TARGETS:${DIRDEPS_TARGETS_SKIP:${M_ListToSkip}}}
|
||||
$t: dirdeps
|
||||
.endfor
|
||||
.endif
|
||||
.endif
|
@ -1,6 +1,7 @@
|
||||
# $Id: dirdeps.mk,v 1.96 2018/06/20 22:26:39 sjg Exp $
|
||||
# $Id: dirdeps.mk,v 1.104 2020/05/16 23:21:48 sjg Exp $
|
||||
|
||||
# Copyright (c) 2010-2013, Juniper Networks, Inc.
|
||||
# Copyright (c) 2010-2020, Simon J. Gerraty
|
||||
# Copyright (c) 2010-2018, Juniper Networks, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@ -339,6 +340,17 @@ BUILD_DIRDEPS ?= yes
|
||||
DIRDEPS_CACHE ?= ${_OBJDIR:tA}/dirdeps.cache${.TARGETS:Nall:O:u:ts-:S,/,_,g:S,^,.,:N.}
|
||||
.endif
|
||||
|
||||
.if ${DEBUG_DIRDEPS:@x@${DEP_RELDIR:M$x}${${DEP_RELDIR}.${DEP_MACHINE}:L:M$x}@} != ""
|
||||
_debug_reldir = 1
|
||||
.else
|
||||
_debug_reldir = 0
|
||||
.endif
|
||||
.if ${DEBUG_DIRDEPS:@x@${DEP_RELDIR:M$x}${${DEP_RELDIR}.depend:L:M$x}@} != ""
|
||||
_debug_search = 1
|
||||
.else
|
||||
_debug_search = 0
|
||||
.endif
|
||||
|
||||
# pickup customizations
|
||||
# as below you can use !target(_DIRDEP_USE) to protect things
|
||||
# which should only be done once.
|
||||
@ -378,7 +390,8 @@ DIRDEPS_FILTER += M${_DEP_RELDIR}
|
||||
.endif
|
||||
|
||||
# this is what we run below
|
||||
DIRDEP_MAKE?= ${.MAKE}
|
||||
DIRDEP_MAKE ?= ${.MAKE}
|
||||
DIRDEP_DIR ?= ${.TARGET:R}
|
||||
|
||||
# we suppress SUBDIR when visiting the leaves
|
||||
# we assume sys.mk will set MACHINE_ARCH
|
||||
@ -388,10 +401,11 @@ _DIRDEP_USE: .USE .MAKE
|
||||
@for m in ${.MAKE.MAKEFILE_PREFERENCE}; do \
|
||||
test -s ${.TARGET:R}/$$m || continue; \
|
||||
echo "${TRACER}Checking ${.TARGET:R} for ${.TARGET:E} ..."; \
|
||||
${DIRDEP_USE_PRELUDE} \
|
||||
MACHINE_ARCH= NO_SUBDIR=1 ${DIRDEP_USE_ENV} \
|
||||
TARGET_SPEC=${.TARGET:E} \
|
||||
MACHINE=${.TARGET:E} \
|
||||
${DIRDEP_MAKE} -C ${.TARGET:R} || exit 1; \
|
||||
${DIRDEP_MAKE} -C ${DIRDEP_DIR} || exit 1; \
|
||||
break; \
|
||||
done
|
||||
|
||||
@ -475,7 +489,7 @@ BUILD_DIRDEPS_TARGETS ?= ${.TARGETS}
|
||||
${DIRDEPS_CACHE}: .META .NOMETA_CMP
|
||||
+@{ echo '# Autogenerated - do NOT edit!'; echo; \
|
||||
echo 'BUILD_DIRDEPS=no'; echo; \
|
||||
echo '.include <dirdeps.mk>'; \
|
||||
echo '.include <dirdeps.mk>'; echo; \
|
||||
} > ${.TARGET}.new
|
||||
+@MAKELEVEL=${.MAKE.LEVEL} DIRDEPS_CACHE=${DIRDEPS_CACHE} \
|
||||
DIRDEPS="${DIRDEPS}" \
|
||||
@ -484,6 +498,7 @@ ${DIRDEPS_CACHE}: .META .NOMETA_CMP
|
||||
${BUILD_DIRDEPS_TARGETS} BUILD_DIRDEPS_CACHE=yes \
|
||||
.MAKE.DEPENDFILE=.none \
|
||||
${.MAKEFLAGS:tW:S,-D ,-D,g:tw:M*WITH*} \
|
||||
${.MAKEFLAGS:tW:S,-d ,-d,g:tw:M-d*} \
|
||||
3>&1 1>&2 | sed 's,${SRCTOP},$${SRCTOP},g' >> ${.TARGET}.new && \
|
||||
mv ${.TARGET}.new ${.TARGET}
|
||||
|
||||
@ -504,16 +519,6 @@ _count_dirdeps: .NOMETA
|
||||
.endif
|
||||
|
||||
.if ${BUILD_DIRDEPS} == "yes"
|
||||
.if ${DEBUG_DIRDEPS:@x@${DEP_RELDIR:M$x}${${DEP_RELDIR}.${DEP_MACHINE}:L:M$x}@} != ""
|
||||
_debug_reldir = 1
|
||||
.else
|
||||
_debug_reldir = 0
|
||||
.endif
|
||||
.if ${DEBUG_DIRDEPS:@x@${DEP_RELDIR:M$x}${${DEP_RELDIR}.depend:L:M$x}@} != ""
|
||||
_debug_search = 1
|
||||
.else
|
||||
_debug_search = 0
|
||||
.endif
|
||||
|
||||
# the rest is done repeatedly for every Makefile.depend we read.
|
||||
# if we are anything but the original dir we care only about the
|
||||
@ -639,9 +644,15 @@ _build_all_dirs := ${_build_all_dirs:O:u}
|
||||
.if ${.MAKEFLAGS:M-V${_V_READ_DIRDEPS}} == ""
|
||||
.if !empty(_build_all_dirs)
|
||||
.if ${BUILD_DIRDEPS_CACHE} == "yes"
|
||||
x!= { echo; echo '\# ${DEP_RELDIR}.${DEP_TARGET_SPEC}'; \
|
||||
echo 'dirdeps: ${_build_all_dirs:${M_oneperline}}'; echo; } >&3; echo
|
||||
x!= { ${_build_all_dirs:@x@${target($x):?:echo '$x: _DIRDEP_USE';}@} echo; } >&3; echo
|
||||
# guard against _build_all_dirs being too big for a single command line
|
||||
# first get list of dirs that need _DIRDEP_USE
|
||||
# then export that and _build_all_dirs
|
||||
_new_dirdeps := ${_build_all_dirs:@x@${target($x):?:$x}@}
|
||||
.export _new_dirdeps _build_all_dirs
|
||||
x!= echo; { echo '\# ${DEP_RELDIR}.${DEP_TARGET_SPEC}'; \
|
||||
echo "dirdeps: \\"; \
|
||||
for x in $$_build_all_dirs; do echo " $$x \\"; done; echo; \
|
||||
for x in $$_new_dirdeps; do echo "$$x: _DIRDEP_USE"; done; echo; } >&3
|
||||
.if !empty(DEP_EXPORT_VARS)
|
||||
# Discouraged, but there are always exceptions.
|
||||
# Handle it here rather than explain how.
|
||||
@ -671,7 +682,10 @@ DEP_EXPORT_VARS=
|
||||
.info ${DEP_RELDIR}.$m: graph: ${_build_dirs:M*.$q}
|
||||
.endif
|
||||
.if ${BUILD_DIRDEPS_CACHE} == "yes"
|
||||
x!= { echo; echo '${_this_dir}.$m: ${_build_dirs:M*.$q:${M_oneperline}}'; echo; } >&3; echo
|
||||
_cache_deps := ${_build_dirs:M*.$q}
|
||||
.export _cache_deps
|
||||
x!= echo; { echo "${_this_dir}.$m: \\"; \
|
||||
for x in $$_cache_deps; do echo " $$x \\"; done; echo; } >&3
|
||||
.else
|
||||
${_this_dir}.$m: ${_build_dirs:M*.$q}
|
||||
.endif
|
||||
@ -681,7 +695,10 @@ ${_this_dir}.$m: ${_build_dirs:M*.$q}
|
||||
.info ${DEP_RELDIR}.$m: graph: ${_build_dirs:M*.$m:N${_this_dir}.$m}
|
||||
.endif
|
||||
.if ${BUILD_DIRDEPS_CACHE} == "yes"
|
||||
x!= { echo; echo '${_this_dir}.$m: ${_build_dirs:M*.$m:N${_this_dir}.$m:${M_oneperline}}'; echo; } >&3; echo
|
||||
_cache_deps := ${_build_dirs:M*.$m:N${_this_dir}.$m}
|
||||
.export _cache_deps
|
||||
x!= echo; { echo "${_this_dir}.$m: \\"; \
|
||||
for x in $$_cache_deps; do echo " $$x \\"; done; echo; } >&3
|
||||
.else
|
||||
${_this_dir}.$m: ${_build_dirs:M*.$m:N${_this_dir}.$m}
|
||||
.endif
|
||||
|
@ -1,8 +1,10 @@
|
||||
# $Id: doc.mk,v 1.6 2017/05/01 21:24:10 sjg Exp $
|
||||
# $Id: doc.mk,v 1.7 2019/06/09 16:22:08 sjg Exp $
|
||||
|
||||
.if !target(__${.PARSEFILE}__)
|
||||
__${.PARSEFILE}__:
|
||||
|
||||
.include <init.mk>
|
||||
|
||||
BIB?= bib
|
||||
EQN?= eqn
|
||||
GREMLIN?= grn
|
||||
@ -16,9 +18,8 @@ TBL?= tbl
|
||||
|
||||
.PATH: ${.CURDIR}
|
||||
|
||||
.if !target(all)
|
||||
.MAIN: all
|
||||
all: paper.ps
|
||||
.if !defined(_SKIP_BUILD)
|
||||
realbuild: paper.ps
|
||||
.endif
|
||||
|
||||
.if !target(paper.ps)
|
||||
@ -56,8 +57,6 @@ install:
|
||||
spell: ${SRCS}
|
||||
spell ${SRCS} | sort | comm -23 - spell.ok > paper.spell
|
||||
|
||||
.include <own.mk>
|
||||
|
||||
.if !empty(DOCOWN)
|
||||
DOC_INSTALL_OWN?= -o ${DOCOWN} -g ${DOCGRP}
|
||||
.endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: dpadd.mk,v 1.26 2018/02/12 21:54:26 sjg Exp $
|
||||
# $Id: dpadd.mk,v 1.27 2019/05/17 13:58:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2004, Simon J. Gerraty
|
||||
#
|
||||
@ -13,6 +13,69 @@
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
||||
##
|
||||
# DESCRIPTION:
|
||||
# This makefile manages a number of variables that simplify
|
||||
# dealing with libs in a build.
|
||||
#
|
||||
# Primary inputs are DPLIBS, DPADD and SRC_LIBS:
|
||||
#
|
||||
# DPLIBS
|
||||
# List of LIB* that we will actually link with
|
||||
# should be in correct link order.
|
||||
# DPLIBS is a short-cut to ensure that DPADD and LDADD are
|
||||
# kept in sync.
|
||||
#
|
||||
# DPADD List of LIB* that should already be built.
|
||||
#
|
||||
# SRC_LIBS
|
||||
# List of LIB* that we want headers from, we do *not*
|
||||
# require that such libs have been built.
|
||||
#
|
||||
# The above all get added to DPMAGIC_LIBS which is what we
|
||||
# process.
|
||||
#
|
||||
# We expect LIB* to be set to absolute path of a library -
|
||||
# suitable for putting in DPADD.
|
||||
# eg.
|
||||
#
|
||||
# LIBC ?= ${OBJTOP}/lib/libc/libc.a
|
||||
#
|
||||
# From such a path we can derrive a number of other variables
|
||||
# for which we can supply sensible default values.
|
||||
# We name all these variables for the basename of the library
|
||||
# (libc in our example above -- ${__lib:T:R} in below):
|
||||
#
|
||||
# LDADD_${__lib:T:R}:
|
||||
# What should be added to LDADD (eg -lc)
|
||||
#
|
||||
# OBJ_${__lib:T:R}:
|
||||
# This is trivial - just the dirname of the built library.
|
||||
#
|
||||
# SRC_${__lib:T:R}:
|
||||
# Where the src for ${__lib} is, if LIB* is set as above
|
||||
# we can simply substitute ${SRCTOP} for ${OBJTOP} in
|
||||
# the dirname.
|
||||
#
|
||||
# INCLUDES_${__lib:T:R}:
|
||||
# What should be added to CFLAGS
|
||||
#
|
||||
# If the directory ${SRC_${__lib:T:R}}/h exists we will
|
||||
# only add -I${SRC_${__lib:T:R}}/h on the basis that
|
||||
# this is where the public api is kept.
|
||||
#
|
||||
# Otherwise default will be -I${OBJ_${__lib:T:R}}
|
||||
# -I${SRC_${__lib:T:R}}
|
||||
#
|
||||
# Note much of the above is skipped for staged libs
|
||||
# eg.
|
||||
# LIBC ?= ${STAGE_OBJTOP}/usr/lib/libc.a
|
||||
#
|
||||
# Since we can safely assume that -I${STAGE_OBJTOP}/usr/include
|
||||
# and -L${STAGE_OBJTOP}/usr/lib are sufficient, and we should
|
||||
# have no need of anything else.
|
||||
#
|
||||
|
||||
.if !target(__${.PARSEFILE}__)
|
||||
__${.PARSEFILE}__:
|
||||
|
||||
@ -50,7 +113,7 @@ CXXFLAGS_LAST += ${CXXFLAGS_DEBUG_XTRA}
|
||||
DPLIBS+= ${DPLIBS_LAST}
|
||||
DPADD+= ${DPLIBS:N-*}
|
||||
.for __lib in ${DPLIBS}
|
||||
.if "${_lib:M-*}" != ""
|
||||
.if "${__lib:M-*}" != ""
|
||||
LDADD += ${__lib}
|
||||
.else
|
||||
LDADD += ${LDADD_${__lib:T:R}:U${__lib:T:R:S/lib/-l/:C/\.so.*//}}
|
||||
|
@ -1,6 +1,7 @@
|
||||
# $Id: gendirdeps.mk,v 1.39 2018/06/08 01:25:31 sjg Exp $
|
||||
# $Id: gendirdeps.mk,v 1.42 2020/05/16 23:21:48 sjg Exp $
|
||||
|
||||
# Copyright (c) 2010-2013, Juniper Networks, Inc.
|
||||
# Copyright (c) 2011-2020, Simon J. Gerraty
|
||||
# Copyright (c) 2010-2018, Juniper Networks, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@ -79,7 +80,6 @@ _DIRDEPS := ${DIRDEPS:U:O:u}
|
||||
.endif
|
||||
|
||||
META_FILES := ${META_FILES:T:O:u}
|
||||
.export META_FILES
|
||||
|
||||
# pickup customizations
|
||||
.-include <local.gendirdeps.mk>
|
||||
@ -183,6 +183,11 @@ x != cd ${_OBJDIR} && find . -name '*.meta' -print -o \( -type d ! -name . -prun
|
||||
.elif ${_meta_files:[#]} > 500
|
||||
.export _meta_files
|
||||
x != echo; for m in $$_meta_files; do echo $$m; done > meta.list
|
||||
# _meta_files is consuming a lot of env space
|
||||
# that can impact command line length,
|
||||
# and we do not need it any more
|
||||
.undef _meta_files
|
||||
.unexport _meta_files
|
||||
.else
|
||||
_meta_files_arg:= ${_meta_files}
|
||||
.endif
|
||||
@ -373,3 +378,6 @@ all ${_DEPENDFILE}:
|
||||
|
||||
.endif
|
||||
${_DEPENDFILE}: .PRECIOUS
|
||||
|
||||
# don't waste time looking for ways to make .meta files
|
||||
.SUFFIXES:
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: init.mk,v 1.15 2017/05/07 20:27:54 sjg Exp $
|
||||
# $Id: init.mk,v 1.16 2019/09/28 16:54:02 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2002, Simon J. Gerraty
|
||||
#
|
||||
@ -25,6 +25,7 @@ _this_mk_dir := ${.PARSEDIR}
|
||||
.-include <local.init.mk>
|
||||
.-include <${.CURDIR:H}/Makefile.inc>
|
||||
.include <own.mk>
|
||||
.include <compiler.mk>
|
||||
|
||||
.MAIN: all
|
||||
|
||||
@ -35,9 +36,9 @@ CXX_SUFFIXES?= .cc .cpp .cxx .C
|
||||
.include <warnings.mk>
|
||||
.endif
|
||||
|
||||
COPTS += ${COPTS.${.IMPSRC:T}}
|
||||
CPPFLAGS += ${CPPFLAGS.${.IMPSRC:T}}
|
||||
CPUFLAGS += ${CPUFLAGS.${.IMPSRC:T}}
|
||||
.for x in COPTS CPPFLAGS CPUFLAGS LDFLAGS
|
||||
$x += ${$x.${COMPILER_TYPE}:U} ${$x.${.IMPSRC:T}:U}
|
||||
.endfor
|
||||
|
||||
CC_PG?= -pg
|
||||
CXX_PG?= ${CC_PG}
|
||||
|
@ -55,7 +55,7 @@
|
||||
# Simon J. Gerraty <sjg@crufty.net>
|
||||
|
||||
# RCSid:
|
||||
# $Id: install-mk,v 1.160 2018/09/20 00:07:19 sjg Exp $
|
||||
# $Id: install-mk,v 1.170 2020/05/15 21:40:24 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 1994 Simon J. Gerraty
|
||||
#
|
||||
@ -70,7 +70,7 @@
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
||||
MK_VERSION=20180919
|
||||
MK_VERSION=20200515
|
||||
OWNER=
|
||||
GROUP=
|
||||
MODE=444
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: lib.mk,v 1.68 2018/01/26 20:08:16 sjg Exp $
|
||||
# $Id: lib.mk,v 1.70 2020/05/02 02:10:20 sjg Exp $
|
||||
|
||||
.if !target(__${.PARSEFILE}__)
|
||||
__${.PARSEFILE}__:
|
||||
@ -170,13 +170,15 @@ LD_solib= lib${LIB}_pic.a
|
||||
.elif ${TARGET_OSNAME} == "Linux"
|
||||
SHLIB_LD = ${CC}
|
||||
# this is ambiguous of course
|
||||
LD_shared=-shared -Wl,"-h lib${LIB}.so.${SHLIB_MAJOR}"
|
||||
LD_shared=-shared -Wl,"-soname lib${LIB}.so.${SHLIB_MAJOR}"
|
||||
LD_solib= -Wl,--whole-archive lib${LIB}_pic.a -Wl,--no-whole-archive
|
||||
.if ${COMPILER_TYPE} == "gcc"
|
||||
# Linux uses GNU ld, which is a multi-pass linker
|
||||
# so we don't need to use lorder or tsort
|
||||
LD_objs = ${OBJS}
|
||||
LD_pobjs = ${POBJS}
|
||||
LD_sobjs = ${SOBJS}
|
||||
.endif
|
||||
.elif ${TARGET_OSNAME} == "Darwin"
|
||||
SHLIB_LD = ${CC}
|
||||
SHLIB_INSTALL_VERSION ?= ${SHLIB_MAJOR}
|
||||
@ -406,18 +408,18 @@ SHLIB_AGE?=0
|
||||
|
||||
# can't really do profiled libs with libtool - its too fascist about
|
||||
# naming the output...
|
||||
lib${LIB}.a:: ${OBJS}
|
||||
lib${LIB}.a: ${OBJS}
|
||||
@rm -f ${.TARGET}
|
||||
${LIBTOOL} --mode=link ${CC} ${LT_STATIC} -o ${.TARGET:.a=.la} ${OBJS:.o=.lo} -rpath ${SHLIBDIR}:/usr/lib -version-info ${SHLIB_MAJOR}:${SHLIB_MINOR}:${SHLIB_AGE}
|
||||
@ln .libs/${.TARGET} .
|
||||
|
||||
lib${LIB}.${LD_so}:: lib${LIB}.a
|
||||
lib${LIB}.${LD_so}: lib${LIB}.a
|
||||
@[ -s ${.TARGET}.${SHLIB_AGE} ] || { ln -s .libs/lib${LIB}.${LD_so}* . 2>/dev/null; : }
|
||||
@[ -s ${.TARGET} ] || ln -s ${.TARGET}.${SHLIB_AGE} ${.TARGET}
|
||||
|
||||
.else # MK_LIBTOOL=yes
|
||||
|
||||
lib${LIB}.a:: ${OBJS}
|
||||
lib${LIB}.a: ${OBJS}
|
||||
@${META_NOECHO} building standard ${LIB} library
|
||||
@rm -f ${.TARGET}
|
||||
@${AR} ${AR_cq} ${.TARGET} ${LD_objs}
|
||||
@ -425,7 +427,7 @@ lib${LIB}.a:: ${OBJS}
|
||||
|
||||
POBJS+= ${OBJS:.o=.po}
|
||||
.NOPATH: ${POBJS}
|
||||
lib${LIB}_p.a:: ${POBJS}
|
||||
lib${LIB}_p.a: ${POBJS}
|
||||
@${META_NOECHO} building profiled ${LIB} library
|
||||
@rm -f ${.TARGET}
|
||||
@${AR} ${AR_cq} ${.TARGET} ${LD_pobjs}
|
||||
@ -433,7 +435,7 @@ lib${LIB}_p.a:: ${POBJS}
|
||||
|
||||
SOBJS+= ${OBJS:.o=${PICO}}
|
||||
.NOPATH: ${SOBJS}
|
||||
lib${LIB}_pic.a:: ${SOBJS}
|
||||
lib${LIB}_pic.a: ${SOBJS}
|
||||
@${META_NOECHO} building shared object ${LIB} library
|
||||
@rm -f ${.TARGET}
|
||||
@${AR} ${AR_cq} ${.TARGET} ${LD_sobjs}
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: meta.stage.mk,v 1.56 2018/07/08 17:12:54 sjg Exp $
|
||||
# $Id: meta.stage.mk,v 1.59 2020/04/25 18:18:27 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2011-2017, Simon J. Gerraty
|
||||
#
|
||||
@ -18,9 +18,11 @@
|
||||
.if !target(__${.PARSEFILE}__)
|
||||
# the guard target is defined later
|
||||
|
||||
.-include <local.meta.stage.mk>
|
||||
|
||||
.if ${.MAKE.DEPENDFILE_PREFERENCE:U${.MAKE.DEPENDFILE}:M*.${MACHINE}} != ""
|
||||
# this is generally safer anyway
|
||||
_dirdep ?= ${RELDIR}.${MACHINE}
|
||||
_dirdep ?= ${RELDIR}.${TARGET_SPEC:U${MACHINE}}
|
||||
.else
|
||||
_dirdep ?= ${RELDIR}
|
||||
.endif
|
||||
@ -67,7 +69,7 @@ LN_CP_SCRIPT = LnCp() { \
|
||||
# a warning is handy when bootstapping different options.
|
||||
STAGE_CONFLICT?= ERROR
|
||||
.if ${STAGE_CONFLICT:tl} == "error"
|
||||
STAGE_CONFLICT_ACTION= exit 1;
|
||||
STAGE_CONFLICT_ACTION= exit 1
|
||||
.else
|
||||
STAGE_CONFLICT_ACTION=
|
||||
.endif
|
||||
@ -78,8 +80,10 @@ STAGE_DIRDEP_SCRIPT = ${LN_CP_SCRIPT}; StageDirdep() { \
|
||||
t=$$1; \
|
||||
if [ -s $$t.dirdep ]; then \
|
||||
cmp -s .dirdep $$t.dirdep && return; \
|
||||
echo "${STAGE_CONFLICT}: $$t installed by `cat $$t.dirdep` not ${_dirdep}" >&2; \
|
||||
${STAGE_CONFLICT_ACTION} \
|
||||
x=`cat $$t.dirdep`; \
|
||||
case "${RELDIR}:${_dirdep}" in $${x%.*}:$${x}*) ;; \
|
||||
*) echo "${STAGE_CONFLICT}: $$t installed by $$x not ${_dirdep}" >&2; \
|
||||
${STAGE_CONFLICT_ACTION} ;; esac; \
|
||||
fi; \
|
||||
LnCp .dirdep $$t.dirdep || exit 1; }
|
||||
|
||||
@ -205,7 +209,7 @@ stage_files.$s: .dirdep
|
||||
STAGE_FILES ?= ${.ALLSRC:N.dirdep:Nstage_*}
|
||||
stage_files: .dirdep
|
||||
.endif
|
||||
@${STAGE_FILE_SCRIPT}; StageFiles ${FLAGS.$@} ${STAGE_FILES_DIR.$s:U${STAGE_DIR.$s}:${STAGE_DIR_FILTER}} ${STAGE_FILES.$s}
|
||||
@${STAGE_FILE_SCRIPT}; StageFiles ${FLAGS.$@} ${STAGE_FILES_DIR.$s:U${STAGE_DIR.$s}:${STAGE_DIR_FILTER}} ${STAGE_FILES.$s:O}
|
||||
@touch $@
|
||||
.endif
|
||||
.endif
|
||||
@ -271,7 +275,7 @@ STAGE_AS.$s ?= ${.ALLSRC:N.dirdep:Nstage_*}
|
||||
.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}}}@}
|
||||
@${STAGE_AS_SCRIPT}; StageAs ${FLAGS.$@} ${STAGE_FILES_DIR.$s:U${STAGE_DIR.$s}:${STAGE_DIR_FILTER}} ${STAGE_AS.$s:O:@f@$f ${STAGE_AS_${f:tA}:U${STAGE_AS_${f:T}:U${f:T}}}@}
|
||||
@touch $@
|
||||
.endif
|
||||
.endif
|
||||
@ -286,8 +290,8 @@ STAGE_AS_AND_SYMLINK.$s ?= ${.ALLSRC:N.dirdep:Nstage_*}
|
||||
.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@}
|
||||
@${STAGE_AS_SCRIPT}; StageAs ${FLAGS.$@} ${STAGE_FILES_DIR.$s:U${STAGE_DIR.$s}:${STAGE_DIR_FILTER}} ${STAGE_AS_AND_SYMLINK.$s:O:@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:O:@f@${STAGE_AS_${f:tA}:U${STAGE_AS_${f:T}:U${f:T}}} $f@}
|
||||
@touch $@
|
||||
.endif
|
||||
.endif
|
||||
|
@ -1,7 +1,7 @@
|
||||
# $Id: meta.sys.mk,v 1.32 2017/06/11 03:24:04 sjg Exp $
|
||||
# $Id: meta.sys.mk,v 1.36 2020/05/16 23:21:48 sjg Exp $
|
||||
|
||||
#
|
||||
# @(#) Copyright (c) 2010, Simon J. Gerraty
|
||||
# @(#) Copyright (c) 2010-2020, Simon J. Gerraty
|
||||
#
|
||||
# This file is provided in the hope that it will
|
||||
# be of use. There is absolutely NO WARRANTY.
|
||||
@ -22,7 +22,7 @@
|
||||
|
||||
.-include <local.meta.sys.mk>
|
||||
|
||||
# absoulte path to what we are reading.
|
||||
# absolute path to what we are reading.
|
||||
_PARSEDIR = ${.PARSEDIR:tA}
|
||||
|
||||
.if !defined(SYS_MK_DIR)
|
||||
@ -61,13 +61,15 @@ META_MODE += silent=yes
|
||||
MACHINE = host
|
||||
.endif
|
||||
|
||||
.if ${.MAKE.LEVEL} == 0
|
||||
.if !defined(MACHINE0)
|
||||
# it can be handy to know which MACHINE kicked off the build
|
||||
# for example, if using Makefild.depend for multiple machines,
|
||||
# allowing only MACHINE0 to update can keep things simple.
|
||||
MACHINE0 := ${MACHINE}
|
||||
.export MACHINE0
|
||||
.endif
|
||||
|
||||
.if !defined(META2DEPS)
|
||||
.if defined(PYTHON) && exists(${PYTHON})
|
||||
# we prefer the python version of this - it is much faster
|
||||
META2DEPS ?= ${.PARSEDIR}/meta2deps.py
|
||||
@ -126,9 +128,11 @@ META_NOECHO= :
|
||||
# ignore mtime of shell
|
||||
# and mtime of makefiles does not matter in meta mode
|
||||
.MAKE.META.IGNORE_PATHS += \
|
||||
${MAKEFILE} \
|
||||
${SHELL} \
|
||||
${SYS_MK_DIR}
|
||||
${MAKEFILE} \
|
||||
${MAKE_SHELL} \
|
||||
${SHELL} \
|
||||
${SYS_MK_DIR} \
|
||||
|
||||
|
||||
.if ${UPDATE_DEPENDFILE:Uyes:tl} != "no"
|
||||
.if ${.MAKEFLAGS:Uno:M-k} != ""
|
||||
|
@ -37,9 +37,10 @@
|
||||
|
||||
"""
|
||||
RCSid:
|
||||
$Id: meta2deps.py,v 1.27 2017/05/24 00:04:04 sjg Exp $
|
||||
$Id: meta2deps.py,v 1.28 2020/05/16 23:21:48 sjg Exp $
|
||||
|
||||
Copyright (c) 2011-2013, Juniper Networks, Inc.
|
||||
Copyright (c) 2011-2019, Simon J. Gerraty
|
||||
Copyright (c) 2011-2017, Juniper Networks, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: options.mk,v 1.10 2014/02/11 18:34:48 sjg Exp $
|
||||
# $Id: options.mk,v 1.11 2020/05/02 21:23:52 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2012, Simon J. Gerraty
|
||||
#
|
||||
@ -77,3 +77,4 @@ ${OPTION_PREFIX}${o:H} ?= no
|
||||
${OPTION_PREFIX}${o:H} ?= ${${OPTION_PREFIX}${o:T}}
|
||||
.endif
|
||||
.endfor
|
||||
.undef OPTIONS_DEFAULT_VALUES OPTIONS_DEFAULT_NO OPTIONS_DEFAULT_YES
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: sys.mk,v 1.46 2017/11/15 22:59:23 sjg Exp $
|
||||
# $Id: sys.mk,v 1.47 2020/04/17 21:08:17 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2003-2009, Simon J. Gerraty
|
||||
#
|
||||
@ -116,6 +116,10 @@ ROOT_GROUP != sed -n /:0:/s/:.*//p /etc/group
|
||||
|
||||
unix ?= We run ${_HOST_OSNAME}.
|
||||
|
||||
# We need a Bourne/POSIX shell
|
||||
MAKE_SHELL ?= sh
|
||||
SHELL ?= ${MAKE_SHELL}
|
||||
|
||||
# A race condition in mkdir, means that it can bail if another
|
||||
# process made a dir that mkdir expected to.
|
||||
# We repeat the mkdir -p a number of times to try and work around this.
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: sys.vars.mk,v 1.3 2018/02/06 00:51:53 sjg Exp $
|
||||
# $Id: sys.vars.mk,v 1.4 2019/05/27 20:22:52 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2003-2009, Simon J. Gerraty
|
||||
#
|
||||
@ -78,3 +78,8 @@ M_cmpv = S,., ,g:_:range:@i@+ $${_:[-$$i]} \* $${M_cmpv.units:[$$i]}@:S,^,expr 0
|
||||
|
||||
# absoulte path to what we are reading.
|
||||
_PARSEDIR = ${.PARSEDIR:${M_tA}}
|
||||
|
||||
# many projects use MAJOR MINOR PATCH versioning
|
||||
# ${OPENSSL:${M_M.M.P_VERSION}} is equivalent to
|
||||
# ${OPENSSL_MAJOR_VERSION}.${OPENSSL_MINOR_VERSION}.${OPENSSL_PATCH_VERSION}
|
||||
M_M.M.P_VERSION = L:@v@$${MAJOR MINOR PATCH:L:@t@$${$$v_$$t_VERSION:U0}@}@:ts.
|
||||
|
@ -72,8 +72,6 @@ PFLAGS=
|
||||
COMPILE.p= ${PC} ${PFLAGS} ${CPPFLAGS} -c
|
||||
LINK.p= ${PC} ${PFLAGS} ${CPPFLAGS} ${LDFLAGS}
|
||||
|
||||
SHELL= sh
|
||||
|
||||
YACC= yacc
|
||||
YFLAGS= -d
|
||||
YACC.y= ${YACC} ${YFLAGS}
|
||||
|
@ -4,7 +4,7 @@
|
||||
OS= Darwin
|
||||
unix?= We run ${OS}.
|
||||
|
||||
.SUFFIXES: .out .a .ln .o .s .S .c ${CXX_SUFFIXES} .F .f .r .y .l .cl .p .h
|
||||
.SUFFIXES: .out .a .ln .o .s .S .c .m ${CXX_SUFFIXES} .F .f .r .y .l .cl .p .h
|
||||
.SUFFIXES: .sh .m4 .dylib
|
||||
|
||||
.LIBS: .a .dylib
|
||||
@ -24,10 +24,15 @@ LINK.s?= ${CC} ${AFLAGS} ${LDFLAGS}
|
||||
COMPILE.S?= ${CC} ${AFLAGS} ${CPPFLAGS} -c
|
||||
LINK.S?= ${CC} ${AFLAGS} ${CPPFLAGS} ${LDFLAGS}
|
||||
|
||||
.if exists(/usr/bin/gcc)
|
||||
CC?= gcc -pipe
|
||||
PIPE?= -pipe
|
||||
|
||||
.if exists(/usr/bin/clang)
|
||||
CC?= cc ${PIPE}
|
||||
CXX?= c++
|
||||
.elif exists(/usr/bin/gcc)
|
||||
CC?= gcc ${PIPE}
|
||||
.else
|
||||
CC?= cc -pipe
|
||||
CC?= cc ${PIPE}
|
||||
.endif
|
||||
DBG?= -O2
|
||||
CFLAGS?= ${DBG}
|
||||
@ -52,7 +57,7 @@ CPP?= cpp
|
||||
NOLINT= 1
|
||||
CPPFLAGS?=
|
||||
|
||||
MK_DEP?= mkdeps.sh -N
|
||||
MK_DEP?= mkdep
|
||||
|
||||
FC?= f77
|
||||
FFLAGS?= -O
|
||||
@ -91,8 +96,6 @@ PFLAGS?=
|
||||
COMPILE.p?= ${PC} ${PFLAGS} ${CPPFLAGS} -c
|
||||
LINK.p?= ${PC} ${PFLAGS} ${CPPFLAGS} ${LDFLAGS}
|
||||
|
||||
SHELL?= sh
|
||||
|
||||
SIZE?= size
|
||||
|
||||
TSORT?= tsort -q
|
||||
@ -121,6 +124,16 @@ ${CXX_SUFFIXES:%=%.a}:
|
||||
${AR} ${ARFLAGS} $@ $*.o
|
||||
rm -f $*.o
|
||||
|
||||
# Objective-C
|
||||
.m:
|
||||
${LINK.m} -o ${.TARGET} ${.IMPSRC} ${LDLIBS}
|
||||
.m.o:
|
||||
${COMPILE.m} ${.IMPSRC}
|
||||
.m.a:
|
||||
${COMPILE.m} ${.IMPSRC}
|
||||
${AR} ${ARFLAGS} $@ $*.o
|
||||
rm -f $*.o
|
||||
|
||||
# Fortran/Ratfor
|
||||
.f:
|
||||
${LINK.f} -o ${.TARGET} ${.IMPSRC} ${LDLIBS}
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: Generic.mk,v 1.13 2017/05/05 18:02:16 sjg Exp $
|
||||
# $Id: Generic.mk,v 1.14 2020/04/17 21:08:17 sjg Exp $
|
||||
#
|
||||
|
||||
# some reasonable defaults
|
||||
@ -87,8 +87,6 @@ PFLAGS?=
|
||||
COMPILE.p?= ${PC} ${PFLAGS} ${CPPFLAGS} -c
|
||||
LINK.p?= ${PC} ${PFLAGS} ${CPPFLAGS} ${LDFLAGS}
|
||||
|
||||
SHELL?= sh
|
||||
|
||||
SIZE?= size
|
||||
|
||||
YACC?= yacc
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: HP-UX.mk,v 1.11 2017/05/05 18:02:16 sjg Exp $
|
||||
# $Id: HP-UX.mk,v 1.12 2020/04/17 21:08:17 sjg Exp $
|
||||
# $NetBSD: sys.mk,v 1.19.2.1 1994/07/26 19:58:31 cgd Exp $
|
||||
# @(#)sys.mk 5.11 (Berkeley) 3/13/91
|
||||
|
||||
@ -108,7 +108,7 @@ LINK.p= ${PC} ${PFLAGS} ${CPPFLAGS} ${LDFLAGS}
|
||||
|
||||
# HP's sh sucks
|
||||
ENV=
|
||||
SHELL= /bin/ksh
|
||||
MAKE_SHELL= /bin/ksh
|
||||
|
||||
.if exists(/usr/local/bin/bison)
|
||||
YACC= bison -y
|
||||
|
@ -77,8 +77,6 @@ PFLAGS?=
|
||||
COMPILE.p?= ${PC} ${PFLAGS} ${CPPFLAGS} -c
|
||||
LINK.p?= ${PC} ${PFLAGS} ${CPPFLAGS} ${LDFLAGS}
|
||||
|
||||
SHELL?= sh
|
||||
|
||||
SIZE?= size
|
||||
|
||||
TSORT?= tsort -q
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: Linux.mk,v 1.9 2017/05/05 18:02:16 sjg Exp $
|
||||
# $Id: Linux.mk,v 1.10 2020/04/17 21:08:17 sjg Exp $
|
||||
# $NetBSD: sys.mk,v 1.19.2.1 1994/07/26 19:58:31 cgd Exp $
|
||||
# @(#)sys.mk 5.11 (Berkeley) 3/13/91
|
||||
|
||||
@ -75,8 +75,6 @@ PFLAGS=
|
||||
COMPILE.p= ${PC} ${PFLAGS} ${CPPFLAGS} -c
|
||||
LINK.p= ${PC} ${PFLAGS} ${CPPFLAGS} ${LDFLAGS}
|
||||
|
||||
SHELL= sh
|
||||
|
||||
YACC= yacc
|
||||
YFLAGS= -d
|
||||
YACC.y= ${YACC} ${YFLAGS}
|
||||
|
@ -112,8 +112,6 @@ PFLAGS?=
|
||||
COMPILE.p?= ${PC} ${PFLAGS} ${CPPFLAGS} -c
|
||||
LINK.p?= ${PC} ${PFLAGS} ${CPPFLAGS} ${LDFLAGS}
|
||||
|
||||
SHELL?= sh
|
||||
|
||||
SIZE?= size
|
||||
|
||||
TSORT?= tsort -q
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: OSF1.mk,v 1.8 2017/05/05 18:02:16 sjg Exp $
|
||||
# $Id: OSF1.mk,v 1.9 2020/04/17 21:08:17 sjg Exp $
|
||||
# $NetBSD: sys.mk,v 1.19.2.1 1994/07/26 19:58:31 cgd Exp $
|
||||
# @(#)sys.mk 5.11 (Berkeley) 3/13/91
|
||||
|
||||
@ -82,8 +82,6 @@ PFLAGS=
|
||||
COMPILE.p= ${PC} ${PFLAGS} ${CPPFLAGS} -c
|
||||
LINK.p= ${PC} ${PFLAGS} ${CPPFLAGS} ${LDFLAGS}
|
||||
|
||||
SHELL= sh
|
||||
|
||||
.if exists(/usr/local/bin/bison) || exists(/opt/gnu/bin/bison)
|
||||
YACC= bison -y
|
||||
.else
|
||||
|
@ -87,8 +87,6 @@ PFLAGS?=
|
||||
COMPILE.p?= ${PC} ${PFLAGS} ${CPPFLAGS} -c
|
||||
LINK.p?= ${PC} ${PFLAGS} ${CPPFLAGS} ${LDFLAGS}
|
||||
|
||||
SHELL?= sh
|
||||
|
||||
SIZE?= size
|
||||
|
||||
TSORT?= tsort -q
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: SunOS.mk,v 1.8 2017/05/05 18:02:17 sjg Exp $
|
||||
# $Id: SunOS.mk,v 1.9 2020/04/17 21:08:17 sjg Exp $
|
||||
|
||||
.if ${.PARSEFILE} == "sys.mk"
|
||||
.include <host-target.mk>
|
||||
@ -103,8 +103,6 @@ PFLAGS=
|
||||
COMPILE.p= ${PC} ${PFLAGS} ${CPPFLAGS} -c
|
||||
LINK.p= ${PC} ${PFLAGS} ${CPPFLAGS} ${LDFLAGS}
|
||||
|
||||
SHELL= sh
|
||||
|
||||
.if exists(/usr/local/bin/bison) || exists(/opt/gnu/bin/bison)
|
||||
YACC= bison -y
|
||||
.else
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: UnixWare.mk,v 1.3 2017/05/05 18:02:17 sjg Exp $
|
||||
# $Id: UnixWare.mk,v 1.4 2020/04/17 21:08:17 sjg Exp $
|
||||
# based on "Id: SunOS.5.sys.mk,v 1.6 2003/09/30 16:42:23 sjg Exp "
|
||||
# $NetBSD: sys.mk,v 1.19.2.1 1994/07/26 19:58:31 cgd Exp $
|
||||
# @(#)sys.mk 5.11 (Berkeley) 3/13/91
|
||||
@ -121,8 +121,6 @@ PFLAGS?=
|
||||
COMPILE.p?= ${PC} ${PFLAGS} ${CPPFLAGS} -c
|
||||
LINK.p?= ${PC} ${PFLAGS} ${CPPFLAGS} ${LDFLAGS}
|
||||
|
||||
SHELL?= sh
|
||||
|
||||
SIZE?= size
|
||||
|
||||
TSORT?= tsort
|
||||
|
@ -1,6 +1,6 @@
|
||||
# $Id: whats.mk,v 1.3 2017/10/19 06:09:14 sjg Exp $
|
||||
# $Id: whats.mk,v 1.9 2020/05/09 19:48:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2014, Simon J. Gerraty
|
||||
# @(#) Copyright (c) 2014-2020, Simon J. Gerraty
|
||||
#
|
||||
# This file is provided in the hope that it will
|
||||
# be of use. There is absolutely NO WARRANTY.
|
||||
@ -13,25 +13,18 @@
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
||||
.if ${MK_WHATSTRING:Uno} != "no"
|
||||
what_build_exts?= o
|
||||
.if ${MK_WHATSTRING:Uno} == "yes"
|
||||
# it can be useful to embed a what(1) string in binaries
|
||||
# so that the build location can be seen from a core file.
|
||||
.if defined(PROG) && ${.MAKE.MAKEFILES:M*prog.mk} != ""
|
||||
what_thing?= ${PROGNAME:U${PROG}}
|
||||
what_build_thing?= ${PROG}
|
||||
.elif defined(LIB) && ${.MAKE.MAKEFILES:M*lib.mk} != ""
|
||||
# probably only makes sense for shared libs
|
||||
# and the plumbing needed varies depending on *lib.mk
|
||||
what_thing?= lib${LIB}
|
||||
.if !empty(SOBJS)
|
||||
_soe:= ${SOBJS:E:[1]}
|
||||
what_build_exts= ${_soe}
|
||||
SOBJS+= ${what_uuid}.${_soe}
|
||||
.endif
|
||||
.elif defined(KMOD) && ${.MAKE.MAKEFILES:M*kmod.mk} != ""
|
||||
what_thing?= ${KMOD}
|
||||
what_build_thing?= ${KMOD}.ko
|
||||
.if defined(KMOD)
|
||||
what_thing ?= ${KMOD}
|
||||
.elif defined(LIB)
|
||||
what_thing ?= lib${LIB}
|
||||
.elif defined(PROG)
|
||||
what_thing ?= ${PROG}
|
||||
SRCS ?= ${PROG}.c
|
||||
.elif defined(SHLIB)
|
||||
what_thing ?= lib${SHLIB}
|
||||
.endif
|
||||
|
||||
.if !empty(what_thing)
|
||||
@ -39,26 +32,38 @@ what_build_thing?= ${KMOD}.ko
|
||||
what_uuid = what_${what_thing}_${.CURDIR:T:hash}
|
||||
what_var = what_${.CURDIR:T:hash}
|
||||
|
||||
.if !empty(what_build_thing)
|
||||
${what_build_thing}: ${what_build_exts:@e@${what_uuid}.$e@}
|
||||
.endif
|
||||
OBJS+= ${what_uuid}.o
|
||||
CLEANFILES+= ${what_uuid}.c
|
||||
|
||||
SRCS += ${what_uuid}.c
|
||||
CLEANFILES += ${what_uuid}.c
|
||||
# we do not need to capture this
|
||||
SUPPRESS_DEPEND+= *${what_uuid}.c
|
||||
SUPPRESS_DEPEND += *${what_uuid}.c
|
||||
|
||||
SB?= ${SRCTOP:H}
|
||||
SB_LOCATION?= ${HOST}:${SB}
|
||||
what_location:= ${.OBJDIR:S,${SB},${SB_LOCATION},}
|
||||
SB ?= ${SRCTOP:H}
|
||||
SB_LOCATION ?= ${HOST}:${SB}
|
||||
# make customization easy
|
||||
WHAT_LOCATION ?= ${.OBJDIR:S,${SB},${SB_LOCATION},}
|
||||
WHAT_1 ?= ${what_thing:tu} built ${%Y%m%d:L:localtime} by ${USER}
|
||||
WHAT_2 ?= ${what_location}
|
||||
WHAT_LINE_IDS ?= 1 2
|
||||
WHAT_NOCMP_LINE_IDS ?= 1
|
||||
# you can add other WHAT_* just be sure to set WHAT_LINE_IDS
|
||||
# and WHAT_NOCMP_LINE_IDS accordingly
|
||||
|
||||
# this works with clang and gcc
|
||||
_what_t= const char __attribute__ ((section(".data")))
|
||||
_what1:= @(\#)${what_thing:tu} built ${%Y%m%d:L:localtime} by ${USER}
|
||||
_what2:= @(\#)${what_location}
|
||||
what_t = const char __attribute__ ((section(".data")))
|
||||
what_location := ${WHAT_LOCATION}
|
||||
|
||||
# this script is done in multiple lines so we can
|
||||
# use the token ${.OODATE:MNO_META_CMP}
|
||||
# to prevent the variable parts making this constantly out-of-date
|
||||
${what_uuid}.c:
|
||||
echo '${_what_t} ${what_var}1[] = "${_what1}";' > $@ ${.OODATE:MNO_META_CMP}
|
||||
echo '${_what_t} ${what_var}2[] = "${_what2}";' >> $@
|
||||
echo 'extern const char ${WHAT_LINE_IDS:@i@${what_var}_$i[]@:ts,};' > $@
|
||||
.for i in ${WHAT_LINE_IDS}
|
||||
.if ${WHAT_NOCMP_LINE_IDS:M$i} != ""
|
||||
echo '${what_t} ${what_var}_$i[] = "@(#)${WHAT_$i}";' >> $@ ${.OODATE:MNO_META_CMP}
|
||||
.else
|
||||
echo '${what_t} ${what_var}_$i[] = "@(#)${WHAT_$i}";' >> $@
|
||||
.endif
|
||||
.endfor
|
||||
|
||||
.endif
|
||||
.endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: nonints.h,v 1.74 2016/09/05 00:40:29 sevan Exp $ */
|
||||
/* $NetBSD: nonints.h,v 1.75 2020/04/25 18:20:57 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1988, 1989, 1990, 1993
|
||||
@ -140,8 +140,8 @@ char *str_concat(const char *, const char *, int);
|
||||
char **brk_string(const char *, int *, Boolean, char **);
|
||||
char *Str_FindSubstring(const char *, const char *);
|
||||
int Str_Match(const char *, const char *);
|
||||
char *Str_SYSVMatch(const char *, const char *, int *len);
|
||||
void Str_SYSVSubst(Buffer *, char *, char *, int);
|
||||
char *Str_SYSVMatch(const char *, const char *, size_t *, Boolean *);
|
||||
void Str_SYSVSubst(Buffer *, char *, char *, size_t, Boolean);
|
||||
|
||||
#ifndef HAVE_STRLCPY
|
||||
/* strlcpy.c */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: parse.c,v 1.231 2018/12/22 00:36:32 sjg Exp $ */
|
||||
/* $NetBSD: parse.c,v 1.233 2019/09/26 21:09:55 sjg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1993
|
||||
@ -69,14 +69,14 @@
|
||||
*/
|
||||
|
||||
#ifndef MAKE_NATIVE
|
||||
static char rcsid[] = "$NetBSD: parse.c,v 1.231 2018/12/22 00:36:32 sjg Exp $";
|
||||
static char rcsid[] = "$NetBSD: parse.c,v 1.233 2019/09/26 21:09:55 sjg Exp $";
|
||||
#else
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)parse.c 8.3 (Berkeley) 3/19/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: parse.c,v 1.231 2018/12/22 00:36:32 sjg Exp $");
|
||||
__RCSID("$NetBSD: parse.c,v 1.233 2019/09/26 21:09:55 sjg Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
@ -685,6 +685,7 @@ ParseVErrorInternal(FILE *f, const char *cfname, size_t clineno, int type,
|
||||
const char *fmt, va_list ap)
|
||||
{
|
||||
static Boolean fatal_warning_error_printed = FALSE;
|
||||
char dirbuf[MAXPATHLEN+1];
|
||||
|
||||
(void)fprintf(f, "%s: ", progname);
|
||||
|
||||
@ -703,9 +704,7 @@ ParseVErrorInternal(FILE *f, const char *cfname, size_t clineno, int type,
|
||||
if (dir == NULL)
|
||||
dir = ".";
|
||||
if (*dir != '/') {
|
||||
dir = cp2 = realpath(dir, NULL);
|
||||
free(cp);
|
||||
cp = cp2; /* cp2 set to NULL by Var_Value */
|
||||
dir = realpath(dir, dirbuf);
|
||||
}
|
||||
fname = Var_Value(".PARSEFILE", VAR_GLOBAL, &cp2);
|
||||
if (fname == NULL) {
|
||||
@ -1768,7 +1767,8 @@ ParseDoDependency(char *line)
|
||||
}
|
||||
|
||||
out:
|
||||
assert(paths == NULL);
|
||||
if (paths)
|
||||
Lst_Destroy(paths, NULL);
|
||||
if (curTargs)
|
||||
Lst_Destroy(curTargs, NULL);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: str.c,v 1.38 2017/04/21 22:15:44 sjg Exp $ */
|
||||
/* $NetBSD: str.c,v 1.42 2020/05/06 02:30:10 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1988, 1989, 1990, 1993
|
||||
@ -69,14 +69,14 @@
|
||||
*/
|
||||
|
||||
#ifndef MAKE_NATIVE
|
||||
static char rcsid[] = "$NetBSD: str.c,v 1.38 2017/04/21 22:15:44 sjg Exp $";
|
||||
static char rcsid[] = "$NetBSD: str.c,v 1.42 2020/05/06 02:30:10 christos Exp $";
|
||||
#else
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)str.c 5.8 (Berkeley) 6/1/90";
|
||||
#else
|
||||
__RCSID("$NetBSD: str.c,v 1.38 2017/04/21 22:15:44 sjg Exp $");
|
||||
__RCSID("$NetBSD: str.c,v 1.42 2020/05/06 02:30:10 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
@ -133,42 +133,43 @@ str_concat(const char *s1, const char *s2, int flags)
|
||||
*
|
||||
* returns --
|
||||
* Pointer to the array of pointers to the words.
|
||||
* Memory containing the actual words in *buffer.
|
||||
* Memory containing the actual words in *store_words_buf.
|
||||
* Both of these must be free'd by the caller.
|
||||
* Number of words in *store_argc.
|
||||
* Number of words in *store_words_len.
|
||||
*/
|
||||
char **
|
||||
brk_string(const char *str, int *store_argc, Boolean expand, char **buffer)
|
||||
brk_string(const char *str, int *store_words_len, Boolean expand,
|
||||
char **store_words_buf)
|
||||
{
|
||||
int argc, ch;
|
||||
char inquote, *start, *t;
|
||||
const char *p;
|
||||
int len;
|
||||
int argmax = 50, curlen = 0;
|
||||
char **argv;
|
||||
char inquote;
|
||||
const char *str_p;
|
||||
size_t str_len;
|
||||
char **words;
|
||||
int words_len;
|
||||
int words_cap = 50;
|
||||
char *words_buf, *word_start, *word_end;
|
||||
|
||||
/* skip leading space chars. */
|
||||
for (; *str == ' ' || *str == '\t'; ++str)
|
||||
continue;
|
||||
|
||||
/* allocate room for a copy of the string */
|
||||
if ((len = strlen(str) + 1) > curlen)
|
||||
*buffer = bmake_malloc(curlen = len);
|
||||
/* words_buf holds the words, separated by '\0'. */
|
||||
str_len = strlen(str);
|
||||
words_buf = bmake_malloc(strlen(str) + 1);
|
||||
|
||||
/*
|
||||
* initial argmax based on len
|
||||
*/
|
||||
argmax = MAX((len / 5), 50);
|
||||
argv = bmake_malloc((argmax + 1) * sizeof(char *));
|
||||
words_cap = MAX((str_len / 5), 50);
|
||||
words = bmake_malloc((words_cap + 1) * sizeof(char *));
|
||||
|
||||
/*
|
||||
* copy the string; at the same time, parse backslashes,
|
||||
* quotes and build the argument list.
|
||||
* quotes and build the word list.
|
||||
*/
|
||||
argc = 0;
|
||||
words_len = 0;
|
||||
inquote = '\0';
|
||||
for (p = str, start = t = *buffer;; ++p) {
|
||||
switch(ch = *p) {
|
||||
word_start = word_end = words_buf;
|
||||
for (str_p = str;; ++str_p) {
|
||||
char ch = *str_p;
|
||||
switch(ch) {
|
||||
case '"':
|
||||
case '\'':
|
||||
if (inquote) {
|
||||
@ -180,21 +181,21 @@ brk_string(const char *str, int *store_argc, Boolean expand, char **buffer)
|
||||
else {
|
||||
inquote = (char) ch;
|
||||
/* Don't miss "" or '' */
|
||||
if (start == NULL && p[1] == inquote) {
|
||||
if (word_start == NULL && str_p[1] == inquote) {
|
||||
if (!expand) {
|
||||
start = t;
|
||||
*t++ = ch;
|
||||
word_start = word_end;
|
||||
*word_end++ = ch;
|
||||
} else
|
||||
start = t + 1;
|
||||
p++;
|
||||
word_start = word_end + 1;
|
||||
str_p++;
|
||||
inquote = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!expand) {
|
||||
if (!start)
|
||||
start = t;
|
||||
*t++ = ch;
|
||||
if (word_start == NULL)
|
||||
word_start = word_end;
|
||||
*word_end++ = ch;
|
||||
}
|
||||
continue;
|
||||
case ' ':
|
||||
@ -202,30 +203,30 @@ brk_string(const char *str, int *store_argc, Boolean expand, char **buffer)
|
||||
case '\n':
|
||||
if (inquote)
|
||||
break;
|
||||
if (!start)
|
||||
if (word_start == NULL)
|
||||
continue;
|
||||
/* FALLTHROUGH */
|
||||
case '\0':
|
||||
/*
|
||||
* end of a token -- make sure there's enough argv
|
||||
* end of a token -- make sure there's enough words
|
||||
* space and save off a pointer.
|
||||
*/
|
||||
if (!start)
|
||||
if (word_start == NULL)
|
||||
goto done;
|
||||
|
||||
*t++ = '\0';
|
||||
if (argc == argmax) {
|
||||
argmax *= 2; /* ramp up fast */
|
||||
argv = (char **)bmake_realloc(argv,
|
||||
(argmax + 1) * sizeof(char *));
|
||||
*word_end++ = '\0';
|
||||
if (words_len == words_cap) {
|
||||
words_cap *= 2; /* ramp up fast */
|
||||
words = (char **)bmake_realloc(words,
|
||||
(words_cap + 1) * sizeof(char *));
|
||||
}
|
||||
argv[argc++] = start;
|
||||
start = NULL;
|
||||
words[words_len++] = word_start;
|
||||
word_start = NULL;
|
||||
if (ch == '\n' || ch == '\0') {
|
||||
if (expand && inquote) {
|
||||
free(argv);
|
||||
free(*buffer);
|
||||
*buffer = NULL;
|
||||
free(words);
|
||||
free(words_buf);
|
||||
*store_words_buf = NULL;
|
||||
return NULL;
|
||||
}
|
||||
goto done;
|
||||
@ -233,21 +234,22 @@ brk_string(const char *str, int *store_argc, Boolean expand, char **buffer)
|
||||
continue;
|
||||
case '\\':
|
||||
if (!expand) {
|
||||
if (!start)
|
||||
start = t;
|
||||
*t++ = '\\';
|
||||
if (*(p+1) == '\0') /* catch '\' at end of line */
|
||||
if (word_start == NULL)
|
||||
word_start = word_end;
|
||||
*word_end++ = '\\';
|
||||
/* catch '\' at end of line */
|
||||
if (str_p[1] == '\0')
|
||||
continue;
|
||||
ch = *++p;
|
||||
ch = *++str_p;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ch = *++p) {
|
||||
switch (ch = *++str_p) {
|
||||
case '\0':
|
||||
case '\n':
|
||||
/* hmmm; fix it up as best we can */
|
||||
ch = '\\';
|
||||
--p;
|
||||
--str_p;
|
||||
break;
|
||||
case 'b':
|
||||
ch = '\b';
|
||||
@ -267,13 +269,14 @@ brk_string(const char *str, int *store_argc, Boolean expand, char **buffer)
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!start)
|
||||
start = t;
|
||||
*t++ = (char) ch;
|
||||
if (word_start == NULL)
|
||||
word_start = word_end;
|
||||
*word_end++ = ch;
|
||||
}
|
||||
done: argv[argc] = NULL;
|
||||
*store_argc = argc;
|
||||
return(argv);
|
||||
done: words[words_len] = NULL;
|
||||
*store_words_len = words_len;
|
||||
*store_words_buf = words_buf;
|
||||
return words;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -407,6 +410,8 @@ Str_Match(const char *string, const char *pattern)
|
||||
return 0;
|
||||
while ((*pattern != ']') && (*pattern != 0))
|
||||
++pattern;
|
||||
if (*pattern == 0)
|
||||
--pattern;
|
||||
goto thisCharOK;
|
||||
}
|
||||
/*
|
||||
@ -450,12 +455,14 @@ thisCharOK: ++pattern;
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
char *
|
||||
Str_SYSVMatch(const char *word, const char *pattern, int *len)
|
||||
Str_SYSVMatch(const char *word, const char *pattern, size_t *len,
|
||||
Boolean *hasPercent)
|
||||
{
|
||||
const char *p = pattern;
|
||||
const char *w = word;
|
||||
const char *m;
|
||||
|
||||
*hasPercent = FALSE;
|
||||
if (*p == '\0') {
|
||||
/* Null pattern is the whole string */
|
||||
*len = strlen(w);
|
||||
@ -463,6 +470,11 @@ Str_SYSVMatch(const char *word, const char *pattern, int *len)
|
||||
}
|
||||
|
||||
if ((m = strchr(p, '%')) != NULL) {
|
||||
*hasPercent = TRUE;
|
||||
if (*w == '\0') {
|
||||
/* empty word does not match pattern */
|
||||
return NULL;
|
||||
}
|
||||
/* check that the prefix matches */
|
||||
for (; p != m && *w && *w == *p; w++, p++)
|
||||
continue;
|
||||
@ -507,19 +519,21 @@ Str_SYSVMatch(const char *word, const char *pattern, int *len)
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
void
|
||||
Str_SYSVSubst(Buffer *buf, char *pat, char *src, int len)
|
||||
Str_SYSVSubst(Buffer *buf, char *pat, char *src, size_t len,
|
||||
Boolean lhsHasPercent)
|
||||
{
|
||||
char *m;
|
||||
|
||||
if ((m = strchr(pat, '%')) != NULL) {
|
||||
if ((m = strchr(pat, '%')) != NULL && lhsHasPercent) {
|
||||
/* Copy the prefix */
|
||||
Buf_AddBytes(buf, m - pat, pat);
|
||||
/* skip the % */
|
||||
pat = m + 1;
|
||||
}
|
||||
|
||||
/* Copy the pattern */
|
||||
Buf_AddBytes(buf, len, src);
|
||||
if (m != NULL || !lhsHasPercent) {
|
||||
/* Copy the pattern */
|
||||
Buf_AddBytes(buf, len, src);
|
||||
}
|
||||
|
||||
/* append the rest */
|
||||
Buf_AddBytes(buf, strlen(pat), pat);
|
||||
|
@ -1,6 +1,6 @@
|
||||
# $Id: Makefile.in,v 1.49 2018/09/21 21:39:05 sjg Exp $
|
||||
# $Id: Makefile,v 1.54 2020/05/17 17:26:14 sjg Exp $
|
||||
#
|
||||
# $NetBSD: Makefile,v 1.53 2018/05/24 00:25:44 christos Exp $
|
||||
# $NetBSD: Makefile,v 1.58 2020/05/17 12:36:26 rillig Exp $
|
||||
#
|
||||
# Unit tests for make(1)
|
||||
# The main targets are:
|
||||
@ -15,28 +15,31 @@
|
||||
# and it should be added to the TESTNAMES list.
|
||||
#
|
||||
|
||||
srcdir= @srcdir@
|
||||
|
||||
.MAIN: all
|
||||
|
||||
UNIT_TESTS:= ${srcdir}
|
||||
.-include "Makefile.config"
|
||||
|
||||
UNIT_TESTS:= ${.PARSEDIR}
|
||||
.PATH: ${UNIT_TESTS}
|
||||
|
||||
# Each test is in a sub-makefile.
|
||||
# Keep the list sorted.
|
||||
TESTNAMES= \
|
||||
comment \
|
||||
cond-late \
|
||||
cond1 \
|
||||
cond2 \
|
||||
dollar \
|
||||
doterror \
|
||||
dotwait \
|
||||
error \
|
||||
export \
|
||||
export-all \
|
||||
export-env \
|
||||
doterror \
|
||||
dotwait \
|
||||
forloop \
|
||||
forsubst \
|
||||
hash \
|
||||
include-main \
|
||||
misc \
|
||||
moderrs \
|
||||
modmatch \
|
||||
@ -54,6 +57,7 @@ TESTNAMES= \
|
||||
unexport-env \
|
||||
varcmd \
|
||||
varmisc \
|
||||
varmod-edge \
|
||||
varquote \
|
||||
varshell
|
||||
|
||||
@ -88,7 +92,6 @@ TEST_MAKE?= ${.MAKE}
|
||||
TOOL_SED?= sed
|
||||
TOOL_TR?= tr
|
||||
TOOL_DIFF?= diff
|
||||
DIFF_FLAGS?= @diff_u@
|
||||
|
||||
.if defined(.PARSEDIR)
|
||||
# ensure consistent results from sort(1)
|
4
contrib/bmake/unit-tests/Makefile.config.in
Normal file
4
contrib/bmake/unit-tests/Makefile.config.in
Normal file
@ -0,0 +1,4 @@
|
||||
# $Id: Makefile.config.in,v 1.1 2018/12/30 17:14:24 sjg Exp $
|
||||
|
||||
srcdir= @srcdir@
|
||||
DIFF_FLAGS?= @diff_u@
|
3
contrib/bmake/unit-tests/cond-late.exp
Normal file
3
contrib/bmake/unit-tests/cond-late.exp
Normal file
@ -0,0 +1,3 @@
|
||||
yes
|
||||
no
|
||||
exit status 0
|
23
contrib/bmake/unit-tests/cond-late.mk
Normal file
23
contrib/bmake/unit-tests/cond-late.mk
Normal file
@ -0,0 +1,23 @@
|
||||
# $NetBSD: cond-late.mk,v 1.1 2020/04/29 23:15:21 rillig Exp $
|
||||
#
|
||||
# Using the :? modifier, variable expressions can contain conditional
|
||||
# expressions that are evaluated late. Any variables appearing in these
|
||||
# conditions are expanded before parsing the condition. This is
|
||||
# different from many other places.
|
||||
#
|
||||
# Because of this, variables that are used in these lazy conditions
|
||||
# should not contain double-quotes, or the parser will probably fail.
|
||||
#
|
||||
# They should also not contain operators like == or <, since these are
|
||||
# actually interpreted as these operators. This is demonstrated below.
|
||||
#
|
||||
# If the order of evaluation were to change to first parse the condition
|
||||
# and then expand the variables, the output would change from the
|
||||
# current "yes no" to "yes yes", since both variables are non-empty.
|
||||
|
||||
COND.true= "yes" == "yes"
|
||||
COND.false= "yes" != "yes"
|
||||
|
||||
all:
|
||||
@echo ${ ${COND.true} :?yes:no}
|
||||
@echo ${ ${COND.false} :?yes:no}
|
51
contrib/bmake/unit-tests/dollar.exp
Normal file
51
contrib/bmake/unit-tests/dollar.exp
Normal file
@ -0,0 +1,51 @@
|
||||
|
||||
Printing dollar from literals and variables
|
||||
|
||||
To survive the parser, a dollar character must be doubled.
|
||||
1 dollar literal => <single-quote-var-value>
|
||||
1 dollar literal eol => <>
|
||||
2 dollar literal => <$>
|
||||
4 dollar literal => <$$>
|
||||
Some hungry part of make eats all the dollars after a :U modifier.
|
||||
1 dollar default => <>
|
||||
2 dollar default => <>
|
||||
4 dollar default => <>
|
||||
This works as expected.
|
||||
1 dollar variable => <>
|
||||
2 dollar variable => <$>
|
||||
4 dollar variable => <$$>
|
||||
Some hungry part of make eats all the dollars after a :U modifier.
|
||||
1 dollar var-default => <>
|
||||
2 dollar var-default => <$>
|
||||
4 dollar var-default => <$$>
|
||||
|
||||
Dollar in :S pattern
|
||||
|
||||
S,$,word, => <$XYword>
|
||||
S,$X,word, => <$XY>
|
||||
S,$$X,word, => <$XY>
|
||||
S,$$$X,word, => <$XY>
|
||||
S,$X,replaced, => <replaced>
|
||||
S,$$X,replaced, => <replaced>
|
||||
S,$$$X,replaced, => <replaced>
|
||||
|
||||
Dollar in :C character class
|
||||
|
||||
The A is replaced because the $$ is reduced to a single $,
|
||||
which is then resolved to the variable X with the value VAR_X.
|
||||
The effective character class becomes [VAR_XY].
|
||||
C,[$$XY],<&>,g => <$<A><X><Y>>
|
||||
|
||||
Dollar in :C pattern
|
||||
|
||||
For some reason, multiple dollars are folded into one.
|
||||
C,$,dollar,g => <>
|
||||
C,$$,dollar,g => <>
|
||||
|
||||
Dollar in :S replacement
|
||||
|
||||
For some reason, multiple dollars are folded into one.
|
||||
S,word,a$Xo, => <aVAR_Xo>
|
||||
S,word,a$$Xo, => <aVAR_Xo>
|
||||
S,word,a$$$Xo, => <aVAR_Xo>
|
||||
exit status 0
|
81
contrib/bmake/unit-tests/dollar.mk
Normal file
81
contrib/bmake/unit-tests/dollar.mk
Normal file
@ -0,0 +1,81 @@
|
||||
# $NetBSD: dollar.mk,v 1.3 2020/05/17 09:37:48 rillig Exp $
|
||||
#
|
||||
# Test the various places where a dollar character can appear and
|
||||
# see what happens. There are lots of surprises here.
|
||||
#
|
||||
|
||||
LIST= plain 'single' "double" 'mix'"ed" back\ slashed
|
||||
WORD= word
|
||||
|
||||
DOLLAR1= $
|
||||
DOLLAR2= $$
|
||||
DOLLAR4= $$$$
|
||||
|
||||
X= VAR_X
|
||||
DOLLAR_XY= $$XY
|
||||
DOLLAR_AXY= $$AXY
|
||||
|
||||
H= @header() { printf '\n%s\n\n' "$$*"; }; header
|
||||
T= @testcase() { printf '%23s => <%s>\n' "$$@"; }; testcase
|
||||
C= @comment() { printf '%s\n' "$$*"; }; comment
|
||||
|
||||
# These variable values are not accessed.
|
||||
# The trailing dollar in the '1 dollar literal eol' test case accesses
|
||||
# the empty variable instead, which is always guaranteed to be empty.
|
||||
${:U }= space-var-value
|
||||
${:U${.newline}}= newline-var-value
|
||||
# But this one is accessed.
|
||||
${:U'}= single-quote-var-value'
|
||||
|
||||
all:
|
||||
$H 'Printing dollar from literals and variables'
|
||||
|
||||
$C 'To survive the parser, a dollar character must be doubled.'
|
||||
$T '1 dollar literal' '$'
|
||||
$T '1 dollar literal eol' ''$
|
||||
$T '2 dollar literal' '$$'
|
||||
$T '4 dollar literal' '$$$$'
|
||||
|
||||
$C 'Some hungry part of make eats all the dollars after a :U modifier.'
|
||||
$T '1 dollar default' ''${:U$:Q}
|
||||
$T '2 dollar default' ''${:U$$:Q}
|
||||
$T '4 dollar default' ''${:U$$$$:Q}
|
||||
|
||||
$C 'This works as expected.'
|
||||
$T '1 dollar variable' ''${DOLLAR1:Q}
|
||||
$T '2 dollar variable' ''${DOLLAR2:Q}
|
||||
$T '4 dollar variable' ''${DOLLAR4:Q}
|
||||
|
||||
$C 'Some hungry part of make eats all the dollars after a :U modifier.'
|
||||
$T '1 dollar var-default' ''${:U${DOLLAR1}:Q}
|
||||
$T '2 dollar var-default' ''${:U${DOLLAR2}:Q}
|
||||
$T '4 dollar var-default' ''${:U${DOLLAR4}:Q}
|
||||
|
||||
$H 'Dollar in :S pattern'
|
||||
|
||||
$T 'S,$$,word,' ''${DOLLAR_XY:S,$,word,:Q}
|
||||
$T 'S,$$X,word,' ''${DOLLAR_XY:S,$X,word,:Q}
|
||||
$T 'S,$$$$X,word,' ''${DOLLAR_XY:S,$$X,word,:Q}
|
||||
$T 'S,$$$$$$X,word,' ''${DOLLAR_XY:S,$$$X,word,:Q}
|
||||
|
||||
$T 'S,$$X,replaced,' ''${X:S,$X,replaced,:Q}
|
||||
$T 'S,$$$$X,replaced,' ''${X:S,$$X,replaced,:Q}
|
||||
$T 'S,$$$$$$X,replaced,' ''${X:S,$$$X,replaced,:Q}
|
||||
|
||||
$H 'Dollar in :C character class'
|
||||
|
||||
$C 'The A is replaced because the $$$$ is reduced to a single $$,'
|
||||
$C 'which is then resolved to the variable X with the value VAR_X.'
|
||||
$C 'The effective character class becomes [VAR_XY].'
|
||||
$T 'C,[$$$$XY],<&>,g' ''${DOLLAR_AXY:C,[$$XY],<&>,g:Q}
|
||||
|
||||
$H 'Dollar in :C pattern'
|
||||
$C 'For some reason, multiple dollars are folded into one.'
|
||||
$T 'C,$$,dollar,g' ''${DOLLAR:C,$,dollar,g:Q}
|
||||
$T 'C,$$$$,dollar,g' ''${DOLLAR:C,$$,dollar,g:Q}
|
||||
|
||||
$H 'Dollar in :S replacement'
|
||||
$C 'For some reason, multiple dollars are folded into one.'
|
||||
$T 'S,word,a$$Xo,' ''${WORD:S,word,a$Xo,:Q}
|
||||
$T 'S,word,a$$$$Xo,' ''${WORD:S,word,a$$Xo,:Q}
|
||||
$T 'S,word,a$$$$$$Xo,' ''${WORD:S,word,a$$$Xo,:Q}
|
@ -1,4 +1,4 @@
|
||||
# $Id: escape.mk,v 1.1.1.2 2014/11/06 01:40:37 sjg Exp $
|
||||
# $Id: escape.mk,v 1.1.1.3 2020/01/22 01:07:14 sjg Exp $
|
||||
#
|
||||
# Test backslash escaping.
|
||||
|
||||
@ -35,8 +35,8 @@
|
||||
# Also, our practice is that an even number of backslashes before a
|
||||
# newline in a variable assignment simply stores the backslashes as part
|
||||
# of the value, and treats the newline as though it was not escaped.
|
||||
# Similarly, ann even number of backslashes before a newline in a
|
||||
# command simply uses the backslashes as part of the command test, but
|
||||
# Similarly, an even number of backslashes before a newline in a
|
||||
# command simply uses the backslashes as part of the command, but
|
||||
# does not escape the newline. This is compatible with GNU make.
|
||||
|
||||
all: .PHONY
|
||||
|
@ -7,12 +7,13 @@ x=-I"This or that"
|
||||
x=-Ithat
|
||||
x="-DTHIS=\"this and that\""
|
||||
cfl=-I/this -I"This or that" -Ithat "-DTHIS=\"this and that\""
|
||||
newline-item=(a)
|
||||
a=one b="two and three"
|
||||
a=four b="five"
|
||||
a=ONE b="TWO AND THREE"
|
||||
a=FOUR b="FIVE"
|
||||
We expect an error next:
|
||||
make: "forloop.mk" line 38: Wrong number of words (9) in .for substitution list with 2 vars
|
||||
make: "forloop.mk" line 46: Wrong number of words (9) in .for substitution list with 2 vars
|
||||
make: Fatal errors encountered -- cannot continue
|
||||
make: stopped in unit-tests
|
||||
OK
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: forloop.mk,v 1.1.1.1 2014/08/30 18:57:18 sjg Exp $
|
||||
# $Id: forloop.mk,v 1.1.1.2 2020/05/05 00:54:40 sjg Exp $
|
||||
|
||||
all: for-loop
|
||||
|
||||
@ -33,7 +33,15 @@ X!= echo 'cfl=${cfl}' >&2; echo
|
||||
.for a b in ${EMPTY}
|
||||
X!= echo 'a=$a b=$b' >&2; echo
|
||||
.endfor
|
||||
.endif
|
||||
|
||||
# Since at least 1993, iteration stops at the first newline.
|
||||
# Back then, the .newline variable didn't exist, therefore it was unlikely
|
||||
# that a newline ever occured.
|
||||
.for var in a${.newline}b${.newline}c
|
||||
X!= echo 'newline-item=('${var:Q}')' 1>&2; echo
|
||||
.endfor
|
||||
|
||||
.endif # for-fail
|
||||
|
||||
.for a b in ${LIST} ${LIST:tu} ${XTRA_LIST}
|
||||
X!= echo 'a=$a b=$b' >&2; echo
|
||||
|
6
contrib/bmake/unit-tests/include-main.exp
Normal file
6
contrib/bmake/unit-tests/include-main.exp
Normal file
@ -0,0 +1,6 @@
|
||||
main-before-ok
|
||||
sub-before-ok
|
||||
subsub-ok
|
||||
sub-after-fail(include-sub.mk)
|
||||
main-after-fail(include-sub.mk)
|
||||
exit status 0
|
30
contrib/bmake/unit-tests/include-main.mk
Normal file
30
contrib/bmake/unit-tests/include-main.mk
Normal file
@ -0,0 +1,30 @@
|
||||
# $NetBSD: include-main.mk,v 1.1 2020/05/17 12:36:26 rillig Exp $
|
||||
#
|
||||
# Demonstrates that the .INCLUDEDFROMFILE magic variable does not behave
|
||||
# as described in the manual page.
|
||||
#
|
||||
# The manual page says that it is the "filename of the file this Makefile
|
||||
# was included from", while in reality it is the "filename in which the
|
||||
# latest .include happened".
|
||||
#
|
||||
|
||||
.if !defined(.INCLUDEDFROMFILE)
|
||||
LOG+= main-before-ok
|
||||
.else
|
||||
. for f in ${.INCLUDEDFROMFILE}
|
||||
LOG+= main-before-fail\(${f:Q}\)
|
||||
. endfor
|
||||
.endif
|
||||
|
||||
.include "include-sub.mk"
|
||||
|
||||
.if !defined(.INCLUDEDFROMFILE)
|
||||
LOG+= main-after-ok
|
||||
.else
|
||||
. for f in ${.INCLUDEDFROMFILE}
|
||||
LOG+= main-after-fail\(${f:Q}\)
|
||||
. endfor
|
||||
.endif
|
||||
|
||||
all:
|
||||
@printf '%s\n' ${LOG}
|
17
contrib/bmake/unit-tests/include-sub.mk
Normal file
17
contrib/bmake/unit-tests/include-sub.mk
Normal file
@ -0,0 +1,17 @@
|
||||
# $NetBSD: include-sub.mk,v 1.1 2020/05/17 12:36:26 rillig Exp $
|
||||
|
||||
.if ${.INCLUDEDFROMFILE} == "include-main.mk"
|
||||
LOG+= sub-before-ok
|
||||
.else
|
||||
LOG+= sub-before-fail
|
||||
.endif
|
||||
|
||||
.include "include-subsub.mk"
|
||||
|
||||
.if ${.INCLUDEDFROMFILE} == "include-main.mk"
|
||||
LOG+= sub-after-ok
|
||||
.else
|
||||
. for f in ${.INCLUDEDFROMFILE}
|
||||
LOG+= sub-after-fail\(${f:Q}\)
|
||||
. endfor
|
||||
.endif
|
7
contrib/bmake/unit-tests/include-subsub.mk
Normal file
7
contrib/bmake/unit-tests/include-subsub.mk
Normal file
@ -0,0 +1,7 @@
|
||||
# $NetBSD: include-subsub.mk,v 1.1 2020/05/17 12:36:26 rillig Exp $
|
||||
|
||||
.if ${.INCLUDEDFROMFILE:T} == "include-sub.mk"
|
||||
LOG+= subsub-ok
|
||||
.else
|
||||
LOG+= subsub-fail
|
||||
.endif
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: modorder.mk,v 1.1 2014/08/21 13:44:51 apb Exp $
|
||||
# $NetBSD: modorder.mk,v 1.2 2020/01/07 22:42:14 rillig Exp $
|
||||
|
||||
LIST= one two three four five six seven eight nine ten
|
||||
LISTX= ${LIST:Ox}
|
||||
@ -12,8 +12,9 @@ all:
|
||||
@echo "LIST:O = ${LIST:O}"
|
||||
# Note that 1 in every 10! trials two independently generated
|
||||
# randomized orderings will be the same. The test framework doesn't
|
||||
# support checking probabilistic output, so we accept that the test
|
||||
# will incorrectly fail with probability 2.8E-7.
|
||||
# support checking probabilistic output, so we accept that each of the
|
||||
# 3 :Ox tests will incorrectly fail with probability 2.756E-7, which
|
||||
# lets the whole test fail once in 1.209.600 runs, on average.
|
||||
@echo "LIST:Ox = `test '${LIST:Ox}' != '${LIST:Ox}' ${TEST_RESULT}`"
|
||||
@echo "LIST:O:Ox = `test '${LIST:O:Ox}' != '${LIST:O:Ox}' ${TEST_RESULT}`"
|
||||
@echo "LISTX = `test '${LISTX}' != '${LISTX}' ${TEST_RESULT}`"
|
||||
|
@ -4,4 +4,12 @@ fun
|
||||
fun
|
||||
fun
|
||||
In the Sun
|
||||
acme
|
||||
aam.d
|
||||
sam.c
|
||||
a%.c
|
||||
asam.c.c
|
||||
asam.c
|
||||
a.c.c
|
||||
|
||||
exit status 0
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: sysv.mk,v 1.2 2014/08/30 22:25:14 sjg Exp $
|
||||
# $Id: sysv.mk,v 1.4 2020/05/07 01:17:51 sjg Exp $
|
||||
|
||||
FOO ?=
|
||||
FOOBAR = ${FOO:=bar}
|
||||
@ -11,7 +11,7 @@ FUN = ${B}${S}fun
|
||||
SUN = the Sun
|
||||
|
||||
# we expect nothing when FOO is empty
|
||||
all: foo fun
|
||||
all: foo fun sam bla
|
||||
|
||||
foo:
|
||||
@echo FOOBAR = ${FOOBAR}
|
||||
@ -24,3 +24,20 @@ fun:
|
||||
@echo ${FUN:${B}${S}fun=fun}
|
||||
@echo ${FUN:${B}${S}%=%}
|
||||
@echo ${In:L:%=% ${SUN}}
|
||||
|
||||
|
||||
SAM=sam.c
|
||||
|
||||
sam:
|
||||
@echo ${SAM:s%.c=acme}
|
||||
@echo ${SAM:s%.c=a%.d}
|
||||
@echo ${SAM:s.c=a%.d}
|
||||
@echo ${SAM:sam.c=a%.c}
|
||||
@echo ${SAM:%=a%.c}
|
||||
@echo ${SAM:%.c=a%.c}
|
||||
@echo ${SAM:sam%=a%.c}
|
||||
|
||||
BLA=
|
||||
|
||||
bla:
|
||||
@echo $(BLA:%=foo/%x)
|
||||
|
17
contrib/bmake/unit-tests/varmod-edge.exp
Normal file
17
contrib/bmake/unit-tests/varmod-edge.exp
Normal file
@ -0,0 +1,17 @@
|
||||
make: Unclosed variable specification (expecting '}') for "" (value "*)") modifier U
|
||||
make: Unclosed substitution for INP.eq-esc (= missing)
|
||||
ok M-paren
|
||||
ok M-mixed
|
||||
ok M-unescape
|
||||
ok M-nest-mix
|
||||
ok M-nest-brk
|
||||
ok M-pat-err
|
||||
ok M-bsbs
|
||||
ok M-bs1-par
|
||||
ok M-bs2-par
|
||||
ok M-128
|
||||
ok eq-ext
|
||||
ok eq-q
|
||||
ok eq-bs
|
||||
ok eq-esc
|
||||
exit status 0
|
162
contrib/bmake/unit-tests/varmod-edge.mk
Normal file
162
contrib/bmake/unit-tests/varmod-edge.mk
Normal file
@ -0,0 +1,162 @@
|
||||
# $NetBSD: varmod-edge.mk,v 1.7 2020/04/27 14:07:22 christos Exp $
|
||||
#
|
||||
# Tests for edge cases in variable modifiers.
|
||||
#
|
||||
# These tests demonstrate the current implementation in small examples.
|
||||
# They may contain surprising behavior.
|
||||
#
|
||||
# Each test consists of:
|
||||
# - INP, the input to the test
|
||||
# - MOD, the expression for testing the modifier
|
||||
# - EXP, the expected output
|
||||
|
||||
TESTS+= M-paren
|
||||
INP.M-paren= (parentheses) {braces} (opening closing) ()
|
||||
MOD.M-paren= ${INP.M-paren:M(*)}
|
||||
EXP.M-paren= (parentheses) ()
|
||||
|
||||
# The first closing brace matches the opening parenthesis.
|
||||
# The second closing brace actually ends the variable expression.
|
||||
#
|
||||
# XXX: This is unexpected but rarely occurs in practice.
|
||||
TESTS+= M-mixed
|
||||
INP.M-mixed= (paren-brace} (
|
||||
MOD.M-mixed= ${INP.M-mixed:M(*}}
|
||||
EXP.M-mixed= (paren-brace}
|
||||
|
||||
# After the :M modifier has parsed the pattern, only the closing brace
|
||||
# and the colon are unescaped. The other characters are left as-is.
|
||||
# To actually see this effect, the backslashes in the :M modifier need
|
||||
# to be doubled since single backslashes would simply be unescaped by
|
||||
# Str_Match.
|
||||
#
|
||||
# XXX: This is unexpected. The opening brace should also be unescaped.
|
||||
TESTS+= M-unescape
|
||||
INP.M-unescape= ({}): \(\{\}\)\: \(\{}\):
|
||||
MOD.M-unescape= ${INP.M-unescape:M\\(\\{\\}\\)\\:}
|
||||
EXP.M-unescape= \(\{}\):
|
||||
|
||||
# When the :M and :N modifiers are parsed, the pattern finishes as soon
|
||||
# as open_parens + open_braces == closing_parens + closing_braces. This
|
||||
# means that ( and } form a matching pair.
|
||||
#
|
||||
# Nested variable expressions are not parsed as such. Instead, only the
|
||||
# parentheses and braces are counted. This leads to a parse error since
|
||||
# the nested expression is not "${:U*)}" but only "${:U*)", which is
|
||||
# missing the closing brace. The expression is evaluated anyway.
|
||||
# The final brace in the output comes from the end of M.nest-mix.
|
||||
#
|
||||
# XXX: This is unexpected but rarely occurs in practice.
|
||||
TESTS+= M-nest-mix
|
||||
INP.M-nest-mix= (parentheses)
|
||||
MOD.M-nest-mix= ${INP.M-nest-mix:M${:U*)}}
|
||||
EXP.M-nest-mix= (parentheses)}
|
||||
# make: Unclosed variable specification (expecting '}') for "" (value "*)") modifier U
|
||||
|
||||
# In contrast to parentheses and braces, the brackets are not counted
|
||||
# when the :M modifier is parsed since Makefile variables only take the
|
||||
# ${VAR} or $(VAR) forms, but not $[VAR].
|
||||
#
|
||||
# The final ] in the pattern is needed to close the character class.
|
||||
TESTS+= M-nest-brk
|
||||
INP.M-nest-brk= [ [[ [[[
|
||||
MOD.M-nest-brk= ${INP.M-nest-brk:M${:U[[[[[]}}
|
||||
EXP.M-nest-brk= [
|
||||
|
||||
# The pattern in the nested variable has an unclosed character class.
|
||||
# No error is reported though, and the pattern is closed implicitly.
|
||||
#
|
||||
# XXX: It is unexpected that no error is reported.
|
||||
# See str.c, function Str_Match.
|
||||
#
|
||||
# Before 2019-12-02, this test case triggered an out-of-bounds read
|
||||
# in Str_Match.
|
||||
TESTS+= M-pat-err
|
||||
INP.M-pat-err= [ [[ [[[
|
||||
MOD.M-pat-err= ${INP.M-pat-err:M${:U[[}}
|
||||
EXP.M-pat-err= [
|
||||
|
||||
# The first backslash does not escape the second backslash.
|
||||
# Therefore, the second backslash escapes the parenthesis.
|
||||
# This means that the pattern ends there.
|
||||
# The final } in the output comes from the end of MOD.M-bsbs.
|
||||
#
|
||||
# If the first backslash were to escape the second backslash, the first
|
||||
# closing brace would match the opening parenthesis (see M-mixed), and
|
||||
# the second closing brace would be needed to close the variable.
|
||||
# After that, the remaining backslash would escape the parenthesis in
|
||||
# the pattern, therefore (} would match.
|
||||
TESTS+= M-bsbs
|
||||
INP.M-bsbs= (} \( \(}
|
||||
MOD.M-bsbs= ${INP.M-bsbs:M\\(}}
|
||||
EXP.M-bsbs= \(}
|
||||
#EXP.M-bsbs= (} # If the first backslash were to escape ...
|
||||
|
||||
# The backslash in \( does not escape the parenthesis, therefore it
|
||||
# counts for the nesting level and matches with the first closing brace.
|
||||
# The second closing brace closes the variable, and the third is copied
|
||||
# literally.
|
||||
#
|
||||
# The second :M in the pattern is nested between ( and }, therefore it
|
||||
# does not start a new modifier.
|
||||
TESTS+= M-bs1-par
|
||||
INP.M-bs1-par= ( (:M (:M} \( \(:M \(:M}
|
||||
MOD.M-bs1-par= ${INP.M-bs1-par:M\(:M*}}}
|
||||
EXP.M-bs1-par= (:M}}
|
||||
|
||||
# The double backslash is passed verbatim to the pattern matcher.
|
||||
# The Str_Match pattern is \\(:M*}, and there the backslash is unescaped.
|
||||
# Again, the ( takes place in the nesting level, and there is no way to
|
||||
# prevent this, no matter how many backslashes are used.
|
||||
TESTS+= M-bs2-par
|
||||
INP.M-bs2-par= ( (:M (:M} \( \(:M \(:M}
|
||||
MOD.M-bs2-par= ${INP.M-bs2-par:M\\(:M*}}}
|
||||
EXP.M-bs2-par= \(:M}}
|
||||
|
||||
# Str_Match uses a recursive algorithm for matching the * patterns.
|
||||
# Make sure that it survives patterns with 128 asterisks.
|
||||
# That should be enough for all practical purposes.
|
||||
# To produce a stack overflow, just add more :Qs below.
|
||||
TESTS+= M-128
|
||||
INP.M-128= ${:U\\:Q:Q:Q:Q:Q:Q:Q:S,\\,x,g}
|
||||
PAT.M-128= ${:U\\:Q:Q:Q:Q:Q:Q:Q:S,\\,*,g}
|
||||
MOD.M-128= ${INP.M-128:M${PAT.M-128}}
|
||||
EXP.M-128= ${INP.M-128}
|
||||
|
||||
# This is the normal SysV substitution. Nothing surprising here.
|
||||
TESTS+= eq-ext
|
||||
INP.eq-ext= file.c file.cc
|
||||
MOD.eq-ext= ${INP.eq-ext:%.c=%.o}
|
||||
EXP.eq-ext= file.o file.cc
|
||||
|
||||
# The SysV := modifier is greedy and consumes all the modifier text
|
||||
# up until the closing brace or parenthesis. The :Q may look like a
|
||||
# modifier, but it really isn't, that's why it appears in the output.
|
||||
TESTS+= eq-q
|
||||
INP.eq-q= file.c file.cc
|
||||
MOD.eq-q= ${INP.eq-q:%.c=%.o:Q}
|
||||
EXP.eq-q= file.o:Q file.cc
|
||||
|
||||
# The = in the := modifier can be escaped.
|
||||
TESTS+= eq-bs
|
||||
INP.eq-bs= file.c file.c=%.o
|
||||
MOD.eq-bs= ${INP.eq-bs:%.c\=%.o=%.ext}
|
||||
EXP.eq-bs= file.c file.ext
|
||||
|
||||
# Having only an escaped = results in a parse error.
|
||||
# The call to "pattern.lhs = VarGetPattern" fails.
|
||||
TESTS+= eq-esc
|
||||
INP.eq-esc= file.c file...
|
||||
MOD.eq-esc= ${INP.eq-esc:a\=b}
|
||||
EXP.eq-esc= # empty
|
||||
# make: Unclosed substitution for INP.eq-esc (= missing)
|
||||
|
||||
all:
|
||||
.for test in ${TESTS}
|
||||
. if ${MOD.${test}} == ${EXP.${test}}
|
||||
@printf 'ok %s\n' ${test:Q}''
|
||||
. else
|
||||
@printf 'error in %s: expected %s, got %s\n' \
|
||||
${test:Q}'' ${EXP.${test}:Q}'' ${MOD.${test}:Q}''
|
||||
. endif
|
||||
.endfor
|
@ -1,9 +1,9 @@
|
||||
/* $NetBSD: util.c,v 1.54 2013/11/26 13:44:41 joerg Exp $ */
|
||||
/* $NetBSD: util.c,v 1.55 2020/01/07 21:24:16 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Missing stuff from OS's
|
||||
*
|
||||
* $Id: util.c,v 1.33 2014/01/02 02:29:49 sjg Exp $
|
||||
* $Id: util.c,v 1.34 2020/01/22 01:19:25 sjg Exp $
|
||||
*/
|
||||
#if defined(__MINT__) || defined(__linux__)
|
||||
#include <signal.h>
|
||||
@ -12,10 +12,10 @@
|
||||
#include "make.h"
|
||||
|
||||
#ifndef MAKE_NATIVE
|
||||
static char rcsid[] = "$NetBSD: util.c,v 1.54 2013/11/26 13:44:41 joerg Exp $";
|
||||
static char rcsid[] = "$NetBSD: util.c,v 1.55 2020/01/07 21:24:16 rillig Exp $";
|
||||
#else
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: util.c,v 1.54 2013/11/26 13:44:41 joerg Exp $");
|
||||
__RCSID("$NetBSD: util.c,v 1.55 2020/01/07 21:24:16 rillig Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -229,32 +229,6 @@ killpg(int pid, int sig)
|
||||
return kill(-pid, sig);
|
||||
}
|
||||
|
||||
#if !defined(__hpux__) && !defined(__hpux)
|
||||
void
|
||||
srandom(long seed)
|
||||
{
|
||||
srand48(seed);
|
||||
}
|
||||
|
||||
long
|
||||
random(void)
|
||||
{
|
||||
return lrand48();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(__hpux__) && !defined(__hpux)
|
||||
int
|
||||
utimes(char *file, struct timeval tvp[2])
|
||||
{
|
||||
struct utimbuf t;
|
||||
|
||||
t.actime = tvp[0].tv_sec;
|
||||
t.modtime = tvp[1].tv_sec;
|
||||
return(utime(file, &t));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(BSD) && !defined(d_fileno)
|
||||
# define d_fileno d_ino
|
||||
#endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: var.c,v 1.221 2018/12/21 05:50:19 sjg Exp $ */
|
||||
/* $NetBSD: var.c,v 1.223 2020/04/25 18:20:57 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1993
|
||||
@ -69,14 +69,14 @@
|
||||
*/
|
||||
|
||||
#ifndef MAKE_NATIVE
|
||||
static char rcsid[] = "$NetBSD: var.c,v 1.221 2018/12/21 05:50:19 sjg Exp $";
|
||||
static char rcsid[] = "$NetBSD: var.c,v 1.223 2020/04/25 18:20:57 christos Exp $";
|
||||
#else
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: var.c,v 1.221 2018/12/21 05:50:19 sjg Exp $");
|
||||
__RCSID("$NetBSD: var.c,v 1.223 2020/04/25 18:20:57 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
@ -1401,8 +1401,9 @@ VarSYSVMatch(GNode *ctx, Var_Parse_State *vpstate,
|
||||
char *word, Boolean addSpace, Buffer *buf,
|
||||
void *patp)
|
||||
{
|
||||
int len;
|
||||
size_t len;
|
||||
char *ptr;
|
||||
Boolean hasPercent;
|
||||
VarPattern *pat = (VarPattern *)patp;
|
||||
char *varexp;
|
||||
|
||||
@ -1411,9 +1412,9 @@ VarSYSVMatch(GNode *ctx, Var_Parse_State *vpstate,
|
||||
|
||||
addSpace = TRUE;
|
||||
|
||||
if ((ptr = Str_SYSVMatch(word, pat->lhs, &len)) != NULL) {
|
||||
if ((ptr = Str_SYSVMatch(word, pat->lhs, &len, &hasPercent)) != NULL) {
|
||||
varexp = Var_Subst(NULL, pat->rhs, ctx, VARF_WANTRES);
|
||||
Str_SYSVSubst(buf, varexp, ptr, len);
|
||||
Str_SYSVSubst(buf, varexp, ptr, len, hasPercent);
|
||||
free(varexp);
|
||||
} else {
|
||||
Buf_AddBytes(buf, strlen(word), word);
|
||||
@ -2399,8 +2400,10 @@ VarHash(char *str)
|
||||
break;
|
||||
case 3:
|
||||
k |= (ustr[2] << 16);
|
||||
/* FALLTHROUGH */
|
||||
case 2:
|
||||
k |= (ustr[1] << 8);
|
||||
/* FALLTHROUGH */
|
||||
case 1:
|
||||
k |= ustr[0];
|
||||
len = 0;
|
||||
|
@ -3,8 +3,6 @@
|
||||
#
|
||||
# $FreeBSD$
|
||||
|
||||
.sinclude "Makefile.inc"
|
||||
|
||||
SRCTOP?= ${.CURDIR:H:H}
|
||||
|
||||
# look here first for config.h
|
||||
@ -14,7 +12,7 @@ CFLAGS+= -I${.CURDIR}
|
||||
CLEANDIRS+= FreeBSD
|
||||
CLEANFILES+= bootstrap
|
||||
|
||||
# $Id: Makefile,v 1.99 2017/08/13 20:12:53 sjg Exp $
|
||||
# $Id: Makefile,v 1.104 2020/02/06 01:33:54 sjg Exp $
|
||||
|
||||
PROG?= ${.CURDIR:T}
|
||||
|
||||
@ -71,6 +69,7 @@ SRCS+= \
|
||||
lstReplace.c \
|
||||
lstSucc.c
|
||||
|
||||
.sinclude "Makefile.inc"
|
||||
|
||||
# this file gets generated by configure
|
||||
.sinclude "Makefile.config"
|
||||
@ -93,10 +92,22 @@ CFLAGS+= ${COPTS.${.ALLSRC:M*.c:T:u}}
|
||||
COPTS.main.c+= "-DMAKE_VERSION=\"${_MAKE_VERSION}\""
|
||||
|
||||
# meta mode can be useful even without filemon
|
||||
# should be set by now
|
||||
USE_FILEMON ?= no
|
||||
.if ${USE_FILEMON:tl} != "no"
|
||||
.PATH: ${srcdir}/filemon
|
||||
SRCS+= filemon_${USE_FILEMON}.c
|
||||
COPTS.meta.c+= -DUSE_FILEMON -DUSE_FILEMON_${USE_FILEMON:tu}
|
||||
COPTS.job.c+= ${COPTS.meta.c}
|
||||
|
||||
.if ${USE_FILEMON} == "dev"
|
||||
FILEMON_H ?= /usr/include/dev/filemon/filemon.h
|
||||
.if exists(${FILEMON_H}) && ${FILEMON_H:T} == "filemon.h"
|
||||
COPTS.meta.c += -DHAVE_FILEMON_H -I${FILEMON_H:H}
|
||||
COPTS.filemon_dev.c += -DHAVE_FILEMON_H -I${FILEMON_H:H}
|
||||
.endif
|
||||
.endif # USE_FILEMON == dev
|
||||
|
||||
.endif # USE_FILEMON
|
||||
|
||||
.PATH: ${srcdir}
|
||||
.PATH: ${srcdir}/lst.lib
|
||||
|
@ -7,7 +7,7 @@ SRCTOP?= ${.CURDIR:H:H}
|
||||
|
||||
# things set by configure
|
||||
|
||||
_MAKE_VERSION?=20181221
|
||||
_MAKE_VERSION?=20200517
|
||||
|
||||
prefix?= /usr
|
||||
srcdir= ${SRCTOP}/contrib/bmake
|
||||
@ -19,7 +19,8 @@ CFLAGS+= ${CPPFLAGS} -DHAVE_CONFIG_H
|
||||
LDFLAGS+=
|
||||
LIBOBJS+= ${LIBOBJDIR}stresep$U.o
|
||||
LDADD+=
|
||||
USE_META= yes
|
||||
USE_META?= yes
|
||||
USE_FILEMON?= dev
|
||||
FILEMON_H?= /usr/include/dev/filemon/filemon.h
|
||||
BMAKE_PATH_MAX?= 1024
|
||||
# used if MAXPATHLEN not defined
|
||||
|
@ -2,7 +2,6 @@
|
||||
# Autogenerated - do NOT edit!
|
||||
|
||||
DIRDEPS = \
|
||||
gnu/lib/csu \
|
||||
include \
|
||||
include/xlocale \
|
||||
lib/${CSU_DIR} \
|
||||
|
@ -145,7 +145,7 @@
|
||||
/* Define to 1 if you have the `strtol' function. */
|
||||
#define HAVE_STRTOL 1
|
||||
|
||||
/* Define to 1 if `struct stat' is a member of `st_rdev'. */
|
||||
/* Define to 1 if `st_rdev' is a member of `struct stat'. */
|
||||
#define HAVE_STRUCT_STAT_ST_RDEV 1
|
||||
|
||||
/* Define to 1 if your `struct stat' has `st_rdev'. Deprecated, use
|
||||
@ -245,7 +245,7 @@
|
||||
#define PACKAGE_NAME "bmake"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "bmake 20171126"
|
||||
#define PACKAGE_STRING "bmake 20200418"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "bmake"
|
||||
@ -254,7 +254,7 @@
|
||||
#define PACKAGE_URL ""
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "20171126"
|
||||
#define PACKAGE_VERSION "20200418"
|
||||
|
||||
/* Define as the return type of signal handlers (`int' or `void'). */
|
||||
#define RETSIGTYPE void
|
||||
|
Loading…
Reference in New Issue
Block a user