Targeting ARM with Clang

All,

I am just learning about clang/ llvm now and I have a very simple question (and I must be missing something easy) but can someone answer how I can use clang to create an ARM executable?

I've downloaded clang + llvm and built them together on an x86 system using the default configuration -- which I believe is to build all targets. Here is some information:

163) llvm-config --version
2.8svn

165) llvm-config --targets-built
x86 sparc powerpc alpha arm mips cellspu pic16 xcore msp430 systemz blackfin cbackend msil cppbackend mblaze

166) clang --version
clang version 2.0 (trunk 105977)
Target: x86_64-unknown-linux-gnu
Thread model: posix

167) clang -arch arm main.c
clang: warning: argument unused during compilation: '-arch arm'

The resulting a.out is an x86 executable.

168) clang -march=arm main.c
'arm' is not a recognized processor for this target (ignoring processor)

169) clang -march=armv7 main.c
'armv7' is not a recognized processor for this target (ignoring processor)

(I've tried various armxx names)

It tried generating assembler for arm by using clang with -emit-llvm and then:
llc -march=arm main.bc (no complaint)

But the resulting main.s will not compile with an arm-compiler that I currently have.

Isn't there is a way to simply generate an executable for an arm-platform using "clang [option] main.c"?

I just noticed this -- isn't the default build for clang to build a native compiler (not something that uses gcc)??

195) clang -target-cpu=arm main.c
gcc: unrecognized option '-target-cpu=arm'

Thanks in advance!

David McNamara

I am just learning about clang/ llvm now and I have a very simple
question (and I must be missing something easy) but can someone answer
how I can use clang to create an ARM executable?

For which platform?

It tried generating assembler for arm by using clang with -emit-llvm and
then:
llc -march=arm main.bc (no complaint)

But the resulting main.s will not compile with an arm-compiler that I
currently have.

Which compiler? Are you using binutils?

Cross-compilation with clang isn't really properly supported... "clang
-ccc-host-triple armv7-apple-darwin10 foo.c -c" (using an appropriate
triple for your platform) might do something close to what you want,
but expect to run into issues.

-Eli

It shouldn't require anything special.

This is what I do (on Mac OS X):

svn co ... llvm
cd tools
svn co .. clang
cd ../..
./configure
make
./Debug+Asserts/bin/clang -arch armv7 -S -O3 -o - hello.c

ARM code comes out.

Evan

./Debug+Asserts/bin/clang -arch armv7 -S -O3 -o - hello.c

-arch is darwin-only thing though...

The platform isn't really important to me right now -- I have a simulator
running on a linux box that will support all arm platforms.

So, it supports arm/linux, arm/darwin and even arm/wince? Then you
should have no problems at all, arm/darwin should work more or less
ok.

The compiler I am using is "armcc".

Ok. Does it support AT&T assembler syntax?

All,

I might be getting somewhere based on several questions asked of me – I seem to be able to get assembler generated and compiled with code sourcery’s arm-gcc compiler by doing the following:

clang -ccc-host-triple arm-none-linux-gnueabi main.c -S -o main.s

which gives me this warning but does generate a main.s
clang: warning: unknown platform, assuming -mfloat-abi=soft

Then using code sourcery’s gcc:
arm-none-linux-gnueabi-gcc main.s

I get an “a.out” … which won’t work with my simulator just yet but I’m getting there…

I now have 2 questions, at the risk of missing something obvious on a Friday afternoon:

  1. How does one replace the default “gcc” that clang uses for assembling with another CC compiler? Looking at the options from “clang --help”, it is not obvious
  2. How do I reconcile what I believe to be the right target-triplet for the assembler (from code sourcery) I am using with clang’s known platforms (ie. how do I find out clang’s known target-triplets?).

Interestingly, if I look at what clang does with the target-triplet I supplied, the underlying clang command reveals -target armv4t-none-linux-gnueabi… but if I try to specify this instead of the target-triplet that I used, I still get the same error message about unknown platform.

Thanks in advance.

Dave Mc

Eli Friedman wrote:

Hello, David

My misunderstanding -- when you asked about platforms, I was thinking of
arm processors -- 7, cortex-a8, 9, neon, etc... I am currently --
temporarily -- starting this project on a linux box.

