[LLVMdev] Targeting ARM Cortex-a9 from x86_64 with clang

801 views
Skip to first unread message

Rob Stewart

unread,
Nov 26, 2013, 10:36:11 AM11/26/13
to llv...@cs.uiuc.edu
Hi, here's the canonical helloworld.c

#include<stdio.h>

int main()
{
printf("Hello World");
return 0;
}

In accordance with the cross-compilation LLVM documentation [1], I am
trying to target the ARM on the Zedboard [2]. It is an ARM Cortex-A9.
The machine I am compiling on is an x86_64 Fedora Linux machine, using
clang 3.3. I am failing to generate an executable, instead seeing an
error "unrecognized option '-mfpu=neon'".

$ clang -v -target armv7a-linux-eabi -mcpu=cortex-a9 -mfloat-abi=soft
-mfpu=neon helloworld.c
clang version 3.3 (tags/RELEASE_33/rc3)
Target: armv7a--linux-eabi
Thread model: posix
"/usr/bin/clang" -cc1 -triple armv7--linux-eabi -S -disable-free
-disable-llvm-verifier -main-file-name helloworld.c -mrelocation-model
static -mdisable-fp-elim -fmath-errno -mconstructor-aliases
-fuse-init-array -target-abi aapcs -target-cpu cortex-a9 -msoft-float
-mfloat-abi soft -target-feature +soft-float -target-feature
+soft-float-abi -target-feature +neon -target-feature -neon
-target-linker-version 2.23.52.0.1 -v -resource-dir
/usr/bin/../lib/clang/3.3 -internal-isystem /usr/local/include
-internal-isystem /usr/bin/../lib/clang/3.3/include
-internal-externc-isystem /usr/include -internal-externc-isystem
/usr/lib/gcc/x86_64-redhat-linux/4.8.2/include
-fno-dwarf-directory-asm -fdebug-compilation-dir /tmp -ferror-limit 19
-fmessage-length 157 -mstackrealign -fno-signed-char
-fobjc-runtime=gcc -fobjc-default-synthesize-properties
-fdiagnostics-show-option -fcolor-diagnostics -backend-option
-vectorize-loops -o /tmp/helloworld-SVQDb9.s -x c helloworld.c
clang -cc1 version 3.3 based upon LLVM 3.3 default target
x86_64-redhat-linux-gnu
#include "..." search starts here:
#include <...> search starts here:
/usr/local/include
/usr/bin/../lib/clang/3.3/include
/usr/include
/usr/lib/gcc/x86_64-redhat-linux/4.8.2/include
End of search list.
"/usr/bin/as" -mfpu=neon -mfloat-abi=soft -mcpu=cortex-a9 -mfpu=neon
-o /tmp/helloworld-DFsRi6.o /tmp/helloworld-SVQDb9.s
/usr/bin/as: unrecognized option '-mfpu=neon'
clang: error: assembler command failed with exit code 1 (use -v to see
invocation)


Any ideas? Thanks!

[1] - http://clang.llvm.org/docs/CrossCompilation.html
[2] - http://elinux.org/Zedboard
_______________________________________________
LLVM Developers mailing list
LLV...@cs.uiuc.edu http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev

Renato Golin

unread,
Nov 26, 2013, 11:44:37 AM11/26/13
to Rob Stewart, llv...@cs.uiuc.edu
On 26 November 2013 15:36, Rob Stewart <robste...@gmail.com> wrote:
$ clang -v -target armv7a-linux-eabi -mcpu=cortex-a9 -mfloat-abi=soft
-mfpu=neon helloworld.c

Hi Rod,

