linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3] Makefile: Fix GCC_TOOLCHAIN_DIR prefix for Clang cross compilation
@ 2020-07-21 17:31 Fangrui Song
  2020-07-21 17:55 ` Nick Desaulniers
  2020-07-21 22:14 ` Masahiro Yamada
  0 siblings, 2 replies; 6+ messages in thread
From: Fangrui Song @ 2020-07-21 17:31 UTC (permalink / raw)
  To: Masahiro Yamada, Michal Marek, linux-kbuild, linux-kernel,
	clang-built-linux
  Cc: Jian Cai, Bill Wendling, Manoj Gupta, Fangrui Song, stable,
	Nathan Chancellor, Nick Desaulniers

When CROSS_COMPILE is set (e.g. aarch64-linux-gnu-), if
$(CROSS_COMPILE)elfedit is found at /usr/bin/aarch64-linux-gnu-elfedit,
GCC_TOOLCHAIN_DIR will be set to /usr/bin/.  --prefix= will be set to
/usr/bin/ and Clang as of 11 will search for both
$(prefix)aarch64-linux-gnu-$needle and $(prefix)$needle.

GCC searchs for $(prefix)aarch64-linux-gnu/$version/$needle,
$(prefix)aarch64-linux-gnu/$needle and $(prefix)$needle. In practice,
$(prefix)aarch64-linux-gnu/$needle rarely contains executables.

To better model how GCC's -B/--prefix takes in effect in practice, newer
Clang (since
https://github.com/llvm/llvm-project/commit/3452a0d8c17f7166f479706b293caf6ac76ffd90)
only searches for $(prefix)$needle. Currently it will find /usr/bin/as
instead of /usr/bin/aarch64-linux-gnu-as.

Set --prefix= to $(GCC_TOOLCHAIN_DIR)$(CROSS_COMPILE)
(/usr/bin/aarch64-linux-gnu-) so that newer Clang can find the
appropriate cross compiling GNU as (when -no-integrated-as is in
effect).

Cc: stable@vger.kernel.org
Reported-by: Nathan Chancellor <natechancellor@gmail.com>
Signed-off-by: Fangrui Song <maskray@google.com>
Reviewed-by: Nathan Chancellor <natechancellor@gmail.com>
Tested-by: Nathan Chancellor <natechancellor@gmail.com>
Tested-by: Nick Desaulniers <ndesaulniers@google.com>
Link: https://github.com/ClangBuiltLinux/linux/issues/1099
---
Changes in v2:
* Updated description to add tags and the llvm-project commit link.
* Fixed a typo.

Changes in v3:
* Add Cc: stable@vger.kernel.org
---
 Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Makefile b/Makefile
index 0b5f8538bde5..3ac83e375b61 100644
--- a/Makefile
+++ b/Makefile
@@ -567,7 +567,7 @@ ifneq ($(shell $(CC) --version 2>&1 | head -n 1 | grep clang),)
 ifneq ($(CROSS_COMPILE),)
 CLANG_FLAGS	+= --target=$(notdir $(CROSS_COMPILE:%-=%))
 GCC_TOOLCHAIN_DIR := $(dir $(shell which $(CROSS_COMPILE)elfedit))
-CLANG_FLAGS	+= --prefix=$(GCC_TOOLCHAIN_DIR)
+CLANG_FLAGS	+= --prefix=$(GCC_TOOLCHAIN_DIR)$(CROSS_COMPILE)
 GCC_TOOLCHAIN	:= $(realpath $(GCC_TOOLCHAIN_DIR)/..)
 endif
 ifneq ($(GCC_TOOLCHAIN),)
-- 
2.28.0.rc0.105.gf9edc3c819-goog


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v3] Makefile: Fix GCC_TOOLCHAIN_DIR prefix for Clang cross compilation
  2020-07-21 17:31 [PATCH v3] Makefile: Fix GCC_TOOLCHAIN_DIR prefix for Clang cross compilation Fangrui Song
@ 2020-07-21 17:55 ` Nick Desaulniers
  2020-07-21 22:14 ` Masahiro Yamada
  1 sibling, 0 replies; 6+ messages in thread
From: Nick Desaulniers @ 2020-07-21 17:55 UTC (permalink / raw)
  To: Fangrui Song
  Cc: Masahiro Yamada, Michal Marek, Linux Kbuild mailing list, LKML,
	clang-built-linux, Jian Cai, Bill Wendling, Manoj Gupta, # 3.4.x,
	Nathan Chancellor