arm/linux works fine for me (via llvm-gcc though). You need to be sure
that you have all necessary stuff in place (headers, libs, etc.), you
cannot grab the x86 bytecode and make it work on arm.

PS: Use "Reaply to all" button, so the message will reach mailing list
as well, not only me.

Hi Anton,

Anton Korobeynikov wrote:

Hello, David

  
  My misunderstanding -- when you asked about platforms, I was thinking of
arm processors -- 7, cortex-a8, 9, neon, etc...  I  am currently --
temporarily -- starting this project on a linux box.
    
arm/linux works fine for me (via llvm-gcc though). You need to be sure
that you have all necessary stuff in place (headers, libs, etc.), you
cannot grab the x86 bytecode and make it work on arm.
  

I am checking out llvm-gcc now and will attempt to build. I’m not married to any particular solution. My main goal here is to have a working clang+llvm+something to give me executables so that I can start learning clang AST and LLVM. My background isn’t in code generation but in writing front ends and optimization passes. And I will most likely be moving off my linux platform soon enough.

PS: Use "Reaply to all" button, so the message will reach mailing list
as well, not only me.
  

Will do! :slight_smile:

Thanks,
David

Why -arch is darwin-only?

Because clang needs to know what assembler, linker, libraries etc to use for arm. Darwin supports -arch throughout the entire toolchain, so clang can just run "as -arch armv7". Linux and other targets don't have anything like this, and noone has enhanced clang to support the linux model.

-Chris

I am facing a similar issue as the original poster; I am targeting both ARM and x86 linux platforms, building on Mac OS X. Would it be possible to gain -arch support via defining a ToolChain instead of using the -ccc-host-triple and piping the assembly into the platform assembler? This I assume would require then building a driver driver for that platform?

Additionally is there a way when defining a ToolChain to replace potentially incompatible assembly calls before its sent to the assembler?

Any insight/suggestions on where to look up more detailed information on defining a ToolChain would be appreciated.

Sincerely,
Philippe Hausler

Any insight/suggestions on where to look up more detailed information on defining a ToolChain would be appreciated.

For now clang has hard coded values for linkers, assemblers, include
paths, etc. If you just want to patch it to do what you want, it
shouldn't be hard. Just search for how freebsd does it for example. If
you want to make it more general, you can try working on

http://clang.llvm.org/UniversalDriver.html
http://llvm.org/bugs/show_bug.cgi?id=4127

Sincerely,
Philippe Hausler
_______________________________________________
cfe-dev mailing list
cfe-dev@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev

Cheers,

Right, this is the most accurate answer.

The main answer to a lot of the questions posed in this thread is "no
one has done it yet". There is no real reason we can't support -arch
on non-Darwin, I just haven't done the driver work for it. As with
many things, it is on my TODO list, but it hasn't made it to the top.

As for supporting targeting ARM, my official position on this is:
(a) Yes, you can kind of do it with -ccc-host-triple.
(b) This isn't a supported usage model. If it works for you, great,
but I don't think we should tell users to try it.
(c) We should do the universal driver work to create a real cross
compilation model that actually works.

- Daniel

Right, this is the most accurate answer.

The main answer to a lot of the questions posed in this thread is "no
one has done it yet". There is no real reason we can't support -arch
on non-Darwin, I just haven't done the driver work for it. As with
many things, it is on my TODO list, but it hasn't made it to the top.

As for supporting targeting ARM, my official position on this is:
(a) Yes, you can kind of do it with -ccc-host-triple.
(b) This isn't a supported usage model. If it works for you, great,
but I don't think we should tell users to try it.
(c) We should do the universal driver work to create a real cross
compilation model that actually works.

- Daniel

Well I appreciate all of your feedback on this; given an ideal scenario I would whole-heartedly agree that a universal driver concept would need to be fleshed out. I have taken a bit to attempt some initial passes at implementing the previously mentioned Universal Driver post with some success.

Ideally what would be needed for a target configuration file to specify?
Where should these specifications be housed? I would assume maybe relative to the clang driver ../etc/clang/ ?
What format should they use? I assume some sort of text, but should it be config file, xml etc?