You need cross-binutils installed on your box. If you use Debian, there are packages (gcc-4.7-arm-linux-gnueabi and friends). Other distros may have similar packages, but you can always download the Linaro toolchain (http://releases.linaro.org/latest/components/toolchain).

Supposing you already have it, and it's in the PATH, Clang only recognizes it automatically if your triple is identical to the name of your cross compiler (See "Toolchain Options" in the referred doc). That means, you either need to have an "armv7a-linux-eabi-gcc" on the path, or you have to change your triple to something like "arm-linux-gnueabi", because that's what your cross-GCC will probably be called. The -mcpu will take care of choosing v7A.

Otherwise, you'll have to set --sysroot or --gcc-name as well as the triple, but that's not recommended.


 "/usr/bin/as" -mfpu=neon -mfloat-abi=soft -mcpu=cortex-a9 -mfpu=neon

As you can see, it chose the platform assembler, which is x86_64-only, not a cross-assembler. That's the hint that Clang didn't find your cross-binutils.

I know, Clang could have better error detection and stop when it's clearly the wrong architecture, but hey, Clang can deal with all archs on the same binary, there's no reason your system assembler (whatever it is) can't, too. One day, LLVM binutils will be... ;)

cheers,
--renato

Sean Silva

unread,
Nov 26, 2013, 12:40:17 PM11/26/13
to Renato Golin, llv...@cs.uiuc.edu
On Tue, Nov 26, 2013 at 11:44 AM, Renato Golin <renato...@linaro.org> wrote:
On 26 November 2013 15:36, Rob Stewart <robste...@gmail.com> wrote:
$ clang -v -target armv7a-linux-eabi -mcpu=cortex-a9 -mfloat-abi=soft
-mfpu=neon helloworld.c

Hi Rod,

You need cross-binutils installed on your box. If you use Debian, there are packages (gcc-4.7-arm-linux-gnueabi and friends). Other distros may have similar packages, but you can always download the Linaro toolchain (http://releases.linaro.org/latest/components/toolchain).

Supposing you already have it, and it's in the PATH, Clang only recognizes it automatically if your triple is identical to the name of your cross compiler (See "Toolchain Options" in the referred doc). That means, you either need to have an "armv7a-linux-eabi-gcc" on the path, or you have to change your triple to something like "arm-linux-gnueabi", because that's what your cross-GCC will probably be called. The -mcpu will take care of choosing v7A.

Otherwise, you'll have to set --sysroot or --gcc-name as well as the triple, but that's not recommended.


 "/usr/bin/as" -mfpu=neon -mfloat-abi=soft -mcpu=cortex-a9 -mfpu=neon

As you can see, it chose the platform assembler, which is x86_64-only, not a cross-assembler. That's the hint that Clang didn't find your cross-binutils.

Out of curiosity, can't clang do the assembly itself in this case?
 

I know, Clang could have better error detection and stop when it's clearly the wrong architecture, but hey, Clang can deal with all archs on the same binary, there's no reason your system assembler (whatever it is) can't, too. One day, LLVM binutils will be... ;)

Well, just remember that the GNU binutils that those tools are derived from support far more architectures (3x, 5x?) than LLVM does (just supporting linux requires like 30 architectures). When we get to that point, it will probably not make sense for a distro to ship a binary targeting all the architectures that we support, for the same reason it doesn't make sense for them to install binaries for every target supported by the GNU toolchain. (but at least in LLVM's case, it would be a conscious tradeoff, while IIRC the GNU toolchain simply can't be built in a way that targets all of them from a single binary).

-- Sean Silva
 

cheers,
--renato

Renato Golin

unread,
Nov 26, 2013, 12:43:41 PM11/26/13
to Sean Silva, llv...@cs.uiuc.edu
On 26 November 2013 17:40, Sean Silva <chiso...@gmail.com> wrote:
As you can see, it chose the platform assembler, which is x86_64-only, not a cross-assembler. That's the hint that Clang didn't find your cross-binutils.

Out of curiosity, can't clang do the assembly itself in this case?

It can, but you need to use -integrated-as, because that's not the default yet. (some missing features).


(but at least in LLVM's case, it would be a conscious tradeoff, while IIRC the GNU toolchain simply can't be built in a way that targets all of them from a single binary).

Exactly!

I only build the ARM back-end on my bots because I don't really care for the rest, but I know I can, if I really want to.

cheers,
--renato

Tim Northover

unread,
Nov 26, 2013, 12:44:30 PM11/26/13
to Sean Silva, llv...@cs.uiuc.edu
> Out of curiosity, can't clang do the assembly itself in this case?

Integrated-assembler is still disabled by default on ARM ELF. It
really should be enabled now, in my opinion. Of course, you'd still
need the linker so dependencies wouldn't change noticeably.

Cheers.

Tim.

Tim Northover

unread,
Nov 26, 2013, 1:13:41 PM11/26/13
to Renato Golin, Sean Silva, llv...@cs.uiuc.edu
>> Out of curiosity, can't clang do the assembly itself in this case?
>
> It can, but you need to use -integrated-as, because that's not the default
> yet. (some missing features).

Do you remember what those features are Renato? MC has been around
years, we really should start sorting them now.

Cheers.

Tim

Greg Fitzgerald

unread,
Nov 26, 2013, 1:46:02 PM11/26/13
to Tim Northover, Sean Silva, llv...@cs.uiuc.edu
Here's where we left off:
http://lists.cs.uiuc.edu/pipermail/llvmdev/2013-February/059099.html

In 3.4, I think the integrated assembler is in excellent shape and
should be enabled by default for ARM ELF. I've been using it
exclusively for at least 6 months now.

-Greg

Tim Northover

unread,
Nov 26, 2013, 2:00:55 PM11/26/13
to Greg Fitzgerald, Sean Silva, llv...@cs.uiuc.edu
On 26 November 2013 18:46, Greg Fitzgerald <gar...@gmail.com> wrote:
> Here's where we left off:
> http://lists.cs.uiuc.edu/pipermail/llvmdev/2013-February/059099.html

Back then you mentioned a Chromium build, are you still running that
routinely with -integrated-as? That would give a reasonable
reassurance about general-usage, if not weird features.

Cheers.

Tim.

Renato Golin

unread,
Nov 26, 2013, 2:02:14 PM11/26/13
to Tim Northover, Sean Silva, llv...@cs.uiuc.edu
On 26 November 2013 18:13, Tim Northover <t.p.no...@gmail.com> wrote:
Do you remember what those features are Renato? MC has been around
years, we really should start sorting them now.

No. I remember there were issues, but I never catalogued them.

I agree we should move as soon as possible, and there's nothing holding me of doing it.

I think post-3.4 we can cope with the consequences if they come, since it seems nobody remembers what they were in the first place. ;)

--renato

Joerg Sonnenberger

unread,
Nov 26, 2013, 2:10:21 PM11/26/13
to llv...@cs.uiuc.edu
On Tue, Nov 26, 2013 at 12:40:17PM -0500, Sean Silva wrote:
> Well, just remember that the GNU binutils that those tools are derived from
> support far more architectures (3x, 5x?) than LLVM does (just supporting
> linux requires like 30 architectures). When we get to that point, it will
> probably not make sense for a distro to ship a binary targeting all the
> architectures that we support, for the same reason it doesn't make sense
> for them to install binaries for every target supported by the GNU
> toolchain.

I know that FreeBSD limits the set of targets by default mostly for
compile reasons, the size difference is not that big. The trade off is
*much* better with LLVM.

Joerg

Tim Northover

unread,
Nov 26, 2013, 2:14:40 PM11/26/13
to Renato Golin, Sean Silva, llv...@cs.uiuc.edu
> I think post-3.4 we can cope with the consequences if they come, since it
> seems nobody remembers what they were in the first place. ;)