On Tue, Jul 21, 2020 at 10:31 AM Fangrui Song <maskray@google.com> wrote:
>
> When CROSS_COMPILE is set (e.g. aarch64-linux-gnu-), if
> $(CROSS_COMPILE)elfedit is found at /usr/bin/aarch64-linux-gnu-elfedit,
> GCC_TOOLCHAIN_DIR will be set to /usr/bin/.  --prefix= will be set to
> /usr/bin/ and Clang as of 11 will search for both
> $(prefix)aarch64-linux-gnu-$needle and $(prefix)$needle.
>
> GCC searchs for $(prefix)aarch64-linux-gnu/$version/$needle,
> $(prefix)aarch64-linux-gnu/$needle and $(prefix)$needle. In practice,
> $(prefix)aarch64-linux-gnu/$needle rarely contains executables.
>
> To better model how GCC's -B/--prefix takes in effect in practice, newer
> Clang (since
> https://github.com/llvm/llvm-project/commit/3452a0d8c17f7166f479706b293caf6ac76ffd90)
> only searches for $(prefix)$needle. Currently it will find /usr/bin/as
> instead of /usr/bin/aarch64-linux-gnu-as.
>
> Set --prefix= to $(GCC_TOOLCHAIN_DIR)$(CROSS_COMPILE)
> (/usr/bin/aarch64-linux-gnu-) so that newer Clang can find the
> appropriate cross compiling GNU as (when -no-integrated-as is in
> effect).
>
> Cc: stable@vger.kernel.org
> Reported-by: Nathan Chancellor <natechancellor@gmail.com>
> Signed-off-by: Fangrui Song <maskray@google.com>
> Reviewed-by: Nathan Chancellor <natechancellor@gmail.com>
> Tested-by: Nathan Chancellor <natechancellor@gmail.com>
> Tested-by: Nick Desaulniers <ndesaulniers@google.com>

Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>

> Link: https://github.com/ClangBuiltLinux/linux/issues/1099
> ---
> Changes in v2:
> * Updated description to add tags and the llvm-project commit link.
> * Fixed a typo.
>
> Changes in v3:
> * Add Cc: stable@vger.kernel.org
> ---
>  Makefile | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/Makefile b/Makefile
> index 0b5f8538bde5..3ac83e375b61 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -567,7 +567,7 @@ ifneq ($(shell $(CC) --version 2>&1 | head -n 1 | grep clang),)
>  ifneq ($(CROSS_COMPILE),)
>  CLANG_FLAGS    += --target=$(notdir $(CROSS_COMPILE:%-=%))
>  GCC_TOOLCHAIN_DIR := $(dir $(shell which $(CROSS_COMPILE)elfedit))
> -CLANG_FLAGS    += --prefix=$(GCC_TOOLCHAIN_DIR)
> +CLANG_FLAGS    += --prefix=$(GCC_TOOLCHAIN_DIR)$(CROSS_COMPILE)
>  GCC_TOOLCHAIN  := $(realpath $(GCC_TOOLCHAIN_DIR)/..)
>  endif
>  ifneq ($(GCC_TOOLCHAIN),)
> --
> 2.28.0.rc0.105.gf9edc3c819-goog
>


-- 
Thanks,
~Nick Desaulniers

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v3] Makefile: Fix GCC_TOOLCHAIN_DIR prefix for Clang cross compilation
  2020-07-21 17:31 [PATCH v3] Makefile: Fix GCC_TOOLCHAIN_DIR prefix for Clang cross compilation Fangrui Song
  2020-07-21 17:55 ` Nick Desaulniers
@ 2020-07-21 22:14 ` Masahiro Yamada
  2020-07-22  0:14   ` Fangrui Song
  1 sibling, 1 reply; 6+ messages in thread
From: Masahiro Yamada @ 2020-07-21 22:14 UTC (permalink / raw)
  To: Fangrui Song
  Cc: Michal Marek, Linux Kbuild mailing list,
	Linux Kernel Mailing List, clang-built-linux, Jian Cai,
	Bill Wendling, Manoj Gupta, stable, Nathan Chancellor,
	Nick Desaulniers

On Wed, Jul 22, 2020 at 2:31 AM 'Fangrui Song' via Clang Built Linux
<clang-built-linux@googlegroups.com> wrote:
>
> When CROSS_COMPILE is set (e.g. aarch64-linux-gnu-), if
> $(CROSS_COMPILE)elfedit is found at /usr/bin/aarch64-linux-gnu-elfedit,
> GCC_TOOLCHAIN_DIR will be set to /usr/bin/.  --prefix= will be set to
> /usr/bin/ and Clang as of 11 will search for both
> $(prefix)aarch64-linux-gnu-$needle and $(prefix)$needle.
>
> GCC searchs for $(prefix)aarch64-linux-gnu/$version/$needle,
> $(prefix)aarch64-linux-gnu/$needle and $(prefix)$needle. In practice,
> $(prefix)aarch64-linux-gnu/$needle rarely contains executables.
>
> To better model how GCC's -B/--prefix takes in effect in practice, newer
> Clang (since
> https://github.com/llvm/llvm-project/commit/3452a0d8c17f7166f479706b293caf6ac76ffd90)
> only searches for $(prefix)$needle. Currently it will find /usr/bin/as
> instead of /usr/bin/aarch64-linux-gnu-as.
>
> Set --prefix= to $(GCC_TOOLCHAIN_DIR)$(CROSS_COMPILE)
> (/usr/bin/aarch64-linux-gnu-) so that newer Clang can find the
> appropriate cross compiling GNU as (when -no-integrated-as is in
> effect).
>
> Cc: stable@vger.kernel.org
> Reported-by: Nathan Chancellor <natechancellor@gmail.com>
> Signed-off-by: Fangrui Song <maskray@google.com>
> Reviewed-by: Nathan Chancellor <natechancellor@gmail.com>
> Tested-by: Nathan Chancellor <natechancellor@gmail.com>
> Tested-by: Nick Desaulniers <ndesaulniers@google.com>
> Link: https://github.com/ClangBuiltLinux/linux/issues/1099
> ---
> Changes in v2:
> * Updated description to add tags and the llvm-project commit link.
> * Fixed a typo.
>
> Changes in v3:
> * Add Cc: stable@vger.kernel.org
> ---
>  Makefile | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/Makefile b/Makefile
> index 0b5f8538bde5..3ac83e375b61 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -567,7 +567,7 @@ ifneq ($(shell $(CC) --version 2>&1 | head -n 1 | grep clang),)
>  ifneq ($(CROSS_COMPILE),)
>  CLANG_FLAGS    += --target=$(notdir $(CROSS_COMPILE:%-=%))
>  GCC_TOOLCHAIN_DIR := $(dir $(shell which $(CROSS_COMPILE)elfedit))
> -CLANG_FLAGS    += --prefix=$(GCC_TOOLCHAIN_DIR)
> +CLANG_FLAGS    += --prefix=$(GCC_TOOLCHAIN_DIR)$(CROSS_COMPILE)



CROSS_COMPILE may contain the directory path
to the cross toolchains.


For example, I use aarch64-linux-gnu-*
installed in
/home/masahiro/tools/aarch64-linaro-7.5/bin



Basically, there are two ways to use it.

[1]
PATH=$PATH:/home/masahiro/tools/aarch64-linaro-7.5/bin
CROSS_COMPILE=aarch64-linux-gnu-


[2]
Without setting PATH,
CROSS_COMPILE=~/tools/aarch64-linaro-7.5/bin/aarch64-linux-gnu-



I usually do [2] (and so does intel's 0day bot).



This patch works for the use-case [1]
but if I do [2], --prefix is set to a strange path:

--prefix=/home/masahiro/tools/aarch64-linaro-7.5/bin//home/masahiro/tools/aarch64-linaro-7.5/bin/aarch64-linux-gnu-



Interestingly, the build is still successful.
Presumably Clang searches for more paths
when $(prefix)$needle is not found ?



I applied your patch and added -v option
to see which assembler was internally invoked:

 "/home/masahiro/tools/aarch64-linaro-7.5/lib/gcc/aarch64-linux-gnu/7.5.0/../../../../aarch64-linux-gnu/bin/as"
-EL -I ./arch/arm64/include -I ./arch/arm64/include/generated -I
./include -I ./arch/arm64/include/uapi -I
./arch/arm64/include/generated/uapi -I ./include/uapi -I
./include/generated/uapi -o kernel/smp.o /tmp/smp-2ec2c7.s


Ok, it looks like Clang found an alternative path
to the correct 'as'.




But, to keep the original behavior for both [1] and [2],
how about this?

CLANG_FLAGS += --prefix=$(GCC_TOOLCHAIN_DIR)$(notdir $(CROSS_COMPILE))



Then, I can get this:

 "/home/masahiro/tools/aarch64-linaro-7.5/bin/aarch64-linux-gnu-as"
-EL -I ./arch/arm64/include -I ./arch/arm64/include/generated -I
./include -I ./arch/arm64/include/uapi -I
./arch/arm64/include/generated/uapi -I ./include/uapi -I
./include/generated/uapi -o kernel/smp.o /tmp/smp-16d76f.s





>  GCC_TOOLCHAIN  := $(realpath $(GCC_TOOLCHAIN_DIR)/..)
>  endif
>  ifneq ($(GCC_TOOLCHAIN),)
> --
> 2.28.0.rc0.105.gf9edc3c819-goog
>
> --
> You received this message because you are subscribed to the Google Groups "Clang Built Linux" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to clang-built-linux+unsubscribe@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/clang-built-linux/20200721173125.1273884-1-maskray%40google.com.



--
Best Regards
Masahiro Yamada

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v3] Makefile: Fix GCC_TOOLCHAIN_DIR prefix for Clang cross compilation
  2020-07-21 22:14 ` Masahiro Yamada
