[PATCH] Makefile: Fix GCC_TOOLCHAIN_DIR prefix for Clang cross compilation

655 views
Skip to first unread message

Fangrui Song

unread,
Jul 20, 2020, 2:12:46 PM7/20/20
to Masahiro Yamada, Michal Marek, linux-...@vger.kernel.org, linux-...@vger.kernel.org, clang-bu...@googlegroups.com, Fangrui Song, Nathan Chancellor
When CROSS_COMPILE is set (e.g. aarch64-linux-gnu-), if
$(CROSS_COMPILE)elfedit is found at /usr/bin/aarch64-linux-gnu-,
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 only searches for $(prefix)$needle and for example 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).

Signed-off-by: Nathan Chancellor <natecha...@gmail.com>
Signed-off-by: Fangrui Song <mas...@google.com>
Link: https://github.com/ClangBuiltLinux/linux/issues/1099
---
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

Nathan Chancellor

unread,
Jul 20, 2020, 2:16:50 PM7/20/20
to Fangrui Song, Masahiro Yamada, Michal Marek, linux-...@vger.kernel.org, linux-...@vger.kernel.org, clang-bu...@googlegroups.com
On Mon, Jul 20, 2020 at 11:12:22AM -0700, Fangrui Song wrote:
> When CROSS_COMPILE is set (e.g. aarch64-linux-gnu-), if
> $(CROSS_COMPILE)elfedit is found at /usr/bin/aarch64-linux-gnu-,
> 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 only searches for $(prefix)$needle and for example 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).
>
> Signed-off-by: Nathan Chancellor <natecha...@gmail.com>
> Signed-off-by: Fangrui Song <mas...@google.com>
> Link: https://github.com/ClangBuiltLinux/linux/issues/1099

Sorry that I did not pay attention before but this needs

Cc: sta...@vger.kernel.org

in the body so that it gets automatically backported into all of our
stable branches. I am not sure if Masahiro is okay with adding that
after the fact or if he will want a v2.

I am fine with having my signed-off-by on the patch but I did not really
do much :) I am fine with having that downgraded to

Reviewed-by: Nathan Chancellor <natecha...@gmail.com>
Tested-by: Nathan Chancellor <natecha...@gmail.com>

if people find it odd.

Thanks for sending this along!

Cheers,
Nathan

Nick Desaulniers

unread,
Jul 20, 2020, 3:28:13 PM7/20/20
to Fangrui Song, Masahiro Yamada, Michal Marek, Linux Kbuild mailing list, LKML, clang-built-linux, Nathan Chancellor, Manoj Gupta, Jian Cai, Bill Wendling
On Mon, Jul 20, 2020 at 11:16 AM Nathan Chancellor
<natecha...@gmail.com> wrote:
>
> On Mon, Jul 20, 2020 at 11:12:22AM -0700, Fangrui Song wrote:
> > When CROSS_COMPILE is set (e.g. aarch64-linux-gnu-), if
> > $(CROSS_COMPILE)elfedit is found at /usr/bin/aarch64-linux-gnu-,
> > 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 only searches for $(prefix)$needle and for example it will find

"newer Clang" requires the reader to recall that "Clang as of 11" was
the previous frame of reference. I think it would be clearer to:
1. call of clang-12 as having a difference in behavior.
2. explicitly link to the commit, ie:
Link: https://github.com/llvm/llvm-project/commit/3452a0d8c17f7166f479706b293caf6ac76ffd90

> > /usr/bin/as instead of /usr/bin/aarch64-linux-gnu-as.

That's a common source of pain (for example, when cross compiling
without having the proper cross binutils installed, it's common to get
spooky errors about unsupported configs or host binutils not
recognizing flags specific to cross building).

/usr/bin/as: unrecognized option '-EL'

being the most common. So in that case, I'm actually very happy with
the llvm change if it solves that particularly common pain point.

> >
> > 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).
> >
> > Signed-off-by: Nathan Chancellor <natecha...@gmail.com>
> > Signed-off-by: Fangrui Song <mas...@google.com>
> > Link: https://github.com/ClangBuiltLinux/linux/issues/1099
>
> Sorry that I did not pay attention before but this needs
>
> Cc: sta...@vger.kernel.org

Agreed. This change to llvm will blow up all of our CI jobs that
cross compile if not backported to stable.