Looks like there might be a handful of .eabi_attribute variantswe
can't handle (http://llvm.org/bugs/show_bug.cgi?id=15172) -- ones
involving a string?

Cheers.

Tim.

Greg Fitzgerald

unread,
Nov 26, 2013, 2:20:00 PM11/26/13
to Tim Northover, Sean Silva, llv...@cs.uiuc.edu
> Back then you mentioned a Chromium build, are you still running that
> routinely with -integrated-as?

Yes. It works perfectly for a C/C++ code. There have been a few
hiccups with inline assembly (missing aliases, switching ARM modes)
and we sometimes disable it explicitly for those. It's very possible
that we can use -integrated-as for most of those now too, but I
haven't tried. It's nice to still have that -no-integrated-as escape
hatch.

-Greg

Renato Golin

unread,
Nov 26, 2013, 5:45:40 PM11/26/13
to Greg Fitzgerald, Sean Silva, llv...@cs.uiuc.edu
On 26 November 2013 19:20, Greg Fitzgerald <gar...@gmail.com> wrote:
It's nice to still have that -no-integrated-as escape hatch.

From all I hear, I think having that would be the best course of action post-3.4 release.

cheers,
-renato

David Chisnall

unread,
Nov 27, 2013, 5:00:07 AM11/27/13
to Joerg Sonnenberger, LLVM Developers Mailing List
On 26 Nov 2013, at 19:10, Joerg Sonnenberger <jo...@britannica.bec.de> wrote:

