mirror of
https://github.com/mirror/make.git
synced 2026-08-07 16:41:04 +00:00
[SV 60412] Allow -I- to throw out the current directory path
Accept a "-" directory value to the -I option to clear the set of directories to be searched up to that point, including the default directories. * NEWS: Announce the change. * doc/make.texi (Summary of Options): Add documentation. * src/read.c (construct_include_path): Check for '-' and if found, clear the list of directories to be searched. * tests/scripts/options/dash-I: Add tests for -I-. * tests/scripts/variables/INCLUDE_DIRS: Add tests for -I-.
This commit is contained in:
4
NEWS
4
NEWS
@@ -50,6 +50,10 @@ https://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=109&se
|
||||
user-defined function and they will not impact global variable assignments.
|
||||
Implementation provided by Jouke Witteveen <j.witteveen@gmail.com>
|
||||
|
||||
* The -I option accepts an argument "-" (e.g., "-I-") which means "reset the
|
||||
list of search directories to empty". Among other things this can be used
|
||||
to prevent GNU make from searching in its default list of directories.
|
||||
|
||||
* New debug option "print" will show the recipe to be run, even when silent
|
||||
mode is set, and new debug option "why" will show why a target is rebuilt
|
||||
(which prerequisites caused the target to be considered out of date).
|
||||
|
||||
@@ -1281,6 +1281,16 @@ hierarchy.})
|
||||
@file{/usr/gnu/include},
|
||||
@file{/usr/local/include}, @file{/usr/include}.
|
||||
|
||||
The @code{.INCLUDE_DIRS} variable will contain the current list of
|
||||
directories that make will search for included files. @xref{Special
|
||||
Variables, ,Other Special Variables}.
|
||||
|
||||
You can avoid searching in these default directories by adding the
|
||||
command line option @code{-I} with the special value @code{-} (e.g.,
|
||||
@code{-I-}) to the command line. This will cause @code{make} to
|
||||
forget any already-set include directories, including the default
|
||||
directories.
|
||||
|
||||
If an included makefile cannot be found in any of these directories it
|
||||
is not an immediately fatal error; processing of the makefile
|
||||
containing the @code{include} continues. Once it has finished reading
|
||||
@@ -6676,6 +6686,8 @@ Supports dynamically loadable objects for creating custom extensions.
|
||||
@item .INCLUDE_DIRS
|
||||
Expands to a list of directories that @code{make} searches for
|
||||
included makefiles (@pxref{Include, , Including Other Makefiles}).
|
||||
Note that modifying this variable's value does not change the list of
|
||||
directories which are searched.
|
||||
|
||||
@vindex .EXTRA_PREREQS @r{(prerequisites not added to automatic variables)}
|
||||
@item .EXTRA_PREREQS
|
||||
@@ -9058,7 +9070,11 @@ Ignore all errors in recipes executed to remake files.
|
||||
Specifies a directory @var{dir} to search for included makefiles.
|
||||
@xref{Include, ,Including Other Makefiles}. If several @samp{-I}
|
||||
options are used to specify several directories, the directories are
|
||||
searched in the order specified.
|
||||
searched in the order specified. If the directory @var{dir} is a
|
||||
single dash (@code{-}) then any already-specified directories up to
|
||||
that point (including the default directory paths) will be discarded.
|
||||
You can examine the current list of directories to be searched via the
|
||||
@code{.INCLUDE_DIRS} variable.
|
||||
|
||||
@item -j [@var{jobs}]
|
||||
@cindex @code{-j}
|
||||
|
||||
71
src/read.c
71
src/read.c
@@ -2926,6 +2926,7 @@ construct_include_path (const char **arg_dirs)
|
||||
const char **dirs;
|
||||
const char **cpp;
|
||||
size_t idx;
|
||||
int disable = 0;
|
||||
|
||||
/* Compute the number of pointers we need in the table. */
|
||||
idx = sizeof (default_include_directories) / sizeof (const char *);
|
||||
@@ -2944,7 +2945,8 @@ construct_include_path (const char **arg_dirs)
|
||||
max_incl_len = 0;
|
||||
|
||||
/* First consider any dirs specified with -I switches.
|
||||
Ignore any that don't exist. Remember the maximum string length. */
|
||||
Ignore any that don't exist. Restart if we find "-".
|
||||
Remember the maximum string length. */
|
||||
|
||||
if (arg_dirs)
|
||||
while (*arg_dirs != 0)
|
||||
@@ -2953,6 +2955,14 @@ construct_include_path (const char **arg_dirs)
|
||||
char *expanded = 0;
|
||||
int e;
|
||||
|
||||
if (dir[0] == '-' && dir[1] == '\0')
|
||||
{
|
||||
disable = 1;
|
||||
idx = 0;
|
||||
max_incl_len = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dir[0] == '~')
|
||||
{
|
||||
expanded = tilde_expand (dir);
|
||||
@@ -2976,41 +2986,40 @@ construct_include_path (const char **arg_dirs)
|
||||
}
|
||||
|
||||
/* Now add the standard default dirs at the end. */
|
||||
|
||||
#ifdef __MSDOS__
|
||||
{
|
||||
/* The environment variable $DJDIR holds the root of the DJGPP directory
|
||||
tree; add ${DJDIR}/include. */
|
||||
struct variable *djdir = lookup_variable ("DJDIR", 5);
|
||||
|
||||
if (djdir)
|
||||
{
|
||||
size_t len = strlen (djdir->value) + 8;
|
||||
char *defdir = alloca (len + 1);
|
||||
|
||||
strcat (strcpy (defdir, djdir->value), "/include");
|
||||
dirs[idx++] = strcache_add (defdir);
|
||||
|
||||
if (len > max_incl_len)
|
||||
max_incl_len = len;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
for (cpp = default_include_directories; *cpp != 0; ++cpp)
|
||||
if (!disable)
|
||||
{
|
||||
int e;
|
||||
#ifdef __MSDOS__
|
||||
/* The environment variable $DJDIR holds the root of the DJGPP directory
|
||||
tree; add ${DJDIR}/include. */
|
||||
struct variable *djdir = lookup_variable ("DJDIR", 5);
|
||||
|
||||
EINTRLOOP (e, stat (*cpp, &stbuf));
|
||||
if (e == 0 && S_ISDIR (stbuf.st_mode))
|
||||
if (djdir)
|
||||
{
|
||||
size_t len = strlen (*cpp);
|
||||
/* If dir name is written with trailing slashes, discard them. */
|
||||
while (len > 1 && (*cpp)[len - 1] == '/')
|
||||
--len;
|
||||
size_t len = strlen (djdir->value) + 8;
|
||||
char *defdir = alloca (len + 1);
|
||||
|
||||
strcat (strcpy (defdir, djdir->value), "/include");
|
||||
dirs[idx++] = strcache_add (defdir);
|
||||
|
||||
if (len > max_incl_len)
|
||||
max_incl_len = len;
|
||||
dirs[idx++] = strcache_add_len (*cpp, len);
|
||||
}
|
||||
#endif
|
||||
for (cpp = default_include_directories; *cpp != 0; ++cpp)
|
||||
{
|
||||
int e;
|
||||
|
||||
EINTRLOOP (e, stat (*cpp, &stbuf));
|
||||
if (e == 0 && S_ISDIR (stbuf.st_mode))
|
||||
{
|
||||
size_t len = strlen (*cpp);
|
||||
/* If dir name is written with trailing slashes, discard them. */
|
||||
while (len > 1 && (*cpp)[len - 1] == '/')
|
||||
--len;
|
||||
if (len > max_incl_len)
|
||||
max_incl_len = len;
|
||||
dirs[idx++] = strcache_add_len (*cpp, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# -*-perl-*-
|
||||
|
||||
$description ="The following test creates a makefile to test the -I option.";
|
||||
$description = "The following test creates a makefile to test the -I option.";
|
||||
|
||||
$details = "\
|
||||
This test tests the -I option by including a filename in
|
||||
@@ -9,53 +9,108 @@ under -I in the command line. Without this option, the make
|
||||
would fail to find the included file. It also checks to make
|
||||
sure that the -I option gets passed to recursive makes.";
|
||||
|
||||
$makefile2 = &get_tmpfile;
|
||||
use File::Spec;
|
||||
|
||||
open(MAKEFILE,"> $makefile");
|
||||
# Create a directory and put a makefile in it.
|
||||
# We can't put it in the current directory since that's automatically searched
|
||||
# anyway.
|
||||
my $subdir = 'idir';
|
||||
mkdir($subdir, 0777);
|
||||
|
||||
# The Contents of the MAKEFILE ...
|
||||
|
||||
$mf2 = substr ($makefile2, index ($makefile2, $pathsep) + 1);
|
||||
print MAKEFILE <<EOF;
|
||||
include $mf2
|
||||
all:
|
||||
\t\@echo There should be no errors for this makefile.
|
||||
EOF
|
||||
|
||||
# END of Contents of MAKEFILE
|
||||
|
||||
close(MAKEFILE);
|
||||
|
||||
|
||||
open(MAKEFILE,"> $makefile2");
|
||||
|
||||
print MAKEFILE <<EOF;
|
||||
my $included = 'ifile.mk';
|
||||
my $ipath = File::Spec->catfile($subdir, $included);
|
||||
create_file($ipath, "
|
||||
ANOTHER:
|
||||
\t\@echo This is another included makefile
|
||||
recurse:
|
||||
\t\$(MAKE) ANOTHER -f $makefile
|
||||
EOF
|
||||
\t\@\$(MAKE) ANOTHER -f \$(main_makefile)\n");
|
||||
|
||||
close(MAKEFILE);
|
||||
|
||||
&run_make_with_options($makefile,"-I $workdir all",&get_logfile);
|
||||
|
||||
# Create the answer to what should be produced by this Makefile
|
||||
$answer = "There should be no errors for this makefile.\n";
|
||||
&compare_output($answer,&get_logfile(1));
|
||||
my $nosuch = "#MAKEFILE#:5: $included: $ERR_no_such_file
|
||||
#MAKE#: *** No rule to make target '$included'. Stop.\n";
|
||||
|
||||
|
||||
$answer = "This is another included makefile\n";
|
||||
&run_make_with_options($makefile,"-I $workdir ANOTHER",&get_logfile);
|
||||
&compare_output($answer,&get_logfile(1));
|
||||
# Verify that we get an error if we don't have -I
|
||||
run_make_test(qq!
|
||||
main_makefile := \$(firstword \$(MAKEFILE_LIST))
|
||||
all:
|
||||
\t\@echo There should be no errors for this makefile
|
||||
include $included
|
||||
!,
|
||||
'', $nosuch, 512);
|
||||
|
||||
# Check basic -I works
|
||||
run_make_test(undef, "-I $subdir all",
|
||||
"There should be no errors for this makefile\n");
|
||||
|
||||
$answer = subst_make_string("$mkpath ANOTHER -f $makefile
|
||||
#MAKE#[1]: Entering directory '#PWD#'
|
||||
# Check that the included target works
|
||||
run_make_test(undef, "-I $subdir ANOTHER",
|
||||
"This is another included makefile\n");
|
||||
|
||||
# Check that -I is passed down through MAKEFLAGS
|
||||
run_make_test(undef, "-I $subdir recurse",
|
||||
"#MAKE#[1]: Entering directory '#PWD#'
|
||||
This is another included makefile
|
||||
#MAKE#[1]: Leaving directory '#PWD#'\n");
|
||||
|
||||
&run_make_with_options($makefile,"-I $workdir recurse",&get_logfile);
|
||||
&compare_output($answer,&get_logfile(1));
|
||||
# Verify that we get an error if we add -I- to delete previous includes
|
||||
run_make_test(undef, "-I $subdir -I- all", $nosuch, 512);
|
||||
|
||||
# Make another directory with the same name and make sure the right one is
|
||||
# chosen if -I- stops the path.
|
||||
|
||||
mkdir('idir2', 0777);
|
||||
my $ipath2 = File::Spec->catfile('idir2', $included);
|
||||
create_file($ipath2, "This is a bad makefile!!\n");
|
||||
|
||||
run_make_test(undef, "-I idir2 -I $subdir ANOTHER",
|
||||
"$included:1: *** missing separator. Stop.\n", 512);
|
||||
|
||||
run_make_test(undef, "-I idir2 -I - -I $subdir ANOTHER",
|
||||
"This is another included makefile\n");
|
||||
|
||||
# Check that -I- is passed down through MAKEFLAGS
|
||||
run_make_test(undef, "-I idir2 -I - -I $subdir recurse",
|
||||
"#MAKE#[1]: Entering directory '#PWD#'
|
||||
This is another included makefile
|
||||
#MAKE#[1]: Leaving directory '#PWD#'\n");
|
||||
|
||||
unlink($ipath2);
|
||||
rmdir('idir2');
|
||||
|
||||
# The only way to check if -I- voids included directories is to see if a file
|
||||
# exists in one and try to include it. We very likely can't add our own files
|
||||
# to the default directories since they're probably write-protected. This
|
||||
# won't work if none of the default directories contain any files :-/
|
||||
|
||||
create_file('defaultdirs.mk', "\$(info \$(.INCLUDE_DIRS))\nall:;\@:\n");
|
||||
my $cmd = subst_make_string("#MAKEPATH# -f defaultdirs.mk");
|
||||
my @dirs = `$cmd`;
|
||||
my $dirs = $dirs[0];
|
||||
chomp $dirs;
|
||||
unlink('defaultdirs.mk');
|
||||
|
||||
my $fn = undef;
|
||||
foreach my $dn (split ' ', $dirs) {
|
||||
# On Windows the default is "." which is bogus!
|
||||
if ($dn != '.') {
|
||||
my @files = glob(File::Spec->catfile($dn, "*"));
|
||||
if (@files) {
|
||||
(undef, undef, $fn) = File::Spec->splitpath($files[0]);
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($fn) {
|
||||
run_make_test("
|
||||
all:;
|
||||
include $fn
|
||||
",
|
||||
'-I-', "#MAKEFILE#:3: $fn: $ERR_no_such_file
|
||||
#MAKE#: *** No rule to make target '$fn'. Stop.\n", 512);
|
||||
}
|
||||
|
||||
unlink($ipath);
|
||||
rmdir($subdir);
|
||||
|
||||
1;
|
||||
|
||||
@@ -20,8 +20,7 @@ endif
|
||||
.PHONY: all
|
||||
all:;@:
|
||||
',
|
||||
'',
|
||||
'');
|
||||
'', '');
|
||||
|
||||
|
||||
# Test #2: Make sure -I paths end up in .INCLUDE_DIRS.
|
||||
@@ -38,9 +37,56 @@ endif
|
||||
.PHONY: all
|
||||
all:;@:
|
||||
',
|
||||
"-I$dir dir=$dir",
|
||||
'');
|
||||
"-I$dir dir=$dir", '');
|
||||
|
||||
# Find the default .INCLUDE_DIRS
|
||||
create_file('defaultdirs.mk', "\$(info \$(.INCLUDE_DIRS))\nall:;\@:\n");
|
||||
my $cmd = subst_make_string("#MAKEPATH# -f defaultdirs.mk");
|
||||
my @dirs = `$cmd`;
|
||||
my $dirs = $dirs[0];
|
||||
chomp $dirs;
|
||||
unlink('defaultdirs.mk');
|
||||
|
||||
run_make_test("
|
||||
ifneq (\$(.INCLUDE_DIRS),$dirs)
|
||||
\$(warning Mismatched \$(.INCLUDE_DIRS) != $dirs)
|
||||
endif
|
||||
all:;\@:
|
||||
",
|
||||
'', '');
|
||||
|
||||
# Verify that -I- disables content from .INCLUDE_DIRS
|
||||
|
||||
run_make_test("
|
||||
ifneq (\$(.INCLUDE_DIRS),)
|
||||
\$(warning Mismatched \$(.INCLUDE_DIRS) != )
|
||||
endif
|
||||
all:;\@:
|
||||
",
|
||||
'-I-', '');
|
||||
|
||||
# Prefix -I dirs to the front
|
||||
mkdir('somedir', 0777);
|
||||
|
||||
run_make_test("
|
||||
ifneq (\$(.INCLUDE_DIRS),somedir $dirs)
|
||||
\$(warning Mismatched \$(.INCLUDE_DIRS) != somedir $dirs)
|
||||
endif
|
||||
all:;\@:
|
||||
",
|
||||
'-I somedir', '');
|
||||
|
||||
# Verify .INCLUDE_DIRS contains files after -I-
|
||||
|
||||
run_make_test("
|
||||
ifneq (\$(.INCLUDE_DIRS),somedir)
|
||||
\$(warning Mismatched \$(.INCLUDE_DIRS) != somedir)
|
||||
endif
|
||||
all:;\@:
|
||||
",
|
||||
'-I - -I somedir', '');
|
||||
|
||||
rmdir('somedir');
|
||||
|
||||
# This tells the test driver that the perl test script executed properly.
|
||||
1;
|
||||
|
||||
Reference in New Issue
Block a user