This fixes a permission error that occurs when cross-compiling with
-save-temps and a relocated toolchain, where the original build path
exists but is inaccessible.
The issue only happened when:
- Building the toolchain at /home/scratch/build/
- Installing it to another location like /home/user/rv64-toolchain/
- The /home/scratch directory exists but has insufficient permissions
(e.g. drwx------ for `/home/scratch/`)
Without this fix, cc1 would report errors like:
cc1: error:
/home/scratch/build/install/riscv64-unknown-elf/usr/local/include: Permission
denied
This occurred because the GCC driver did not pass GCC_EXEC_PREFIX and
isysroot to cc1 in the compile stage when using -save-temps, causing
cc1 to search headers from the wrong (original build) path instead of
the relocated installation path.
The fix ensures cc1 is aware of relocation by passing %I (which includes
isysroot) and setting the GCC_EXEC_PREFIX environment variable.
Also another issue is cc1 will only silently ignore EPERM and ENOENT
(at remove_duplicates), but not EACCES, that make this issue more confusing,
maybe we could consider adding EACCES to the list of silently ignored errors in
future, but I think this patch still worth since it will prevent us from trying
wrong path at beginning, that could prevent unnessesary autofs mounting in some
cases (Yeah, our server env will hit that).
Or...another way we could try is we should not collect include path at
all when -fpreprocessed is specified, since the input is already
preprocessed.
gcc/ChangeLog:
* gcc.cc (default_compilers): Add %I to cc1 invocation for C and
C++ when using -save-temps.
(do_spec_1): Set GCC_EXEC_PREFIX environment variable before
collecting gcc options.
---
gcc/gcc.cc | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/gcc/gcc.cc b/gcc/gcc.cc
index eae7f07d962..e18415b5a47 100644
--- a/gcc/gcc.cc
+++ b/gcc/gcc.cc
@@ -1469,10 +1469,10 @@ static const struct compiler default_compilers[] =
%eGNU C no longer supports -traditional without -E}\
%{save-temps*|traditional-cpp|no-integrated-cpp:%(trad_capable_cpp) \
%(cpp_options) -o %{save-temps*:%b.i} %{!save-temps*:%g.i} \n\
- cc1 -fpreprocessed %{save-temps*:%b.i} %{!save-temps*:%g.i} \
+ cc1 %I -fpreprocessed %{save-temps*:%b.i} %{!save-temps*:%g.i} \
%(cc1_options)}\
%{!save-temps*:%{!traditional-cpp:%{!no-integrated-cpp:\
- cc1 %(cpp_unique_options) %(cc1_options)}}}\
+ cc1 %I %(cpp_unique_options) %(cc1_options)}}}\
%{!fsyntax-only:%(invoke_as)}}}}", 0, 0, 1},
{"-",
"%{!E:%e-E or -x required when input is from standard input}\
@@ -1485,19 +1485,19 @@ static const struct compiler default_compilers[] =
%{!E:%{!M:%{!MM:\
%{save-temps*|traditional-cpp|no-integrated-cpp:%(trad_capable_cpp) \
%(cpp_options) -o %{save-temps*:%b.i} %{!save-temps*:%g.i} \n\
- cc1 -fpreprocessed %{save-temps*:%b.i} %{!save-temps*:%g.i}
\
+ cc1 %I -fpreprocessed %{save-temps*:%b.i}
%{!save-temps*:%g.i} \
%(cc1_options)\
%{!fsyntax-only:%{!S:-o %g.s} \
%{!fdump-ada-spec*:%{!o*:--output-pch %w%i.gch}\
%W{o*:--output-pch
%w%*}}%{!S:%V}}}\
%{!save-temps*:%{!traditional-cpp:%{!no-integrated-cpp:\
- cc1 %(cpp_unique_options) %(cc1_options)\
+ cc1 %I %(cpp_unique_options) %(cc1_options)\
%{!fsyntax-only:%{!S:-o %g.s} \
%{!fdump-ada-spec*:%{!o*:--output-pch %w%i.gch}\
%W{o*:--output-pch
%w%*}}%{!S:%V}}}}}}}}", 0, 0, 0},
{".i", "@cpp-output", 0, 0, 0},
{"@cpp-output",
- "%{!M:%{!MM:%{!E:cc1 -fpreprocessed %i %(cc1_options)
%{!fsyntax-only:%(invoke_as)}}}}", 0, 0, 0},
+ "%{!M:%{!MM:%{!E:cc1 %I -fpreprocessed %i %(cc1_options)
%{!fsyntax-only:%(invoke_as)}}}}", 0, 0, 0},
{".s", "@assembler", 0, 0, 0},
{"@assembler",
"%{!M:%{!MM:%{!E:%{!S:as %(asm_debug) %(asm_options) %i %A }}}}", 0, 0, 0},
@@ -6146,6 +6146,8 @@ do_spec_1 (const char *spec, int inswitch, const char
*soft_matched_part)
argbuf.pop ();
}
+ if (gcc_exec_prefix)
+ xputenv (concat ("GCC_EXEC_PREFIX=", gcc_exec_prefix, NULL));
set_collect_gcc_options ();
if (argbuf.length () > 0)
--
2.34.1