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
> >

Reply via email to