[cfe-dev] --gcc-toolchain (GCC_INSTALL_PREFIX) and --prefix(-B)

Fāng-ruì Sòng via cfe-dev cfe-dev at lists.llvm.org
Thu Mar 4 15:13:39 PST 2021


On Thu, Mar 4, 2021 at 2:31 PM Hubert Tong
<hubert.reinterpretcast at gmail.com> wrote:
>
> On Thu, Mar 4, 2021 at 1:54 PM Fāng-ruì Sòng <maskray at google.com> wrote:
>>
>> On 2021-03-04, Hubert Tong wrote:
>> >On Thu, Mar 4, 2021 at 3:19 AM Fāng-ruì Sòng via cfe-dev <
>> >cfe-dev at lists.llvm.org> wrote:
>> >
>> >> If --gcc-toolchain is specified, its value overrides the cmake variable
>> >> GCC_INSTALL_PREFIX.
>> >> When the value is non-empty: the value is appended to the --prefix list
>> >> and is used to detect GCC installations.
>> >> The GCC installation is used to provide include directories/library
>> >> directories and some startup files (e.g. crtbegin).
>> >>
>> >> Problem 1.
>> >>
>> >> --prefix(-B) does more than --gcc-toolchain:
>> >> clang::driver::Driver::GetProgramPath basically searches for
>> >> $prefix/$triple-$file and $prefix$file,
>> >> where $prefix is taken from the list of --prefix(-B). --gcc-toolchain does
>> >> not participate in the search. <have attached a summary of the algorithm at
>> >> the bottom>
>> >> The result is that 'ld' and 'as' may come from the system (more precisely,
>> >> sysroot):
>> >>
>> >> cd clang/test/Driver
>> >> # Make sure Inputs/opensuse_42.2_aarch64_tree/usr/bin/ld exists.
>> >> clang -target aarch64-suse-linux
>> >> --gcc-toolchain=Inputs/opensuse_42.2_aarch64_tree/usr '-###'
>> >> gcc-toolchain.cpp -v
>> >>
>> >>    # I have ld in my /usr/local/bin and it takes precedence over
>> >> /usr/bin/ld
>> >>  "/usr/local/bin/ld" "-EL" "--eh-frame-hdr" "-m" "aarch64linux"
>> >> "-dynamic-linker" "/lib/ld-linux-aarch64.so.1" "-o" "a.out"
>> >> "Inputs/opensuse_42.2_aarch64_tree/usr/lib64/gcc/aarch64-suse-linux/4.8/../../../../lib64/crt1.o"
>> >> "Inputs/opensuse_42.2_aarch64_tree/usr/lib64/gcc/aarch64-suse-linux/4.8/../../../../lib64/crti.o"
>> >> "Inputs/opensuse_42.2_aarch64_tree/usr/lib64/gcc/aarch64-suse-linux/4.8/crtbegin.o"
>> >> "-LInputs/opensuse_42.2_aarch64_tree/usr/lib64/gcc/aarch64-suse-linux/4.8"
>> >> "-LInputs/opensuse_42.2_aarch64_tree/usr/lib64/gcc/aarch64-suse-linux/4.8/../../../../lib64"
>> >> "-L/lib/aarch64-linux-gnu" "-L/lib/../lib64" "-L/usr/lib/aarch64-linux-gnu"
>> >> "-L/usr/lib/../lib64"
>> >> "-LInputs/opensuse_42.2_aarch64_tree/usr/lib64/gcc/aarch64-suse-linux/4.8/../../.."
>> >> "-L/tmp/RelA/bin/../lib" "-L/lib" "-L/usr/lib"
>> >> "/tmp/gcc-toolchain-f87f08.o" "-lgcc" "--as-needed" "-lgcc_s"
>> >> "--no-as-needed" "-lc" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed"
>> >> "Inputs/opensuse_42.2_aarch64_tree/usr/lib64/gcc/aarch64-suse-linux/4.8/crtend.o"
>> >> "Inputs/opensuse_42.2_aarch64_tree/usr/lib64/gcc/aarch64-suse-linux/4.8/../../../../lib64/crtn.o"
>> >>
>> >> The -L and crt* files are indeed from
>> >> Inputs/opensuse_42.2_aarch64_tree/usr, but ld (and as if
>> >> -fno-integrated-as) is from the system.
>> >> On many Linux distributions you can normally assume that the system ld and
>> >> as only support the host architecture.
>> >> This means --gcc-toolchain can only be used to specify a GCC installation
>> >> with the same architecture.
>> >>
>> >... and specifying a GCC installation with the same architecture (e.g., to
>> >use a newer libstdc++) is something that people do:
>> >$ clang++ -fuse-ld=ld --gcc-toolchain=/opt/rh/devtoolset-7/root -xc -
>> >-fno-integrated-as <<<'#include <stdio.h>'$'\n''int main(void) {
>> >printf("Hello, world!\n"); }' && echo OKAY
>> >OKAY
>> >... but it does seem ld is coming from --gcc-toolchain for me anyway:
>> >$ ./build/bootstrap/stage1/build/bin/clang++ -fuse-ld=ld
>> >--gcc-toolchain=/opt/rh/devtoolset-7/root -xc - -fno-integrated-as
>> ><<<'#include <stdio.h>'$'\n''int main(void) { printf("Hello, world!\n"); }'
>> >-### 2>&1 | grep /ld
>> > "/opt/rh/devtoolset-7/root/lib/gcc/ppc64le-redhat-linux/7/../../../../bin/ld"
>> >"--hash-style=gnu" "--eh-frame-hdr" "-m" "elf64lppc" "-dynamic-linker"
>> >"/lib64/ld64.so.2" "-o" "a.out" "/lib/../lib64/crt1.o"
>> >"/lib/../lib64/crti.o"
>> >"/opt/rh/devtoolset-7/root/lib/gcc/ppc64le-redhat-linux/7/crtbegin.o"
>> >"-L/opt/rh/devtoolset-7/root/lib/gcc/ppc64le-redhat-linux/7"
>> >"-L/opt/rh/devtoolset-7/root/lib/gcc/ppc64le-redhat-linux/7/../../../../lib64"
>> >"-L/lib/powerpc64le-linux-gnu" "-L/lib/../lib64"
>> >"-L/usr/lib/powerpc64le-linux-gnu" "-L/usr/lib/../lib64"
>> >"-L/opt/rh/devtoolset-7/root/lib/gcc/ppc64le-redhat-linux/7/../../.."
>> >"-L/data1/hstong.local/wybuild/build/bootstrap/stage1/build/bin/../lib"
>> >"-L/lib" "-L/usr/lib" "/tmp/--8f8c6a.o" "-lstdc++" "-lm" "-lgcc_s" "-lgcc"
>> >"-lc" "-lgcc_s" "-lgcc"
>> >"/opt/rh/devtoolset-7/root/lib/gcc/ppc64le-redhat-linux/7/crtend.o"
>> >"/lib/../lib64/crtn.o"
>>
>> 'ld' path is computed by clang/lib/Driver/Driver.cpp Driver::GetProgramPath.
>> Did you set PATH to the devtoolset-7 bin directory?
>
> No, I did not.

