Another approach for fixing this: https://patchwork.sourceware.org/project/gcc/patch/[email protected]/
On Tue, Nov 11, 2025 at 11:03 AM Kito Cheng <[email protected]> wrote: > > I found that the title might be misleading, so I’ll fix it in v2. > The problem actually also occurs when the input is a preprocessed file > (e.g. .i or .ii). > > $ riscv64-unknown-elf-gcc x.i > cc1: error: /home/scratch/build/install/riscv64-unknown-elf/usr/local/include: > Permission denied > cc1: error: /home/scratch/build/install/riscv64-unknown-elf/include: > Permission denied > > > On Tue, Nov 11, 2025 at 10:53 AM Kito Cheng <[email protected]> wrote: > > > > 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 > >