> On Tue, Nov 26, 2013 at 12:40:17PM -0500, Sean Silva wrote:
>> Well, just remember that the GNU binutils that those tools are derived from
>> support far more architectures (3x, 5x?) than LLVM does (just supporting
>> linux requires like 30 architectures). When we get to that point, it will
>> probably not make sense for a distro to ship a binary targeting all the
>> architectures that we support, for the same reason it doesn't make sense
>> for them to install binaries for every target supported by the GNU
>> toolchain.
>
> I know that FreeBSD limits the set of targets by default mostly for
> compile reasons, the size difference is not that big. The trade off is
> *much* better with LLVM.

We only do it, I believe, for the bootstrap build. When you build FreeBSD, you first build the toolchain that you'll build the system with (from the source tree that you're going to build, for the host arch), then you build the tree with that toolchain (for whatever your target arch is). Given how much of the total build time LLVM / Clang accounts for, building it twice caused a lot of irritating. We quite aggressively stripped down the bootstrap build, so that it only supports the specified target (unless requested otherwise), doesn't include the Clang rewriter, the static analyser, and a few other things. Removing the JIT would probably also make sense.

David

Rob Stewart

unread,
Nov 27, 2013, 8:57:46 AM11/27/13
to Renato Golin, llv...@cs.uiuc.edu
On 26 November 2013 16:44, Renato Golin <renato...@linaro.org> wrote:
> On 26 November 2013 15:36, Rob Stewart <robste...@gmail.com> wrote:
>>
>> $ clang -v -target armv7a-linux-eabi -mcpu=cortex-a9 -mfloat-abi=soft
>> -mfpu=neon helloworld.c
>
> Hi Rod,

I'm honoured. (But Rob is also OK) :-)