So far for my scenario I would like to implement control over from a target configuration file for:

The triple which would adapt the arch/platform/os and maybe be later hooked to any other needed linkage in the compilation phases (this seems like it would be a near 100% requirement for a well formed configuration)

Locations of the assembler and the linker for the target (potentially either relative to clang or absolute on the system)
^ what other actions would be sane here?

Specifications for a assembly pre-processor (in my case usable for double checking the assembly output and replacing a few incompatible calls)

Specifications for a linker post-processor (usable to perform build tasks like archival, or ant builds for JNI projects, bundle creation etc)

Default clang, assembler, and linker flags that are inferred by the target configuration (but these should be override-able by any arguments explicitly sent to clang)

Maybe some sort of option that defines if the assembler/linker are expected to be piped or not (not sure if this is needed/desirable/good-place-for-it)

Maybe some sort of option that specifies if the assembler or linker is used at all for platforms similar to the TCEToolChain

A flags for default for blocks, integrated assembler, non-fragile-abi, objc legacy dispatch, mixed dispatch, stack protection levels, unwind tables, relocation models, pic models, objc-gc, dwarf, and SjLj exceptions (these would all allow a fully text based implementation of a ToolChain)

Most likely I have missed a fair amount of things that would need to be done here.

I would like to make this as potentially useful to people beyond myself, so any feedback is welcomed.

Sincerely,
Philippe Hausler

Ideally what would be needed for a target configuration file to specify?
Where should these specifications be housed? I would assume maybe relative to the clang driver ../etc/clang/ ?
What format should they use? I assume some sort of text, but should it be config file, xml etc?
From my feeling, first of all one needs to unify all the places, where

the configuration data is used.

Currently there are at least two completely different places:
  - Preprocessor (which uses paths for includes & similar stuff)
  - Driver itself

Locations of the assembler and the linker for the target (potentially either relative to clang or absolute on the system)
^ what other actions would be sane here?

Sometimes extra post-link step is required. E.g. dsymutil on darwin.

Specifications for a assembly pre-processor (in my case usable for double checking the assembly output and replacing a few incompatible calls)
Specifications for a linker post-processor (usable to perform build tasks like archival, or ant builds for JNI projects, bundle creation etc)

? This definitely should be done outside of clang driver.

A flags for default for blocks, integrated assembler, non-fragile-abi, objc legacy dispatch, mixed dispatch, stack protection levels, unwind tables, relocation models, pic models, objc-gc, dwarf, and SjLj exceptions (these would all allow a fully text based implementation of a ToolChain)

All this is already implemented. No need to some additional stuff in most cases.

See http://clang.llvm.org/UniversalDriver.html as well.

[ Resurrecting an old thread ]

I'm looking to put together a set of development tools for a ARM-based system - partially for my own use, and also to see what pieces are missing in clang/LLVM.

I would appreciate any help in identifying the parts that I need.

My (inexact) goals:
* Put together a LLVM-based development and runtime environment for a ARM based system. (The dev environment doesn't have to run on the ARM, btw)
* Use as little GPL software as possible
* Document what all the pieces are and where they come from.

So far, I've got:
* Compiler - clang
* Linker - ???
* C standard library - ???
* C++ standard library - libc++
* Locale support (needed by libc++) - xlocale
* C++ ABI library - ??? [ On x86, I can use libcppabi - but not on ARM ]
* C runtime library - compiler-rt

What parts are missing from this list?
What have I got wrong here?

Thanks in advance!

-- Marshall

One specific, but important, piece of this is cxa_demangle. Howard, do you want to talk about your recent work on this?

-Chris

Sure! :slight_smile:

I've been working on a clean-sheet replacement for:

char* __cxa_demangle(const char* mangled_name,
           char* buf,
           size_t* n,
           int* status);

http://www.codesourcery.com/public/cxx-abi/abi.html

It is still under development, and isn't quite yet ready for prime time, but it is coming along nicely. I just recently passed the milestone of demangling every symbol in the clang compiler as compiled on OS X. This implementation will eventually demangle all of the new C++0x symbols, but that part of the work is just barely started.

This implementation also sports a new lower-level interface meant for tools such as compilers and debuggers: