Add ability to search up the directory hierarchy for the system directory.

Do by specifying ".../" with '-m' or MAKESYSPATH (new) environment variable.

Reviewed by:	<sjg@NetBSD.org>
Obtained from:	NetBSD (+ embellishment by me, sent back to NetBSD)
This commit is contained in:
David E. O'Brien 2010-01-04 18:57:22 +00:00
parent f40ea8b948
commit 290dac20e6
23 changed files with 246 additions and 11 deletions

View File

@ -233,6 +233,12 @@ reset_test()
#
eval_clean()
{
#
# If you have special cleaning needs, provide a 'cleanup' shell script.
#
if [ -n "${TEST_CLEANUP}" ] ; then
. ${SRC_DIR}/cleanup
fi
rm -rf ${WORK_DIR}
rm -rf ${OUTPUT_DIR}
}

View File

@ -0,0 +1,6 @@
# $FreeBSD$
#
# Can we traverse up to / and find a 'mk/sys.mk'?
#
all:
@echo ${DASH_M_DOTDOTDOT}

View File

@ -0,0 +1 @@
0

View File

@ -0,0 +1 @@
Found_DotDotDot_sys_mk

View File

@ -0,0 +1,17 @@
#!/bin/sh
# $FreeBSD$
cd `dirname $0`
. ../../../../common.sh
# Description
DESC="Can we traverse up to / and find a 'mk/sys.mk'?"
# Run
TEST_N=1
TEST_1="-m .../mk"
TEST_MAKE_DIRS="../../mk 755"
TEST_COPY_FILES="../../mk/sys.mk 644"
eval_cmd $*

View File

@ -0,0 +1,3 @@
# $FreeBSD$
DASH_M_DOTDOTDOT=Found_DotDotDot_sys_mk

View File

@ -0,0 +1,3 @@
# $FreeBSD$
rm -rf ${WORK_DIR}/../../../t0/2/1

View File

@ -0,0 +1 @@
0

View File

@ -0,0 +1 @@
Found_DotDotDot_sys_mk

View File

@ -0,0 +1,19 @@
#!/bin/sh
# $FreeBSD$
cd `dirname $0`
. ../../../../common.sh
# Description
DESC="Can we traverse up to / and find a 'mk/sys.mk' with -C -m?"
# Run
TEST_N=1
TEST_1="-C ../../../t0/2/1 -m .../mk"
TEST_MAKE_DIRS="../../mk 755 ../../../t0/mk 755 ../../../t0/2/1 755"
TEST_COPY_FILES="../../mk/sys.mk 644 ../../../t0/mk/sys.mk 644 ../../../t0/2/1/Makefile 644"
TEST_CLEAN_FILES="../../../t0/2/1"
TEST_CLEANUP=clean-special
eval_cmd $*

View File

@ -0,0 +1,3 @@
# $FreeBSD$
DASH_M_DOTDOTDOT=Found_WRONG_DotDotDot_sys_mk__with_C_before_m

View File

@ -0,0 +1,3 @@
# $FreeBSD$
rm -rf ${WORK_DIR}/../../../t0/2/1

View File

@ -0,0 +1 @@
0

View File

@ -0,0 +1 @@
Found_DotDotDot_sys_mk__with_m_before_C

View File

@ -0,0 +1,19 @@
#!/bin/sh
# $FreeBSD$
cd `dirname $0`
. ../../../../common.sh
# Description
DESC="Can we traverse up to / and find a 'mk/sys.mk' with -m -C?"
# Run
TEST_N=1
TEST_1="-m .../mk -C ../../../t0/2/1"
TEST_MAKE_DIRS="../../mk 755 ../../../t0/mk 755 ../../../t0/2/1 755"
TEST_COPY_FILES="../../mk/sys.mk 644 ../../../t0/mk/sys.mk 644 ../../../t0/2/1/Makefile 644"
TEST_CLEAN_FILES="../../../t0/2/1"
TEST_CLEANUP=clean-special
eval_cmd $*

View File

@ -0,0 +1,3 @@
# $FreeBSD$
DASH_M_DOTDOTDOT=Found_DotDotDot_sys_mk__with_m_before_C

View File

@ -61,6 +61,10 @@ __FBSDID("$FreeBSD$");
* If it exists, the entire path is returned.
* Otherwise NULL is returned.
*
* Dir_FindHereOrAbove Search for a path in the current directory and
* then all the directories above it in turn until
* the path is found or we reach the root ("/").
*
* Dir_MTime Return the modification time of a node. The file
* is searched for along the default search path.
* The path and mtime fields of the node are filled in.
@ -83,7 +87,7 @@ __FBSDID("$FreeBSD$");
* Dir_PrintDirectories Print stats about the directory cache.
*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <dirent.h>
#include <err.h>
@ -849,6 +853,83 @@ Path_FindFile(char *name, struct Path *path)
}
}
/*-
*-----------------------------------------------------------------------
* Dir_FindHereOrAbove --
* search for a path starting at a given directory and then working
* our way up towards the root.
*
* Input:
* here starting directory
* search_path the path we are looking for
* result the result of a successful search is placed here
* rlen the length of the result buffer
* (typically MAXPATHLEN + 1)
*
* Results:
* 0 on failure, 1 on success [in which case the found path is put
* in the result buffer].
*
* Side Effects:
*-----------------------------------------------------------------------
*/
int
Dir_FindHereOrAbove(char *here, char *search_path, char *result, int rlen)
{
struct stat st;
char dirbase[MAXPATHLEN + 1], *db_end;
char try[MAXPATHLEN + 1], *try_end;
/* copy out our starting point */
snprintf(dirbase, sizeof(dirbase), "%s", here);
db_end = dirbase + strlen(dirbase);
/* loop until we determine a result */
while (1) {
/* try and stat(2) it ... */
snprintf(try, sizeof(try), "%s/%s", dirbase, search_path);
if (stat(try, &st) != -1) {
/*
* Success! If we found a file, chop off
* the filename so we return a directory.
*/
if ((st.st_mode & S_IFMT) != S_IFDIR) {
try_end = try + strlen(try);
while (try_end > try && *try_end != '/')
try_end--;
if (try_end > try)
*try_end = 0; /* chop! */
}
/*
* Done!
*/
snprintf(result, rlen, "%s", try);
return(1);
}
/*
* Nope, we didn't find it. If we used up dirbase we've
* reached the root and failed.
*/
if (db_end == dirbase)
break; /* Failed! */
/*
* truncate dirbase from the end to move up a dir
*/
while (db_end > dirbase && *db_end != '/')
db_end--;
*db_end = 0; /* chop! */
} /* while (1) */
/*
* We failed...
*/
return(0);
}
/*-
*-----------------------------------------------------------------------
* Dir_MTime --

View File

@ -56,6 +56,7 @@ TAILQ_HEAD(Path, PathElement);
void Dir_Init(void);
void Dir_InitDot(void);
Boolean Dir_HasWildcards(const char *);
int Dir_FindHereOrAbove(char *, char *, char *, int);
int Dir_MTime(struct GNode *);
void Dir_PrintDirectories(void);

View File

@ -368,6 +368,7 @@ MainParseArgs(int argc, char **argv)
{
int c;
Boolean found_dd = FALSE;
char found_dir[MAXPATHLEN + 1]; /* for searching for sys.mk */
rearg:
optind = 1; /* since we're called more than once */
@ -394,6 +395,8 @@ MainParseArgs(int argc, char **argv)
case 'C':
if (chdir(optarg) == -1)
err(1, "chdir %s", optarg);
if (getcwd(curdir, MAXPATHLEN) == NULL)
err(2, NULL);
break;
case 'D':
Var_SetGlobal(optarg, "1");
@ -492,7 +495,15 @@ MainParseArgs(int argc, char **argv)
MFLAGS_append("-k", NULL);
break;
case 'm':
Path_AddDir(&sysIncPath, optarg);
/* look for magic parent directory search string */
if (strncmp(".../", optarg, 4) == 0) {
if (!Dir_FindHereOrAbove(curdir, optarg + 4,
found_dir, sizeof(found_dir)))
break; /* nothing doing */
Path_AddDir(&sysIncPath, found_dir);
} else {
Path_AddDir(&sysIncPath, optarg);
}
MFLAGS_append("-m", optarg);
break;
case 'n':
@ -869,6 +880,7 @@ main(int argc, char **argv)
char mdpath[MAXPATHLEN];
char obpath[MAXPATHLEN];
char cdpath[MAXPATHLEN];
char found_dir[MAXPATHLEN + 1]; /* for searching for sys.mk */
char *cp = NULL, *start;
save_argv = argv;
@ -1021,6 +1033,12 @@ main(int argc, char **argv)
}
Job_SetPrefix();
/*
* Find where we are...
*/
if (getcwd(curdir, MAXPATHLEN) == NULL)
err(2, NULL);
/*
* First snag things out of the MAKEFLAGS environment
* variable. Then parse the command line arguments.
@ -1030,11 +1048,8 @@ main(int argc, char **argv)
MainParseArgs(argc, argv);
/*
* Find where we are...
* Verify that cwd is sane (after -C may have changed it).
*/
if (getcwd(curdir, MAXPATHLEN) == NULL)
err(2, NULL);
{
struct stat sa;
@ -1132,18 +1147,37 @@ main(int argc, char **argv)
* as dir1:...:dirn) to the system include path.
*/
if (TAILQ_EMPTY(&sysIncPath)) {
char syspath[] = PATH_DEFSYSPATH;
char defsyspath[] = PATH_DEFSYSPATH;
char *syspath = getenv("MAKESYSPATH");
/*
* If no user-supplied system path was given (thru -m option)
* add the directories from the DEFSYSPATH (more than one may
* be given as dir1:...:dirn) to the system include path.
*/
if (syspath == NULL || *syspath == '\0')
syspath = defsyspath;
else
syspath = estrdup(syspath);
for (start = syspath; *start != '\0'; start = cp) {
for (cp = start; *cp != '\0' && *cp != ':'; cp++)
continue;
if (*cp == '\0') {
Path_AddDir(&sysIncPath, start);
} else {
if (*cp == ':') {
*cp++ = '\0';
}
/* look for magic parent directory search string */
if (strncmp(".../", start, 4) == 0) {
if (Dir_FindHereOrAbove(curdir, start + 4,
found_dir, sizeof(found_dir))) {
Path_AddDir(&sysIncPath, found_dir);
}
} else {
Path_AddDir(&sysIncPath, start);
}
}
if (syspath != defsyspath)
free(syspath);
}
/*

View File

@ -240,6 +240,36 @@ The system include path will always be appended to the search path used
for "..."-style inclusions and makefile searches (see the
.Fl I
option).
.Pp
If a file or directory name in the
.Fl m
argument (or the
.Ev MAKESYSPATH
environment variable) starts with the string
.Qq \&.../
then
.Nm
will search for the specified file or directory named in the remaining part
of the argument string.
The search starts with the current directory of the Makefile and then works
upward towards the root of the filesystem.
If the search is successful,
then the resulting directory replaces the
.Qq \&.../
specification in the
.Fl m
argument.
If used, this feature allows
.Nm
to easily search in the current source tree for customized sys.mk files
(e.g. by using
.Qq \&.../mk/sys.mk
as an argument).
Note that a
.Fl C
that are earlier on the command line affect where
.Fl m Qq \&.../
searches.
.It Fl n
Display the commands that would have been executed, but do not actually
execute them.
@ -1665,8 +1695,9 @@ utility uses the following environment variables, if they exist:
.Ev MAKE ,
.Ev MAKEFLAGS ,
.Ev MAKEOBJDIR ,
.Ev MAKEOBJDIRPREFIX ,
and
.Ev MAKEOBJDIRPREFIX .
.Ev MAKESYSPATH .
.Sh FILES
.Bl -tag -width /usr/share/doc/psd/12.make -compact
.It Pa .depend