> You need cross-binutils installed on your box. If you use Debian, there are
> packages (gcc-4.7-arm-linux-gnueabi and friends). Other distros may have
> similar packages, but you can always download the Linaro toolchain
> (http://releases.linaro.org/latest/components/toolchain).
>
> Supposing you already have it, and it's in the PATH, Clang only recognizes
> it automatically if your triple is identical to the name of your cross
> compiler (See "Toolchain Options" in the referred doc). That means, you
> either need to have an "armv7a-linux-eabi-gcc" on the path, or you have to
> change your triple to something like "arm-linux-gnueabi", because that's
> what your cross-GCC will probably be called. The -mcpu will take care of
> choosing v7A.

So on my Fedora box, I've installed packages gcc-arm-linux-gnu.x86_64
and cross-binutils-common.noarch . Moreover, the first of these two
packages provide `/usr/bin/arm-linux-gnu-gcc`
$ repoquery -lq gcc-arm-linux-gnu.x86_64
Repository google-chrome is listed more than once in the configuration
/usr/bin/arm-linux-gnu-cpp
/usr/bin/arm-linux-gnu-gcc
/usr/bin/arm-linux-gnu-gcov
/usr/lib/gcc/arm-linux-gnueabi
/usr/lib/gcc/arm-linux-gnueabi/4.8.1
/usr/lib/gcc/arm-linux-gnueabi/4.8.1/crtbegin.o
...

The -target that appears to be recognised by clang is `arm-none-eabi`.
However, I'm now falling in to another trap.
$ clang -v -target arm-none-eabi -mcpu=cortex-a9 -mfloat-abi=soft helloworld.c
...
arm-none-eabi-gcc: fatal error: selected multilib '.' not installed

I've put the -v output to gist: https://gist.github.com/robstewart57/7676030

Renato Golin

unread,
Nov 27, 2013, 9:34:31 AM11/27/13
to Rob Stewart, llv...@cs.uiuc.edu
On 27 November 2013 13:57, Rob Stewart <robste...@gmail.com> wrote:
>> Hi Rod,
>
> I'm honoured. (But Rob is also OK) :-)

Haha! That was my best typo ever! ;)


> So on my Fedora box, I've installed packages gcc-arm-linux-gnu.x86_64
> and cross-binutils-common.noarch.

I'm not sure Clang understands "arm-linux-gnu" as a triple. The driver
is not the most sane code in Clang, so it might have holes in it that
won't make sense.

It is worth opening a new thread on cfe-dev@ discussing the possible
outcome of using arm-linux-gnu or arm-linux-androideabi as your triple
and get your toolchain to be detected correctly on Fedora.


> The -target that appears to be recognised by clang is `arm-none-eabi`.

That triple is normally used when targeting bare-metal ARM targets,
which I don't think is your case.

I can see from your output, all seem fine until...


> arm-none-eabi-gcc: fatal error: selected multilib '.' not installed

Normally, the problem with this is that you have libraries compiled
with hard-float and is trying to compile code with soft-float. But you
should focus on getting Clang to recognize your original triple first,
I think.

cheers,
--renato

Richard Pennington

unread,
Nov 27, 2013, 9:55:03 AM11/27/13
to Rob Stewart, llv...@cs.uiuc.edu
Your link says that clang is using gcc to compile rather than compiling
directly. You might want to look at the ELLCC project, which is designed
for just the sort of cross compilation you are trying to do.
http://ellcc.org

-Rich

Renato Golin

unread,
Nov 27, 2013, 10:10:46 AM11/27/13
to Richard Pennington, llv...@cs.uiuc.edu
On 27 November 2013 14:55, Richard Pennington <ri...@pennware.com> wrote:
> Your link says that clang is using gcc to compile rather than compiling
> directly. You might want to look at the ELLCC project, which is designed for
> just the sort of cross compilation you are trying to do. http://ellcc.org

Hi Rich,

No, his output only has gcc to assemble and link:

"/usr/bin/arm-none-eabi-gcc" -v -mcpu=cortex-a9 -mfloat-abi=soft -c -o
/tmp/helloworld-2n4ZGp.o -x assembler /tmp/helloworld-Iarp5R.s
"/usr/bin/arm-none-eabi-gcc" -v -mcpu=cortex-a9 -mfloat-abi=soft -o
a.out /tmp/helloworld-2n4ZGp.o

Clang normally calls GAS in case "-integrated-as" is not specified for ARM.

Btw, Rod, you might try the integrated assembler, too.

cheers,
--renato

Renato Golin

unread,
Nov 27, 2013, 10:11:58 AM11/27/13
to Richard Pennington, llv...@cs.uiuc.edu
On 27 November 2013 15:10, Renato Golin <renato...@linaro.org> wrote:
> Btw, Rod, you might try the integrated assembler, too.

And I did it again! Argh! Sorry!

Dimitry Andric

unread,
Nov 27, 2013, 5:52:35 PM11/27/13
to David Chisnall, LLVM Developers Mailing List
On 27 Nov 2013, at 11:00, David Chisnall <David.C...@cl.cam.ac.uk> wrote:
> On 26 Nov 2013, at 19:10, Joerg Sonnenberger <jo...@britannica.bec.de> wrote:
...
>> I know that FreeBSD limits the set of targets by default mostly for
>> compile reasons, the size difference is not that big. The trade off is
>> *much* better with LLVM.
>
> We only do it, I believe, for the bootstrap build. When you build FreeBSD, you first build the toolchain that you'll build the system with (from the source tree that you're going to build, for the host arch), then you build the tree with that toolchain (for whatever your target arch is). Given how much of the total build time LLVM / Clang accounts for, building it twice caused a lot of irritating. We quite aggressively stripped down the bootstrap build, so that it only supports the specified target (unless requested otherwise), doesn't include the Clang rewriter, the static analyser, and a few other things. Removing the JIT would probably also make sense.

Not entirely, yet. We do strip out the static analyzer, arcmigrate, and the rewriter during the bootstrap build, and only enable them for the second (target system) build. Stripping out unused target arches during the bootstrap would be nice to have, but the work has not been done yet. :-)

Stripping out the JIT might indeed also be interesting, though I guess stripping out unused arches will save more compile time?

-Dimitry

signature.asc

Alp Toker

unread,
Nov 27, 2013, 9:36:15 PM11/27/13
to David Chisnall, Joerg Sonnenberger, LLVM Developers Mailing List

On 27/11/2013 10:00, David Chisnall wrote:
> On 26 Nov 2013, at 19:10, Joerg Sonnenberger <jo...@britannica.bec.de> wrote:
>
>> On Tue, Nov 26, 2013 at 12:40:17PM -0500, Sean Silva wrote:
>>> Well, just remember that the GNU binutils that those tools are derived from
>>> support far more architectures (3x, 5x?) than LLVM does (just supporting
>>> linux requires like 30 architectures). When we get to that point, it will
>>> probably not make sense for a distro to ship a binary targeting all the
>>> architectures that we support, for the same reason it doesn't make sense
>>> for them to install binaries for every target supported by the GNU
>>> toolchain.
>> I know that FreeBSD limits the set of targets by default mostly for
>> compile reasons, the size difference is not that big. The trade off is
>> *much* better with LLVM.
> We only do it, I believe, for the bootstrap build. When you build FreeBSD, you first build the toolchain that you'll build the system with (from the source tree that you're going to build, for the host arch), then you build the tree with that toolchain (for whatever your target arch is). Given how much of the total build time LLVM / Clang accounts for, building it twice caused a lot of irritating. We quite aggressively stripped down the bootstrap build, so that it only supports the specified target (unless requested otherwise), doesn't include the Clang rewriter, the static analyser, and a few other things. Removing the JIT would probably also make sense.

Since you're on the topic and this thread has already gone off on a
tangent..

While investigating vendor patches on various third party LLVM branches,
I noticed FreeBSD also strips out the entire LLVM and clang test suites
from the repository.

As a result, some of the platform-specific changes and cherry-picks from
upstream don't appear to have obvious tests despite being a little
invasive. Are the related tests hiding away in a surrogate repository
somewhere or is it more of a "compiles, then ship it" policy?

(Not intended as a criticism, rather that I've been trying to understand
how external projects are consuming clang so we might accommodate them
better upstream, eg. by providing a streamlined boostrap configuration.)

Alp.


>
> David
>
>
> _______________________________________________
> LLVM Developers mailing list
> LLV...@cs.uiuc.edu http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev

--
http://www.nuanti.com
the browser experts
Reply all
Reply to author
Forward
0 new messages