[PATCH 3/3] driver: Search PATH with the machine prefix too
John Ericson <[email protected]>
| Newsgroups | gmane.comp.gcc.patches |
|---|---|
| Message-ID | <[email protected]> |
Background: commit r17-1532-ga514707ffd7d58 ("find_a_program: Search
with machine prefix in some cases") taught find_a_program to try
MACHINE-NAME ahead of NAME when looking in a directory that is not
already machine-specific, so that a directory holding tools for several
targets can still be disambiguated.
That reached only the exec prefixes -- the compiler's own directories,
-B arguments, and COMPILER_PATH -- because those were the only
directories find_a_program looked in. PATH was left to execvp, by way
of PEX_SEARCH, and execvp matches NAME alone.
That was basically an oversight on my part. In Nixpkgs, for example, we
do plenty of PATH-based tool lookup, and indeed PATH is one of the
strongest motivations for machine prefixing, because it is how a single
PATH executable search path can be shared between multiple targets.
The previous commit brought PATH into find_a_program, but did not deal
with MACHINE-NAME in order to be closer to a pure refactor. This commit
actually implements the feature: PATH entries are never machine-specific,
so MACHINE-NAME is now tried ahead of NAME in each of them, exactly as it
already was in the machine-agnostic exec prefixes.
Note that this is not exactly a new policy: collect2 has long searched
PATH for MACHINE-ld and MACHINE-nm ahead of the bare names.
This also sharpens the -print-prog-name improvement of the previous
commit: the more complex the driver's PATH search, the more a caller
gains from not having to reimplement it.
As a bonus, since the logic for PATH and exec_prefixes directories is
now the same, we can share one callback between the two for_each_*
calls. There is now a single lambda bound to a name, which is called
by both functions, ensuring the logic for both sorts of directories
will stay in sync.
gcc/ChangeLog:
* gcc.cc (find_a_program): Try the machine-prefixed name when
searching PATH. Name the exec prefix search callback and reuse it
there.
* doc/invoke.texi (Developer Options): Document that the
machine-prefixed name is tried first.
Signed-off-by: John Ericson <[email protected]>
---
gcc/doc/invoke.texi | 7 +++++--
gcc/gcc.cc | 36 ++++++++++++++++--------------------
2 files changed, 21 insertions(+), 22 deletions(-)
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 43469bf3d5e..b72fa1d8dec 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -21230,8 +21230,11 @@ relative to some @file{lib} subdirectory.
@itemx --print-prog-name=@var{program}
@itemx --print-prog-name @var{program}
Like @option{-print-file-name}, but searches for a program such as @command{cpp}.
-The compiler's own directories are searched first, then @env{PATH}. If no
-such program is found, @var{program} is printed back unchanged.
+The compiler's own directories are searched first, then @env{PATH}. In a
+directory that is not already specific to one target, the name prefixed
+with the target machine, such as @command{@var{machine}-ld}, is tried
+before @var{program} itself. If no such program is found, @var{program}
+is printed back unchanged.
@opindex print-libgcc-file-name
@item -print-libgcc-file-name
diff --git a/gcc/gcc.cc b/gcc/gcc.cc
index c494ddd0665..0b4491e5b89 100644
--- a/gcc/gcc.cc
+++ b/gcc/gcc.cc
@@ -3195,9 +3195,7 @@ find_a_program (const char *name)
/* Callback appends the file name to the directory path. If the
resulting file exists in the right mode, return the full pathname
to the file. */
- char *ret = for_each_path (&exec_prefixes, false,
- prefix_len + name_len + suffix_len,
- [=](char *path, bool machine_specific) -> char*
+ auto try_dir = [=](char *path, bool machine_specific) -> char*
{
size_t path_len = strlen (path);
@@ -3235,7 +3233,10 @@ find_a_program (const char *name)
}
return search(path_len);
- });
+ };
+
+ char *ret = for_each_path (&exec_prefixes, false,
+ prefix_len + name_len + suffix_len, try_dir);
if (ret)
return ret;
@@ -3243,26 +3244,21 @@ find_a_program (const char *name)
/* Nothing among our own directories, so fall back to PATH.
Searching it here rather than via execvp means we know which file
- we picked, so -print-prog-name can report it. */
+ we picked, so -print-prog-name can report it. It also lets us look
+ for NAME and MACHINE-NAME without revisiting the directory. */
return for_each_env_path (env.get ("PATH"), [&] (const char *dir) -> char*
{
- /* Some systems have a suffix for executable files. As above, try
- appending that first. */
- if (suffix_len)
- {
- char *candidate = concat (dir, name, suffix, NULL);
- if (access_check (candidate, X_OK) == 0)
- return candidate;
- free (candidate);
- }
+ char *path = XNEWVEC (char, strlen (dir) + prefix_len + name_len
+ + suffix_len + 1);
+ strcpy (path, dir);
- char *candidate = concat (dir, name, NULL);
- if (access_check (candidate, X_OK) == 0)
- return candidate;
-
- free (candidate);
- return NULL;
+ char *found = try_dir (path,
+ /* PATH dirs we consider machine-agnostic. */
+ false);
+ if (!found)
+ free (path);
+ return found;
});
}
--
2.54.0