>
> in the body so that it gets automatically backported into all of our
> stable branches. I am not sure if Masahiro is okay with adding that
> after the fact or if he will want a v2.
>
> I am fine with having my signed-off-by on the patch but I did not really
> do much :) I am fine with having that downgraded to

Not a big deal, but there's only really two cases I can think of where
it's appropriate to attach someone else's "SOB" to a patch:
1. It's their patch that you're resending on their behalf, possibly as
part of a larger series.
2. You're a maintainer, and...well I guess that's also case 1 above.

Reported-by is more appropriate, and you can include the tags
collected from this thread. Please ping me internally for help
sending a v2, if needed.

>
> Reviewed-by: Nathan Chancellor <natecha...@gmail.com>
> Tested-by: Nathan Chancellor <natecha...@gmail.com>

I tested with this llvm pre- and post-
https://github.com/llvm/llvm-project/commit/3452a0d8c17f7166f479706b293caf6ac76ffd90.
I also tested downstream Android kernel builds with
3452a0d8c17f7166f479706b293caf6ac76ffd90. Builds that don't make use
of CROSS_COMPILE (native host targets) are obviously unaffected. We
might see this issue pop up a few more times internally if the patch
isn't picked up by stable, or if those downstream kernel trees don't
rebase on stable kernel trees as often as they refresh their
toolchain.

Tested-by: Nick Desaulniers <ndesau...@google.com>

>
> if people find it odd.
>
> Thanks for sending this along!
>
> Cheers,
> Nathan
>
> > ---
> > 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

Fangrui Song

unread,
Jul 20, 2020, 8:27:49 PM7/20/20
to Nick Desaulniers, Masahiro Yamada, Michal Marek, Linux Kbuild mailing list, LKML, clang-built-linux, Nathan Chancellor, Manoj Gupta, Jian Cai, Bill Wendling
Thanks. I did not know this.

>>
>> in the body so that it gets automatically backported into all of our
>> stable branches. I am not sure if Masahiro is okay with adding that
>> after the fact or if he will want a v2.
>>
>> I am fine with having my signed-off-by on the patch but I did not really
>> do much :) I am fine with having that downgraded to
>
>Not a big deal, but there's only really two cases I can think of where
>it's appropriate to attach someone else's "SOB" to a patch:
>1. It's their patch that you're resending on their behalf, possibly as
>part of a larger series.
>2. You're a maintainer, and...well I guess that's also case 1 above.
>
>Reported-by is more appropriate, and you can include the tags
>collected from this thread. Please ping me internally for help
>sending a v2, if needed.

Nathan's draft patch on
https://github.com/ClangBuiltLinux/linux/issues/1099 actually works.
I removed the slash. The words are my own. Since Nathan explicitly
requested a downgrade of his tag, I'll do that for V2.

I'll do that anyway because I need to fix a typo in the description:

$(CROSS_COMPILE)elfedit is found at /usr/bin/aarch64-linux-gnu-
$(CROSS_COMPILE)elfedit is found at /usr/bin/aarch64-linux-gnu-elfedit

>>
>> Reviewed-by: Nathan Chancellor <natecha...@gmail.com>
>> Tested-by: Nathan Chancellor <natecha...@gmail.com>
>
>I tested with this llvm pre- and post-
>https://github.com/llvm/llvm-project/commit/3452a0d8c17f7166f479706b293caf6ac76ffd90.
>I also tested downstream Android kernel builds with
>3452a0d8c17f7166f479706b293caf6ac76ffd90. Builds that don't make use
>of CROSS_COMPILE (native host targets) are obviously unaffected. We
>might see this issue pop up a few more times internally if the patch
>isn't picked up by stable, or if those downstream kernel trees don't
>rebase on stable kernel trees as often as they refresh their
>toolchain.
>
>Tested-by: Nick Desaulniers <ndesau...@google.com>

Thanks for offerring proofreading service! I'm working on the
description...

Fangrui Song

unread,
Jul 21, 2020, 12:20:05 AM7/21/20
to Masahiro Yamada, Michal Marek, linux-...@vger.kernel.org, linux-...@vger.kernel.org, clang-bu...@googlegroups.com, sta...@vger.kernel.org, Jian Cai, Bill Wendling, Manoj Gupta, Fangrui Song, 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).

Reported-by: Nathan Chancellor <natecha...@gmail.com>
Signed-off-by: Fangrui Song <mas...@google.com>
Reviewed-by: Nathan Chancellor <natecha...@gmail.com>
Tested-by: Nathan Chancellor <natecha...@gmail.com>
Tested-by: Nick Desaulniers <ndesau...@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.

Greg KH

unread,
Jul 21, 2020, 6:40:27 AM7/21/20
to Fangrui Song, Masahiro Yamada, Michal Marek, linux-...@vger.kernel.org, linux-...@vger.kernel.org, clang-bu...@googlegroups.com, sta...@vger.kernel.org, Jian Cai, Bill Wendling, Manoj Gupta, Nathan Chancellor, Nick Desaulniers
<formletter>

This is not the correct way to submit patches for inclusion in the
stable kernel tree. Please read:
https://www.kernel.org/doc/html/latest/process/stable-kernel-rules.html
for how to do this properly.

</formletter>

Sedat Dilek

unread,
Jul 21, 2020, 10:53:09 AM7/21/20
to Greg KH, Fangrui Song, Masahiro Yamada, Michal Marek, linux-...@vger.kernel.org, linux-...@vger.kernel.org, Clang-Built-Linux ML, sta...@vger.kernel.org, Jian Cai, Bill Wendling, Manoj Gupta, Nathan Chancellor, Nick Desaulniers
Hi Fangrui,

your patch needs to be accepted first in Linus tree - among other
things to have a unique commit-id for inclusion into any affected
Linux-stable trees.

Regards,
- Sedat -

Nathan Chancellor

unread,
Jul 21, 2020, 1:13:26 PM7/21/20
to Sedat Dilek, Greg KH, Fangrui Song, Masahiro Yamada, Michal Marek, linux-...@vger.kernel.org, linux-...@vger.kernel.org, Clang-Built-Linux ML, sta...@vger.kernel.org, Jian Cai, Bill Wendling, Manoj Gupta, Nick Desaulniers
You are not wrong but that is not what Greg's auto response is complaining
about. It is that sta...@vger.kernel.org was cc'd but there was no

Cc: sta...@vger.kernel.org

in the commit message, which is how patches get automatically picked up
by Greg and Sasha once they hit Linus's tree.

That line should be added above my Reported-by tag. Fangrui, sorry for
not being clear in my initial response :(

Cheers,
Nathan

Fangrui Song

unread,
Jul 21, 2020, 1:31:36 PM7/21/20
to Masahiro Yamada, Michal Marek, linux-...@vger.kernel.org, linux-...@vger.kernel.org, clang-bu...@googlegroups.com, Jian Cai, Bill Wendling, Manoj Gupta, Fangrui Song, sta...@vger.kernel.org, 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: sta...@vger.kernel.org
Reported-by: Nathan Chancellor <natecha...@gmail.com>
Signed-off-by: Fangrui Song <mas...@google.com>
Reviewed-by: Nathan Chancellor <natecha...@gmail.com>
Tested-by: Nathan Chancellor <natecha...@gmail.com>
Tested-by: Nick Desaulniers <ndesau...@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: sta...@vger.kernel.org

Nick Desaulniers

unread,
Jul 21, 2020, 1:56:03 PM7/21/20
to Fangrui Song, 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 <mas...@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: sta...@vger.kernel.org
> Reported-by: Nathan Chancellor <natecha...@gmail.com>
> Signed-off-by: Fangrui Song <mas...@google.com>
> Reviewed-by: Nathan Chancellor <natecha...@gmail.com>
> Tested-by: Nathan Chancellor <natecha...@gmail.com>
> Tested-by: Nick Desaulniers <ndesau...@google.com>

Reviewed-by: Nick Desaulniers <ndesau...@google.com>
--
Thanks,
~Nick Desaulniers

Sedat Dilek

unread,
Jul 21, 2020, 3:54:45 PM7/21/20
to Fangrui Song, Masahiro Yamada, Michal Marek, linux-...@vger.kernel.org, linux-...@vger.kernel.org, Clang-Built-Linux ML, sta...@vger.kernel.org, Jian Cai, Bill Wendling, Manoj Gupta, Nathan Chancellor, Nick Desaulniers
Tested-by: Sedat Dilek <sedat.dilek@gmail,com>

- Sedat -

> ---
> 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
>
> --
> 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-li...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/clang-built-linux/20200721041940.4029552-1-maskray%40google.com.

Masahiro Yamada

unread,
Jul 21, 2020, 6:15:32 PM7/21/20
to Fangrui Song, Michal Marek, Linux Kbuild mailing list, Linux Kernel Mailing List, clang-built-linux, Jian Cai, Bill Wendling, Manoj Gupta, stable, Nathan Chancellor, Nick Desaulniers
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-li...@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

Fangrui Song

unread,
Jul 21, 2020, 8:14:28 PM7/21/20
to Masahiro Yamada, Michal Marek, Linux Kbuild mailing list, Linux Kernel Mailing List, clang-built-linux, Jian Cai, Bill Wendling, Manoj Gupta, stable, Nathan Chancellor, Nick Desaulniers
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? :)

Masahiro Yamada

unread,
Jul 21, 2020, 9:37:35 PM7/21/20
to Fangrui Song, Michal Marek, Linux Kbuild mailing list, Linux Kernel Mailing List, clang-built-linux, Jian Cai, Bill Wendling, Manoj Gupta, stable, Nathan Chancellor, Nick Desaulniers
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 ?

Fangrui Song

unread,
Jul 22, 2020, 1:45:19 AM7/22/20
to Masahiro Yamada, Michal Marek, Linux Kbuild mailing list, Linux Kernel Mailing List, clang-built-linux, Jian Cai, Bill Wendling, Manoj Gupta, stable, Nathan Chancellor, Nick Desaulniers
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.

Thomas-topway-it

unread,
Jun 3, 2023, 2:45:57 PM6/3/23
to Clang Built Linux
hello,  I'm trying to compile a c++ library on Android Studio,
on Ubuntu 22.10, Clang 15.0.7, with CFlag '-no-integrated-as'.
I think I experience the issue here described
/usr/bin/as: unrecognized option '-EL'
(this also setting manually the path of 
aarch64-linux-android-as)
I've tried to downgrade to Clang 11 but no luck with
this also. (it compiles x86 and x86_64, but not
armeabi and arm64 for the same cause)
Is there a way to set the prefix at Android Studio
level instead than manually in the mk of
all the libraries? Or is there a solution
for the latest version of Ubuntu ?
I'm not sure if this is the right place to
ask this question, but perhaps you are able to
give some suggestions.
Thanks a lot

Nick Desaulniers

unread,
Jun 5, 2023, 12:25:43 PM6/5/23
to Thomas-topway-it, Clang Built Linux
On Sat, Jun 3, 2023 at 11:46 AM Thomas-topway-it
<thomas.t...@gmail.com> wrote:
>
> hello, I'm trying to compile a c++ library on Android Studio,
> on Ubuntu 22.10, Clang 15.0.7, with CFlag '-no-integrated-as'.
> I think I experience the issue here described
> /usr/bin/as: unrecognized option '-EL'
> (this also setting manually the path of
> aarch64-linux-android-as)
> I've tried to downgrade to Clang 11 but no luck with
> this also. (it compiles x86 and x86_64, but not
> armeabi and arm64 for the same cause)
> Is there a way to set the prefix at Android Studio
> level instead than manually in the mk of
> all the libraries? Or is there a solution
> for the latest version of Ubuntu ?
> I'm not sure if this is the right place to
> ask this question, but perhaps you are able to
> give some suggestions.

Hi Thomas,
This mailing list was used for discussion building the linux kernel with clang.
https://clangbuiltlinux.github.io/
We now use ll...@lists.linux.dev instead and this ML is inactive.

I've never used Android Studio, so I can't help you with UI questions,
but I know that the (host) assembler (probably x86_64) is complaining
that it doesn't recognize the command line flag (`-EL`; endianness
little) because x86_64 is not bi-endian (it's always LE) and that
assembler flag was probably meant for the target assembler (aarch64?
arm?). That's a familiar failure when clang is not given a target
triple on the command line, like `--target=aarch64-linux-gnu`, during
cross compilation. I'm guessing you'd want a triple with `android`
somewhere in the string.

Hope this helps!
> --
> 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-li...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/clang-built-linux/6576b5c0-ff42-4d12-be68-bc66dce268a5n%40googlegroups.com.



--
Thanks,
~Nick Desaulniers
Reply all
Reply to author
Forward
0 new messages