@ 2020-07-22  0:14   ` Fangrui Song
  2020-07-22  1:36     ` Masahiro Yamada
  0 siblings, 1 reply; 6+ messages in thread
From: Fangrui Song @ 2020-07-22  0:14 UTC (permalink / raw)
  To: Masahiro Yamada
  Cc: Michal Marek, Linux Kbuild mailing list,
	Linux Kernel Mailing List, clang-built-linux, Jian Cai,
	Bill Wendling, Manoj Gupta, stable, Nathan Chancellor,
	Nick Desaulniers

On 2020-07-22, Masahiro Yamada wrote:
>On Wed, Jul 22, 2020 at 2:31 AM 'Fangrui Song' via Clang Built Linux
><clang-built-linux@googlegroups.com> wrote:
>>
>> When CROSS_COMPILE is set (e.g. aarch64-linux-gnu-), if
>> $(CROSS_COMPILE)elfedit is found at /usr/bin/aarch64-linux-gnu-elfedit,
>> GCC_TOOLCHAIN_DIR will be set to /usr/bin/.  --prefix= will be set to
>> /usr/bin/ and Clang as of 11 will search for both
>> $(prefix)aarch64-linux-gnu-$needle and $(prefix)$needle.
>>
>> GCC searchs for $(prefix)aarch64-linux-gnu/$version/$needle,
>> $(prefix)aarch64-linux-gnu/$needle and $(prefix)$needle. In practice,
>> $(prefix)aarch64-linux-gnu/$needle rarely contains executables.
>>
>> To better model how GCC's -B/--prefix takes in effect in practice, newer
>> Clang (since
>> https://github.com/llvm/llvm-project/commit/3452a0d8c17f7166f479706b293caf6ac76ffd90)
>> only searches for $(prefix)$needle. Currently it will find /usr/bin/as
>> instead of /usr/bin/aarch64-linux-gnu-as.
>>
>> Set --prefix= to $(GCC_TOOLCHAIN_DIR)$(CROSS_COMPILE)
>> (/usr/bin/aarch64-linux-gnu-) so that newer Clang can find the
>> appropriate cross compiling GNU as (when -no-integrated-as is in
>> effect).
>>
>> Cc: stable@vger.kernel.org
>> Reported-by: Nathan Chancellor <natechancellor@gmail.com>
>> Signed-off-by: Fangrui Song <maskray@google.com>
>> Reviewed-by: Nathan Chancellor <natechancellor@gmail.com>
>> Tested-by: Nathan Chancellor <natechancellor@gmail.com>
>> Tested-by: Nick Desaulniers <ndesaulniers@google.com>
>> Link: https://github.com/ClangBuiltLinux/linux/issues/1099
>> ---
>> Changes in v2:
>> * Updated description to add tags and the llvm-project commit link.
>> * Fixed a typo.
>>
>> Changes in v3:
>> * Add Cc: stable@vger.kernel.org
>> ---
>>  Makefile | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/Makefile b/Makefile
>> index 0b5f8538bde5..3ac83e375b61 100644
>> --- a/Makefile
>> +++ b/Makefile
>> @@ -567,7 +567,7 @@ ifneq ($(shell $(CC) --version 2>&1 | head -n 1 | grep clang),)
>>  ifneq ($(CROSS_COMPILE),)
>>  CLANG_FLAGS    += --target=$(notdir $(CROSS_COMPILE:%-=%))
>>  GCC_TOOLCHAIN_DIR := $(dir $(shell which $(CROSS_COMPILE)elfedit))
>> -CLANG_FLAGS    += --prefix=$(GCC_TOOLCHAIN_DIR)
>> +CLANG_FLAGS    += --prefix=$(GCC_TOOLCHAIN_DIR)$(CROSS_COMPILE)
>
>
>
>CROSS_COMPILE may contain the directory path
>to the cross toolchains.
>
>
>For example, I use aarch64-linux-gnu-*
>installed in
>/home/masahiro/tools/aarch64-linaro-7.5/bin
>
>
>
>Basically, there are two ways to use it.
>
>[1]
>PATH=$PATH:/home/masahiro/tools/aarch64-linaro-7.5/bin
>CROSS_COMPILE=aarch64-linux-gnu-
>
>
>[2]
>Without setting PATH,
>CROSS_COMPILE=~/tools/aarch64-linaro-7.5/bin/aarch64-linux-gnu-
>
>
>
>I usually do [2] (and so does intel's 0day bot).
>
>
>
>This patch works for the use-case [1]
>but if I do [2], --prefix is set to a strange path:
>
>--prefix=/home/masahiro/tools/aarch64-linaro-7.5/bin//home/masahiro/tools/aarch64-linaro-7.5/bin/aarch64-linux-gnu-

Thanks. I did not know the use-case [2].
This explains why there is a `$(notdir ...)` in
`CLANG_FLAGS     += --target=$(notdir $(CROSS_COMPILE:%-=%))`


>
>
>Interestingly, the build is still successful.
>Presumably Clang searches for more paths
>when $(prefix)$needle is not found ?

The priority order is:

-B(--prefix), COMPILER_PATH, detected gcc-cross paths

(In GCC, -B paths get prepended to the COMPILER_PATH list. Clang<=11 incorrectly
adds -B to the COMPILER_PATH list. I have fixed it for 12.0.0)

If -B fails, the detected gcc-cross paths may still be able to find 
/usr/bin/aarch64-linux-gnu-

For example, on my machine (a variant of Debian testing), Clang finds
$(realpath
/usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/as),
which is /usr/bin/aarch64-linux-gnu-as

>
>I applied your patch and added -v option
>to see which assembler was internally invoked:
>
> "/home/masahiro/tools/aarch64-linaro-7.5/lib/gcc/aarch64-linux-gnu/7.5.0/../../../../aarch64-linux-gnu/bin/as"
>-EL -I ./arch/arm64/include -I ./arch/arm64/include/generated -I
>./include -I ./arch/arm64/include/uapi -I
>./arch/arm64/include/generated/uapi -I ./include/uapi -I
>./include/generated/uapi -o kernel/smp.o /tmp/smp-2ec2c7.s
>
>
>Ok, it looks like Clang found an alternative path
>to the correct 'as'.
>
>
>
>
>But, to keep the original behavior for both [1] and [2],
>how about this?
>
>CLANG_FLAGS += --prefix=$(GCC_TOOLCHAIN_DIR)$(notdir $(CROSS_COMPILE))
>
>
>
>Then, I can get this:
>
> "/home/masahiro/tools/aarch64-linaro-7.5/bin/aarch64-linux-gnu-as"
>-EL -I ./arch/arm64/include -I ./arch/arm64/include/generated -I
>./include -I ./arch/arm64/include/uapi -I
>./arch/arm64/include/generated/uapi -I ./include/uapi -I
>./include/generated/uapi -o kernel/smp.o /tmp/smp-16d76f.s

This looks good.

Agreed that `--prefix=$(GCC_TOOLCHAIN_DIR)$(notdir $(CROSS_COMPILE))` should work for both [1] and [2].

Shall I send a v4? Or you are kind enough that you'll just add your Signed-off-by: tag
and fix that for me? :)

>
>
>>  GCC_TOOLCHAIN  := $(realpath $(GCC_TOOLCHAIN_DIR)/..)
>>  endif
>>  ifneq ($(GCC_TOOLCHAIN),)
>> --
>> 2.28.0.rc0.105.gf9edc3c819-goog
>>
>> --
>> You received this message because you are subscribed to the Google Groups "Clang Built Linux" group.
>> To unsubscribe from this group and stop receiving emails from it, send an email to clang-built-linux+unsubscribe@googlegroups.com.
>> To view this discussion on the web visit https://groups.google.com/d/msgid/clang-built-linux/20200721173125.1273884-1-maskray%40google.com.
>
>
>
>--
>Best Regards
>Masahiro Yamada

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v3] Makefile: Fix GCC_TOOLCHAIN_DIR prefix for Clang cross compilation
  2020-07-22  0:14   ` Fangrui Song
@ 2020-07-22  1:36     ` Masahiro Yamada
  2020-07-22  5:45       ` Fangrui Song
  0 siblings, 1 reply; 6+ messages in thread
From: Masahiro Yamada @ 2020-07-22  1:36 UTC (permalink / raw)
  To: Fangrui Song
  Cc: Michal Marek, Linux Kbuild mailing list,
	Linux Kernel Mailing List, clang-built-linux, Jian Cai,
	Bill Wendling, Manoj Gupta, stable, Nathan Chancellor,
	Nick Desaulniers

On Wed, Jul 22, 2020 at 9:14 AM Fangrui Song <maskray@google.com> wrote:
>
> On 2020-07-22, Masahiro Yamada wrote:
> >On Wed, Jul 22, 2020 at 2:31 AM 'Fangrui Song' via Clang Built Linux
> ><clang-built-linux@googlegroups.com> wrote:
> >>
> >> When CROSS_COMPILE is set (e.g. aarch64-linux-gnu-), if
> >> $(CROSS_COMPILE)elfedit is found at /usr/bin/aarch64-linux-gnu-elfedit,
> >> GCC_TOOLCHAIN_DIR will be set to /usr/bin/.  --prefix= will be set to
> >> /usr/bin/ and Clang as of 11 will search for both
> >> $(prefix)aarch64-linux-gnu-$needle and $(prefix)$needle.
> >>
> >> GCC searchs for $(prefix)aarch64-linux-gnu/$version/$needle,
> >> $(prefix)aarch64-linux-gnu/$needle and $(prefix)$needle. In practice,
> >> $(prefix)aarch64-linux-gnu/$needle rarely contains executables.
> >>
> >> To better model how GCC's -B/--prefix takes in effect in practice, newer
> >> Clang (since
> >> https://github.com/llvm/llvm-project/commit/3452a0d8c17f7166f479706b293caf6ac76ffd90)
> >> only searches for $(prefix)$needle. Currently it will find /usr/bin/as
> >> instead of /usr/bin/aarch64-linux-gnu-as.
> >>
> >> Set --prefix= to $(GCC_TOOLCHAIN_DIR)$(CROSS_COMPILE)
> >> (/usr/bin/aarch64-linux-gnu-) so that newer Clang can find the
> >> appropriate cross compiling GNU as (when -no-integrated-as is in
> >> effect).
> >>
> >> Cc: stable@vger.kernel.org
> >> Reported-by: Nathan Chancellor <natechancellor@gmail.com>
> >> Signed-off-by: Fangrui Song <maskray@google.com>
> >> Reviewed-by: Nathan Chancellor <natechancellor@gmail.com>
> >> Tested-by: Nathan Chancellor <natechancellor@gmail.com>
> >> Tested-by: Nick Desaulniers <ndesaulniers@google.com>
> >> Link: https://github.com/ClangBuiltLinux/linux/issues/1099
> >> ---
> >> Changes in v2:
> >> * Updated description to add tags and the llvm-project commit link.
> >> * Fixed a typo.
> >>
> >> Changes in v3:
> >> * Add Cc: stable@vger.kernel.org
> >> ---
> >>  Makefile | 2 +-
> >>  1 file changed, 1 insertion(+), 1 deletion(-)
> >>
> >> diff --git a/Makefile b/Makefile
> >> index 0b5f8538bde5..3ac83e375b61 100644
> >> --- a/Makefile
> >> +++ b/Makefile
> >> @@ -567,7 +567,7 @@ ifneq ($(shell $(CC) --version 2>&1 | head -n 1 | grep clang),)
> >>  ifneq ($(CROSS_COMPILE),)
> >>  CLANG_FLAGS    += --target=$(notdir $(CROSS_COMPILE:%-=%))
> >>  GCC_TOOLCHAIN_DIR := $(dir $(shell which $(CROSS_COMPILE)elfedit))
> >> -CLANG_FLAGS    += --prefix=$(GCC_TOOLCHAIN_DIR)
> >> +CLANG_FLAGS    += --prefix=$(GCC_TOOLCHAIN_DIR)$(CROSS_COMPILE)
> >
> >
> >
> >CROSS_COMPILE may contain the directory path
> >to the cross toolchains.
> >
> >
> >For example, I use aarch64-linux-gnu-*
> >installed in
> >/home/masahiro/tools/aarch64-linaro-7.5/bin
> >
> >
> >
> >Basically, there are two ways to use it.
> >
> >[1]
> >PATH=$PATH:/home/masahiro/tools/aarch64-linaro-7.5/bin
> >CROSS_COMPILE=aarch64-linux-gnu-
> >
> >
> >[2]
> >Without setting PATH,
> >CROSS_COMPILE=~/tools/aarch64-linaro-7.5/bin/aarch64-linux-gnu-
> >
> >
> >
> >I usually do [2] (and so does intel's 0day bot).
> >
> >
> >
> >This patch works for the use-case [1]
> >but if I do [2], --prefix is set to a strange path:
> >
> >--prefix=/home/masahiro/tools/aarch64-linaro-7.5/bin//home/masahiro/tools/aarch64-linaro-7.5/bin/aarch64-linux-gnu-
>
> Thanks. I did not know the use-case [2].
> This explains why there is a `$(notdir ...)` in
> `CLANG_FLAGS     += --target=$(notdir $(CROSS_COMPILE:%-=%))`
>
>
> >
> >
> >Interestingly, the build is still successful.
> >Presumably Clang searches for more paths
> >when $(prefix)$needle is not found ?
>
> The priority order is:
>
> -B(--prefix), COMPILER_PATH, detected gcc-cross paths
>
> (In GCC, -B paths get prepended to the COMPILER_PATH list. Clang<=11 incorrectly
> adds -B to the COMPILER_PATH list. I have fixed it for 12.0.0)
>
> If -B fails, the detected gcc-cross paths may still be able to find
> /usr/bin/aarch64-linux-gnu-
>
> For example, on my machine (a variant of Debian testing), Clang finds
> $(realpath
> /usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/as),
> which is /usr/bin/aarch64-linux-gnu-as
>
> >
> >I applied your patch and added -v option
> >to see which assembler was internally invoked:
> >
> > "/home/masahiro/tools/aarch64-linaro-7.5/lib/gcc/aarch64-linux-gnu/7.5.0/../../../../aarch64-linux-gnu/bin/as"
> >-EL -I ./arch/arm64/include -I ./arch/arm64/include/generated -I
> >./include -I ./arch/arm64/include/uapi -I
> >./arch/arm64/include/generated/uapi -I ./include/uapi -I
> >./include/generated/uapi -o kernel/smp.o /tmp/smp-2ec2c7.s
> >
> >
> >Ok, it looks like Clang found an alternative path
> >to the correct 'as'.
> >
> >
> >
> >
> >But, to keep the original behavior for both [1] and [2],
> >how about this?
> >
> >CLANG_FLAGS += --prefix=$(GCC_TOOLCHAIN_DIR)$(notdir $(CROSS_COMPILE))
> >
> >
> >
> >Then, I can get this:
> >
> > "/home/masahiro/tools/aarch64-linaro-7.5/bin/aarch64-linux-gnu-as"
> >-EL -I ./arch/arm64/include -I ./arch/arm64/include/generated -I
> >./include -I ./arch/arm64/include/uapi -I
> >./arch/arm64/include/generated/uapi -I ./include/uapi -I
> >./include/generated/uapi -o kernel/smp.o /tmp/smp-16d76f.s
>
> This looks good.
>
> Agreed that `--prefix=$(GCC_TOOLCHAIN_DIR)$(notdir $(CROSS_COMPILE))` should work for both [1] and [2].
>
> Shall I send a v4? Or you are kind enough that you'll just add your Signed-off-by: tag
> and fix that for me? :)
>

I fixed it up and applied to linux-kbuild/fixes.
Thanks.




While I am here, could you teach me a bit more?


The top Makefile sets the following option as well:

CLANG_GCC_TC    := --gcc-toolchain=$(GCC_TOOLCHAIN)



I checked the manual:
https://clang.llvm.org/docs/ClangCommandLineReference.html


  -B<dir>, --prefix <arg>, --prefix=<arg>
  Add <dir> to search path for binaries and object files used implicitly

  --gcc-toolchain=<arg>, -gcc-toolchain <arg>
  Use the gcc toolchain at the given directory




It is not clear to me
how they work differently when
clang searches for toolchains.




If I delete --gcc-toolchain from the top Makefile,
clang fails to link standalone programs
because it wrongly invokes /usr/bin/ld
instead of aarch64-linux-gnu-ld.


Does Clang search for gnu assembler
based on --prefix option?

And, searches for a linker
based on --gcc-toolchain ?



-- 
Best Regards
Masahiro Yamada

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v3] Makefile: Fix GCC_TOOLCHAIN_DIR prefix for Clang cross compilation
  2020-07-22  1:36     ` Masahiro Yamada
@ 2020-07-22  5:45       ` Fangrui Song
  0 siblings, 0 replies; 6+ messages in thread
From: Fangrui Song @ 2020-07-22  5:45 UTC (permalink / raw)
  To: Masahiro Yamada
  Cc: Michal Marek, Linux Kbuild mailing list,
	Linux Kernel Mailing List, clang-built-linux, Jian Cai,
	Bill Wendling, Manoj Gupta, stable, Nathan Chancellor,
	Nick Desaulniers

On 2020-07-22, Masahiro Yamada wrote:
>On Wed, Jul 22, 2020 at 9:14 AM Fangrui Song <maskray@google.com> wrote:
>>
>> On 2020-07-22, Masahiro Yamada wrote:
>> >On Wed, Jul 22, 2020 at 2:31 AM 'Fangrui Song' via Clang Built Linux
>> ><clang-built-linux@googlegroups.com> wrote:
>> >>
>> >> When CROSS_COMPILE is set (e.g. aarch64-linux-gnu-), if
>> >> $(CROSS_COMPILE)elfedit is found at /usr/bin/aarch64-linux-gnu-elfedit,
>> >> GCC_TOOLCHAIN_DIR will be set to /usr/bin/.  --prefix= will be set to
>> >> /usr/bin/ and Clang as of 11 will search for both
>> >> $(prefix)aarch64-linux-gnu-$needle and $(prefix)$needle.
>> >>
>> >> GCC searchs for $(prefix)aarch64-linux-gnu/$version/$needle,
>> >> $(prefix)aarch64-linux-gnu/$needle and $(prefix)$needle. In practice,
>> >> $(prefix)aarch64-linux-gnu/$needle rarely contains executables.
>> >>
>> >> To better model how GCC's -B/--prefix takes in effect in practice, newer
>> >> Clang (since
>> >> https://github.com/llvm/llvm-project/commit/3452a0d8c17f7166f479706b293caf6ac76ffd90)
>> >> only searches for $(prefix)$needle. Currently it will find /usr/bin/as
>> >> instead of /usr/bin/aarch64-linux-gnu-as.
>> >>
>> >> Set --prefix= to $(GCC_TOOLCHAIN_DIR)$(CROSS_COMPILE)
>> >> (/usr/bin/aarch64-linux-gnu-) so that newer Clang can find the
>> >> appropriate cross compiling GNU as (when -no-integrated-as is in
>> >> effect).
>> >>
>> >> Cc: stable@vger.kernel.org
>> >> Reported-by: Nathan Chancellor <natechancellor@gmail.com>
>> >> Signed-off-by: Fangrui Song <maskray@google.com>
>> >> Reviewed-by: Nathan Chancellor <natechancellor@gmail.com>
>> >> Tested-by: Nathan Chancellor <natechancellor@gmail.com>
>> >> Tested-by: Nick Desaulniers <ndesaulniers@google.com>
>> >> Link: https://github.com/ClangBuiltLinux/linux/issues/1099
>> >> ---
>> >> Changes in v2:
>> >> * Updated description to add tags and the llvm-project commit link.
>> >> * Fixed a typo.
>> >>
>> >> Changes in v3:
>> >> * Add Cc: stable@vger.kernel.org
>> >> ---
>> >>  Makefile | 2 +-
>> >>  1 file changed, 1 insertion(+), 1 deletion(-)
>> >>
>> >> diff --git a/Makefile b/Makefile
>> >> index 0b5f8538bde5..3ac83e375b61 100644
>> >> --- a/Makefile
>> >> +++ b/Makefile
>> >> @@ -567,7 +567,7 @@ ifneq ($(shell $(CC) --version 2>&1 | head -n 1 | grep clang),)
>> >>  ifneq ($(CROSS_COMPILE),)
>> >>  CLANG_FLAGS    += --target=$(notdir $(CROSS_COMPILE:%-=%))
>> >>  GCC_TOOLCHAIN_DIR := $(dir $(shell which $(CROSS_COMPILE)elfedit))
>> >> -CLANG_FLAGS    += --prefix=$(GCC_TOOLCHAIN_DIR)
>> >> +CLANG_FLAGS    += --prefix=$(GCC_TOOLCHAIN_DIR)$(CROSS_COMPILE)
>> >
>> >
>> >
>> >CROSS_COMPILE may contain the directory path
>> >to the cross toolchains.
>> >
>> >
>> >For example, I use aarch64-linux-gnu-*
>> >installed in
>> >/home/masahiro/tools/aarch64-linaro-7.5/bin
>> >
>> >
>> >
>> >Basically, there are two ways to use it.
>> >
>> >[1]
>> >PATH=$PATH:/home/masahiro/tools/aarch64-linaro-7.5/bin
>> >CROSS_COMPILE=aarch64-linux-gnu-
>> >
>> >
>> >[2]
>> >Without setting PATH,
>> >CROSS_COMPILE=~/tools/aarch64-linaro-7.5/bin/aarch64-linux-gnu-
>> >
>> >
>> >
>> >I usually do [2] (and so does intel's 0day bot).
>> >
>> >
>> >
>> >This patch works for the use-case [1]
>> >but if I do [2], --prefix is set to a strange path:
>> >
>> >--prefix=/home/masahiro/tools/aarch64-linaro-7.5/bin//home/masahiro/tools/aarch64-linaro-7.5/bin/aarch64-linux-gnu-
>>
>> Thanks. I did not know the use-case [2].
>> This explains why there is a `$(notdir ...)` in
>> `CLANG_FLAGS     += --target=$(notdir $(CROSS_COMPILE:%-=%))`
>>
>>
>> >
>> >
>> >Interestingly, the build is still successful.
>> >Presumably Clang searches for more paths
>> >when $(prefix)$needle is not found ?
>>
>> The priority order is:
>>
>> -B(--prefix), COMPILER_PATH, detected gcc-cross paths
>>
>> (In GCC, -B paths get prepended to the COMPILER_PATH list. Clang<=11 incorrectly
>> adds -B to the COMPILER_PATH list. I have fixed it for 12.0.0)
>>
>> If -B fails, the detected gcc-cross paths may still be able to find
>> /usr/bin/aarch64-linux-gnu-
>>
>> For example, on my machine (a variant of Debian testing), Clang finds
>> $(realpath
>> /usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/as),
>> which is /usr/bin/aarch64-linux-gnu-as
>>
>> >
>> >I applied your patch and added -v option
>> >to see which assembler was internally invoked:
>> >
>> > "/home/masahiro/tools/aarch64-linaro-7.5/lib/gcc/aarch64-linux-gnu/7.5.0/../../../../aarch64-linux-gnu/bin/as"
>> >-EL -I ./arch/arm64/include -I ./arch/arm64/include/generated -I
>> >./include -I ./arch/arm64/include/uapi -I
>> >./arch/arm64/include/generated/uapi -I ./include/uapi -I
>> >./include/generated/uapi -o kernel/smp.o /tmp/smp-2ec2c7.s
>> >
>> >
>> >Ok, it looks like Clang found an alternative path
>> >to the correct 'as'.
>> >
>> >
>> >
>> >
>> >But, to keep the original behavior for both [1] and [2],
>> >how about this?
>> >
>> >CLANG_FLAGS += --prefix=$(GCC_TOOLCHAIN_DIR)$(notdir $(CROSS_COMPILE))
>> >
>> >
>> >
>> >Then, I can get this:
>> >
>> > "/home/masahiro/tools/aarch64-linaro-7.5/bin/aarch64-linux-gnu-as"
>> >-EL -I ./arch/arm64/include -I ./arch/arm64/include/generated -I
>> >./include -I ./arch/arm64/include/uapi -I
>> >./arch/arm64/include/generated/uapi -I ./include/uapi -I
>> >./include/generated/uapi -o kernel/smp.o /tmp/smp-16d76f.s
>>
>> This looks good.
>>
>> Agreed that `--prefix=$(GCC_TOOLCHAIN_DIR)$(notdir $(CROSS_COMPILE))` should work for both [1] and [2].
>>
>> Shall I send a v4? Or you are kind enough that you'll just add your Signed-off-by: tag
>> and fix that for me? :)
>>
>
>I fixed it up and applied to linux-kbuild/fixes.
>Thanks.

Thanks!

The description 'Set --prefix= to $(GCC_TOOLCHAIN_DIR)$(CROSS_COMPILE)'
should probably be fixed to say '$(GCC_TOOLCHAIN_DIR)$(notdir $(CROSS_COMPILE))'

>While I am here, could you teach me a bit more?
>
>
>The top Makefile sets the following option as well:
>
>CLANG_GCC_TC    := --gcc-toolchain=$(GCC_TOOLCHAIN)
>
>
>
>I checked the manual:
>https://clang.llvm.org/docs/ClangCommandLineReference.html
>
>
>  -B<dir>, --prefix <arg>, --prefix=<arg>
>  Add <dir> to search path for binaries and object files used implicitly
>
>  --gcc-toolchain=<arg>, -gcc-toolchain <arg>
>  Use the gcc toolchain at the given directory
>
>
>
>
>It is not clear to me
>how they work differently when
>clang searches for toolchains.
>
>
>
>
>If I delete --gcc-toolchain from the top Makefile,
>clang fails to link standalone programs
>because it wrongly invokes /usr/bin/ld
>instead of aarch64-linux-gnu-ld.
>
>
>Does Clang search for gnu assembler
>based on --prefix option?
>
>And, searches for a linker
>based on --gcc-toolchain ?
>
>
>
>-- 
>Best Regards
>Masahiro Yamada

While GCC seems to encourage distributions to apply various environment
settings, Clang encourages downstream users to contribute their
configurations to the upstream clangDriver library... So, clang works
seemingly on many operating systems and many distributions without much
additional customization, but the host/target environment detection code
is very messy.

Freestanding builds (if you use integrated assembler/LLD) do not need --gcc-toolchain.

-fhosted builds need --gcc-toolchain to reuse libstdc++ include paths
and runtime libraries (crt1.o libgcc.a libgcc_s.so.1 etc).
I think on most Linux distributions, with distribution shipped GCC
packages, the only meaningful value is --gcc-toolchain=/usr

Clang will find 'lib' or 'lib64' under --gcc-toolchain= (e.g. /usr/lib),
then locate common cross-compiling GCC installations (e.g. /usr/lib +
gcc-cross/aarch-linux-gnu (Debian uses gcc-cross/), or just /usr/lib +
gcc/aarch-linux-gnu). You can see that with an incorrect --gcc-toolchain=/ (or some other arbitrary path):
(https://github.com/llvm/llvm-project/blob/master/clang/lib/Driver/ToolChains/Gnu.cpp#L1903 )

* `clang -v` does not print `Found candidate GCC installation: `
* There is no libstdc++ search path in `#include <...> search starts here:` for a C++ compile
* In the linking stage, ld reports a number of issues like 'cannot find crt1.o'