Do you mind debugging clang '-###' a bit: set a breakpoint on
clang/lib/Driver/Driver.cpp `GetProgramPath` and report how the 'ld'
under --gcc-toolchain is selected?

>>
>>
>> If --gcc-toolchain and multiple -B are specified, the search order is:
>>
>> -B -B -B --gcc-toolchain
>>
>> Currently the GCC installation with the largest version wins.
>> Do you think we should stop search after one -B provides a GCC installation?
>
> Well, the ordering where --gcc-toolchain follows all of the -B seems okay in the context of looking for ld or as. For changing "largest version wins", it might make some sense to order --gcc-toolchain first for the resolution of the GCC installation (which allows "largest version wins" to continue with -B). I suppose it means people using builds preconfigured with a GCC install prefix will be somewhat inconvenienced when they don't want to use the preconfigured path; however, I think this retains most functionality (there is a way to limit the search for GCC installations but also a way to compose search paths for the latest GCC version).

If cmake GCC_INSTALL_PREFIX was specified configuring llvm-project, I
think it makes sense that explicit options (-B, --gcc-toolchain) take
precedence over GCC_INSTALL_PREFIX.
When --gcc-toolchain is specified: yes, probably it should take
precedence over --prefix. I wonder whether it should suppress --prefix
for GCC installation.

I played with gcc -B a bit: looks like it picks the first --prefix
where files can be found. So I am going to send a patch making the
"largest version wins" local to one -B (i.e. if multiple versions are
detected, pick the largest).


>>
>>
>> >> --prefix can make as and ld paths correct, but: if another --prefix is
>> >> needed, why do we use --gcc-toolchain?
>> >>
>> >Well, I'm not sure that another --prefix is needed. Also, --prefix doesn't
>> >help to pick up the GCC header and library paths and --sysroot overrides
>> >too much:
>> >$ clang++ -fuse-ld=ld --sysroot=/opt/rh/devtoolset-7/root -xc -
>> >-fno-integrated-as <<<'#include <stdio.h>'$'\n''int main(void) {
>> >printf("Hello, world!\n"); }'
>> ><stdin>:1:10: fatal error: 'stdio.h' file not found
>> >#include <stdio.h>
>> >         ^~~~~~~~~
>> >1 error generated.
>>
>> (The example used --sysroot instead of --prefix)
>
> Yes.
>
>>
>>
>> OK, your other reply clarified that --prefix does pick up include/library directories.
>
> Yes.



-- 
宋方睿


More information about the cfe-dev mailing list