Import bmake-20160606

From ChangeLog:

          o dir.c: extend mtimes cache to others via cached_stat()
This commit is contained in:
Simon J. Gerraty 2016-06-08 15:38:06 +00:00
parent e944e081cf
commit e6b08231c8
11 changed files with 167 additions and 91 deletions

View File

@ -1,3 +1,9 @@
2016-06-06 Simon J. Gerraty <sjg@bad.crufty.net>
* Makefile (_MAKE_VERSION): 20160606
Merge with NetBSD make, pick up
o dir.c: extend mtimes cache to others via cached_stat()
2016-06-04 Simon J. Gerraty <sjg@bad.crufty.net>
* Makefile (_MAKE_VERSION): 20160604

View File

@ -1,7 +1,7 @@
# $Id: Makefile,v 1.66 2016/06/04 22:21:15 sjg Exp $
# $Id: Makefile,v 1.67 2016/06/07 00:46:12 sjg Exp $
# Base version on src date
_MAKE_VERSION= 20160604
_MAKE_VERSION= 20160606
PROG= bmake

51
README
View File

@ -1,47 +1,52 @@
bmake
*****
This directory contains a port of the BSD make tool (from NetBSD)
I have run it on SunOS,Solaris,HP-UX,AIX,IRIX,FreeBSD and Linux.
This directory contains a port of the BSD make tool (from NetBSD).
Since 1993 I have run it on AIX, BSDi, Darwin, FreeBSD, HP-UX, IRIX,
Linux, Minix, OSF, Solaris, SunOS and even UTS.
Others have run it on many more systems.
Version 3 was re-worked from scratch to better facilitate
importing newer make(1) versions from NetBSD. The original code base
was NetBSD-1.0, so version 3 was built by doing a fresh import of the
NetBSD-1.0 usr.bin/make, adding the autoconf and other portability
patches to sync it with bmake v2, and then NetBSD's make
of Feb 20, 2000 was imported and conflicts dealt with.
NetBSD's make was again imported on June 6 and December 15, 2000.
Currently each release is tested on NetBSD, FreeBSD, Solaris and Linux.
In 2003 bmake switched to a date based version (first was 20030714)
Since 2003 bmake switched to a date based version (first was 20030714)
which generally represents the date it was last merged with NetBSD's
make. Since then, NetBSD's make is imported within a week of any
interesting changes, so that bmake tracks it very closely.
Building:
Building
========
The preferred way to bootstrap bmake is:
The preferred way to bootstrap bmake is::
./bmake/boot-strap
./bmake/boot-strap
there are a number of args - most of which get passed to configure,
eg.
::
./bmake/boot-strap --prefix=/opt
./bmake/boot-strap --prefix=/opt
see the boot-strap script for details.
For folk that hate to read anything, since 20121212 you can also use
the GNU standard process of::
./configure; make; make install
To make much use of bmake you will need the bsd.*.mk macros or my
portable *.mk macros. See
portable *.mk macros which are included with bmake since 20121212
and separately available from
http://www.crufty.net/ftp/pub/sjg/mk.tar.gz
which will be links to the latest versions.
On a non-BSD system, you would want to unpack mk[-YYYYmmdd].tar.gz in
the same directory as bmake (so ./mk and ./bmake exist), and
./bmake/boot-strap will do the rest.
Porting
=======
If you want to do it all by hand then read boot-strap first to get the
idea.
If you encounter a system that bmake does not build or work on *out of
the box*, I welcome patches.
If you can provide access to a suitable machine - even better.
Even if you have an earlier version of bmake installed, use boot-strap
to ensure that all goes well.
More info can be found at http://www.crufty.net/help/sjg/bmake.htm
--sjg <sjg@crufty.net>
--sjg

View File

@ -324,6 +324,9 @@
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
/* Define to `int' if <sys/types.h> does not define. */
#undef mode_t
/* Define to `long int' if <sys/types.h> does not define. */
#undef off_t

29
configure vendored
View File

@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.64 for bmake 20151022.
# Generated by GNU Autoconf 2.64 for bmake 20160606.
#
# Report bugs to <sjg@NetBSD.org>.
#
@ -549,8 +549,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='bmake'
PACKAGE_TARNAME='bmake'
PACKAGE_VERSION='20151022'
PACKAGE_STRING='bmake 20151022'
PACKAGE_VERSION='20160606'
PACKAGE_STRING='bmake 20160606'
PACKAGE_BUGREPORT='sjg@NetBSD.org'
PACKAGE_URL=''
@ -1221,7 +1221,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures bmake 20151022 to adapt to many kinds of systems.
\`configure' configures bmake 20160606 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1282,7 +1282,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of bmake 20151022:";;
short | recursive ) echo "Configuration of bmake 20160606:";;
esac
cat <<\_ACEOF
@ -1387,7 +1387,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
bmake configure 20151022
bmake configure 20160606
generated by GNU Autoconf 2.64
Copyright (C) 2009 Free Software Foundation, Inc.
@ -1960,7 +1960,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by bmake $as_me 20151022, which was
It was created by bmake $as_me 20160606, which was
generated by GNU Autoconf 2.64. Invocation command line was
$ $0 $@
@ -5055,6 +5055,17 @@ $as_echo "#define const /**/" >>confdefs.h
fi
ac_fn_c_check_type "$LINENO" "mode_t" "ac_cv_type_mode_t" "$ac_includes_default"
if test "x$ac_cv_type_mode_t" = x""yes; then :
else
cat >>confdefs.h <<_ACEOF
#define mode_t int
_ACEOF
fi
ac_fn_c_check_type "$LINENO" "off_t" "ac_cv_type_off_t" "$ac_includes_default"
if test "x$ac_cv_type_off_t" = x""yes; then :
@ -6502,7 +6513,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by bmake $as_me 20151022, which was
This file was extended by bmake $as_me 20160606, which was
generated by GNU Autoconf 2.64. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@ -6562,7 +6573,7 @@ Report bugs to <sjg@NetBSD.org>."
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_version="\\
bmake config.status 20151022
bmake config.status 20160606
configured by $0, generated by GNU Autoconf 2.64,
with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"

View File

@ -1,11 +1,11 @@
dnl
dnl RCSid:
dnl $Id: configure.in,v 1.56 2015/10/25 05:20:48 sjg Exp $
dnl $Id: configure.in,v 1.57 2016/06/07 00:49:44 sjg Exp $
dnl
dnl Process this file with autoconf to produce a configure script
dnl
AC_PREREQ(2.50)
AC_INIT([bmake], [20151022], [sjg@NetBSD.org])
AC_INIT([bmake], [20160606], [sjg@NetBSD.org])
AC_CONFIG_HEADERS(config.h)
dnl make srcdir absolute
@ -148,6 +148,7 @@ dnl Checks for typedefs, structures, and compiler characteristics.
AC_C___ATTRIBUTE__
AC_C_BIGENDIAN
AC_C_CONST
AC_TYPE_MODE_T
AC_TYPE_OFF_T
AC_TYPE_PID_T
AC_TYPE_SIZE_T

115
dir.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: dir.c,v 1.67 2013/03/05 22:01:43 christos Exp $ */
/* $NetBSD: dir.c,v 1.68 2016/06/07 00:40:00 sjg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@ -70,14 +70,14 @@
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: dir.c,v 1.67 2013/03/05 22:01:43 christos Exp $";
static char rcsid[] = "$NetBSD: dir.c,v 1.68 2016/06/07 00:40:00 sjg Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)dir.c 8.2 (Berkeley) 1/2/94";
#else
__RCSID("$NetBSD: dir.c,v 1.67 2013/03/05 22:01:43 christos Exp $");
__RCSID("$NetBSD: dir.c,v 1.68 2016/06/07 00:40:00 sjg Exp $");
#endif
#endif /* not lint */
#endif
@ -244,6 +244,7 @@ static Hash_Table mtimes; /* Results of doing a last-resort stat in
* be two rules to update a single file, so this
* should be ok, but... */
static Hash_Table lmtimes; /* same as mtimes but for lstat */
static int DirFindName(const void *, const void *);
static int DirMatchFiles(const char *, Path *, Lst);
@ -256,6 +257,80 @@ static char *DirLookupSubdir(Path *, const char *);
static char *DirFindDot(Boolean, const char *, const char *);
static char *DirLookupAbs(Path *, const char *, const char *);
/*
* We use stat(2) a lot, cache the results
* mtime and mode are all we care about.
*/
struct cache_st {
time_t mtime;
mode_t mode;
};
/* minimize changes below */
static time_t
Hash_GetTimeValue(Hash_Entry *entry)
{
struct cache_st *cst;
cst = entry->clientPtr;
return cst->mtime;
}
#define CST_LSTAT 1
#define CST_UPDATE 2
static int
cached_stats(Hash_Table *htp, const char *pathname, struct stat *st, int flags)
{
Hash_Entry *entry;
struct cache_st *cst;
int rc;
if (!pathname || !pathname[0])
return -1;
entry = Hash_FindEntry(htp, pathname);
if (entry && (flags & CST_UPDATE) == 0) {
cst = entry->clientPtr;
memset(st, 0, sizeof(*st));
st->st_mtime = cst->mtime;
st->st_mode = cst->mode;
return 0;
}
rc = (flags & CST_LSTAT) ? lstat(pathname, st) : stat(pathname, st);
if (rc == -1)
return -1;
if (st->st_mtime == 0)
st->st_mtime = 1; /* avoid confusion with missing file */
if (!entry)
entry = Hash_CreateEntry(htp, pathname, NULL);
if (!entry->clientPtr)
entry->clientPtr = bmake_malloc(sizeof(*cst));
cst = entry->clientPtr;
cst->mtime = st->st_mtime;
cst->mode = st->st_mode;
return 0;
}
int
cached_stat(const char *pathname, void *st)
{
return cached_stats(&mtimes, pathname, st, 0);
}
int
cached_lstat(const char *pathname, void *st)
{
return cached_stats(&lmtimes, pathname, st, CST_LSTAT);
}
/*-
*-----------------------------------------------------------------------
* Dir_Init --
@ -274,6 +349,7 @@ Dir_Init(const char *cdname)
dirSearchPath = Lst_Init(FALSE);
openDirectories = Lst_Init(FALSE);
Hash_InitTable(&mtimes, 0);
Hash_InitTable(&lmtimes, 0);
Dir_InitCur(cdname);
@ -901,7 +977,6 @@ static char *
DirLookupSubdir(Path *p, const char *name)
{
struct stat stb; /* Buffer for stat, if necessary */
Hash_Entry *entry; /* Entry for mtimes table */
char *file; /* the current filename to check */
if (p != dot) {
@ -917,9 +992,7 @@ DirLookupSubdir(Path *p, const char *name)
fprintf(debug_file, "checking %s ...\n", file);
}
if (stat(file, &stb) == 0) {
if (stb.st_mtime == 0)
stb.st_mtime = 1;
if (cached_stat(file, &stb) == 0) {
/*
* Save the modification time so if it's needed, we don't have
* to fetch it again.
@ -928,8 +1001,6 @@ DirLookupSubdir(Path *p, const char *name)
fprintf(debug_file, " Caching %s for %s\n", Targ_FmtTime(stb.st_mtime),
file);
}
entry = Hash_CreateEntry(&mtimes, file, NULL);
Hash_SetTimeValue(entry, stb.st_mtime);
nearmisses += 1;
return (file);
}
@ -1312,15 +1383,11 @@ Dir_FindFile(const char *name, Lst path)
fprintf(debug_file, " got it (in mtime cache)\n");
}
return(bmake_strdup(name));
} else if (stat(name, &stb) == 0) {
if (stb.st_mtime == 0)
stb.st_mtime = 1;
entry = Hash_CreateEntry(&mtimes, name, NULL);
} else if (cached_stat(name, &stb) == 0) {
if (DEBUG(DIR)) {
fprintf(debug_file, " Caching %s for %s\n", Targ_FmtTime(stb.st_mtime),
name);
}
Hash_SetTimeValue(entry, stb.st_mtime);
return (bmake_strdup(name));
} else {
if (DEBUG(DIR)) {
@ -1368,7 +1435,7 @@ Dir_FindHereOrAbove(char *here, char *search_path, char *result, int rlen) {
/* try and stat(2) it ... */
snprintf(try, sizeof(try), "%s/%s", dirbase, search_path);
if (stat(try, &st) != -1) {
if (cached_stat(try, &st) != -1) {
/*
* success! if we found a file, chop off
* the filename so we return a directory.
@ -1489,12 +1556,12 @@ Dir_MTime(GNode *gn, Boolean recheck)
else
entry = NULL;
if (entry != NULL) {
stb.st_mtime = Hash_GetTimeValue(entry);
if (DEBUG(DIR)) {
fprintf(debug_file, "Using cached time %s for %s\n",
Targ_FmtTime(Hash_GetTimeValue(entry)), fullName);
Targ_FmtTime(stb.st_mtime), fullName);
}
stb.st_mtime = Hash_GetTimeValue(entry);
} else if (stat(fullName, &stb) < 0) {
} else if (cached_stats(&mtimes, fullName, &stb, recheck ? CST_UPDATE : 0) < 0) {
if (gn->type & OP_MEMBER) {
if (fullName != gn->path)
free(fullName);
@ -1502,18 +1569,8 @@ Dir_MTime(GNode *gn, Boolean recheck)
} else {
stb.st_mtime = 0;
}
} else {
if (stb.st_mtime == 0) {
/*
* 0 handled specially by the code, if the time is really 0,
* return something else instead
*/
stb.st_mtime = 1;
}
entry = Hash_CreateEntry(&mtimes, fullName, NULL);
Hash_SetTimeValue(entry, stb.st_mtime);
}
if (fullName && gn->path == NULL) {
gn->path = fullName;
}

13
hash.h
View File

@ -1,4 +1,4 @@
/* $NetBSD: hash.h,v 1.10 2009/01/24 10:59:09 dsl Exp $ */
/* $NetBSD: hash.h,v 1.11 2016/06/07 00:40:00 sjg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@ -89,10 +89,7 @@ typedef struct Hash_Entry {
struct Hash_Entry *next; /* Used to link together all the
* entries associated with the same
* bucket. */
union {
void *clientPtr; /* Arbitrary pointer */
time_t clientTime; /* Arbitrary Time */
} clientInfo;
void *clientPtr; /* Arbitrary pointer */
unsigned namehash; /* hash value of key */
char name[1]; /* key string */
} Hash_Entry;
@ -125,8 +122,7 @@ typedef struct Hash_Search {
* Hash_Entry *h;
*/
#define Hash_GetValue(h) ((h)->clientInfo.clientPtr)
#define Hash_GetTimeValue(h) ((h)->clientInfo.clientTime)
#define Hash_GetValue(h) ((h)->clientPtr)
/*
* Hash_SetValue(h, val);
@ -134,8 +130,7 @@ typedef struct Hash_Search {
* char *val;
*/
#define Hash_SetValue(h, val) ((h)->clientInfo.clientPtr = (val))
#define Hash_SetTimeValue(h, val) ((h)->clientInfo.clientTime = (val))
#define Hash_SetValue(h, val) ((h)->clientPtr = (val))
/*
* Hash_Size(n) returns the number of words in an object of n bytes

18
main.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: main.c,v 1.245 2016/06/03 01:21:59 sjg Exp $ */
/* $NetBSD: main.c,v 1.247 2016/06/05 01:39:17 christos Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@ -69,7 +69,7 @@
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: main.c,v 1.245 2016/06/03 01:21:59 sjg Exp $";
static char rcsid[] = "$NetBSD: main.c,v 1.247 2016/06/05 01:39:17 christos Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
@ -81,7 +81,7 @@ __COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993\
#if 0
static char sccsid[] = "@(#)main.c 8.3 (Berkeley) 3/19/94";
#else
__RCSID("$NetBSD: main.c,v 1.245 2016/06/03 01:21:59 sjg Exp $");
__RCSID("$NetBSD: main.c,v 1.247 2016/06/05 01:39:17 christos Exp $");
#endif
#endif /* not lint */
#endif
@ -1906,15 +1906,11 @@ cached_realpath(const char *pathname, char *resolved)
rp = Var_Value(pathname, cache, &cp);
if (rp) {
/* a hit */
if (resolved)
strlcpy(resolved, rp, MAXPATHLEN);
else
resolved = bmake_strdup(rp);
} else {
if ((rp = realpath(pathname, resolved))) {
Var_Set(pathname, rp, cache, 0);
}
strlcpy(resolved, rp, MAXPATHLEN);
} else if ((rp = realpath(pathname, resolved))) {
Var_Set(pathname, rp, cache, 0);
}
free(cp);
return rp ? resolved : NULL;
}

4
make.h
View File

@ -1,4 +1,4 @@
/* $NetBSD: make.h,v 1.99 2016/06/03 01:21:59 sjg Exp $ */
/* $NetBSD: make.h,v 1.100 2016/06/07 00:40:00 sjg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@ -506,6 +506,8 @@ void Main_ExportMAKEFLAGS(Boolean);
Boolean Main_SetObjdir(const char *);
int mkTempFile(const char *, char **);
int str2Lst_Append(Lst, char *, const char *);
int cached_lstat(const char *, void *);
int cached_stat(const char *, void *);
#define VARF_UNDEFERR 1
#define VARF_WANTRES 2

10
meta.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: meta.c,v 1.60 2016/06/04 22:17:14 sjg Exp $ */
/* $NetBSD: meta.c,v 1.61 2016/06/07 00:40:00 sjg Exp $ */
/*
* Implement 'meta' mode.
@ -429,7 +429,7 @@ meta_needed(GNode *gn, const char *dname, const char *tname,
}
/* The object directory may not exist. Check it.. */
if (stat(dname, &fs) != 0) {
if (cached_stat(dname, &fs) != 0) {
if (verbose)
fprintf(debug_file, "Skipping meta for %s: no .OBJDIR\n",
gn->name);
@ -1238,8 +1238,8 @@ meta_oodate(GNode *gn, Boolean oodate)
if ((strstr("tmp", p)))
break;
if ((link_src != NULL && lstat(p, &fs) < 0) ||
(link_src == NULL && stat(p, &fs) < 0)) {
if ((link_src != NULL && cached_lstat(p, &fs) < 0) ||
(link_src == NULL && cached_stat(p, &fs) < 0)) {
if (Lst_Find(missingFiles, p, string_match) == NULL)
Lst_AtEnd(missingFiles, bmake_strdup(p));
}
@ -1328,7 +1328,7 @@ meta_oodate(GNode *gn, Boolean oodate)
if (DEBUG(META))
fprintf(debug_file, "%s: %d: looking for: %s\n", fname, lineno, *sdp);
#endif
if (stat(*sdp, &fs) == 0) {
if (cached_stat(*sdp, &fs) == 0) {
found = 1;
p = *sdp;
}