When --gcc-toolchain is not specified, in many cases Clang can guess the
correct value (usually /usr). So clang++ --target=aarch64-linux-gnu works just fine.

(As you can see from the code, the code --gcc-toolchain= is tangled with
environment detection, which is ugly: specifying a wrong --gcc-toolchain= can remove a lot of file stats...
You can find that the number of syscalls changes with different --gcc-toolchain: `strace -fe file clang`)

External programs like 'as' and 'ld' use the bin/ directory somewhere
relative to the GCC installation directory (they are appended to getProgramPaths).
clang::driver::Driver::GetProgramPath locates these programs.
https://github.com/llvm/llvm-project/blob/master/clang/lib/Driver/ToolChains/Gnu.cpp#L1903
As you see from the code, -B and COMPILER_PATH take precedence over
getProgramPaths.
You can print the 'programs' path with `clang --print-search-dirs [--target=...] [-B...] [--gcc-toolchain=...]`
Latest clang will be closer to GCC.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2020-07-22  5:45 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-21 17:31 [PATCH v3] Makefile: Fix GCC_TOOLCHAIN_DIR prefix for Clang cross compilation Fangrui Song
2020-07-21 17:55 ` Nick Desaulniers
2020-07-21 22:14 ` Masahiro Yamada
2020-07-22  0:14   ` Fangrui Song
2020-07-22  1:36     ` Masahiro Yamada
2020-07-22  5:45       ` Fangrui Song

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).