LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 4127 - The clang driver should support cross compilation
Summary: The clang driver should support cross compilation
Status: RESOLVED FIXED
Alias: None
Product: clang
Classification: Unclassified
Component: Driver (show other bugs)
Version: unspecified
Hardware: All All
: P normal
Assignee: Unassigned Clang Bugs
URL:
Keywords:
: 11824 (view as bug list)
Depends on:
Blocks:
 
Reported: 2009-05-02 17:04 PDT by Daniel Dunbar
Modified: 2017-08-23 02:12 PDT (History)
25 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Daniel Dunbar 2009-05-02 17:04:37 PDT
The clang driver does not yet have a model for supporting cross compilation. In general, we should aim to do a much better job than GCC here.

The first step is probably deciding what the appropriate user interface is. We could reclaim -b for this purpose, for example, where the argument would be the target triple.

Once we have chosen the user interface, we need to figure out what tool chain support looks like. The issue is that the tool chain is really a combination of the host triple and the target triple; the host should have control over where it finds the assembler, linker, etc. for the target architecture.

We also need to decide where -arch, -m32, -m64, etc. fit in this world.
Comment 1 Daniel Dunbar 2009-08-18 01:49:40 PDT
I believe Chris and I have converged to using '-triple' as the argument for this.
Comment 2 Daniel Dunbar 2009-10-17 16:50:46 PDT
See also http://clang.llvm.org/UniversalDriver.html
Comment 3 Daniel Dunbar 2009-11-03 02:17:00 PST
My new proposal is that we use '-target' as the name for this option. The motivation for not using -triple is that a target configuration won't be tied to a particular target triple, rather it will be a user-defined name for a particular target (which may encompasses the target triple, information on the headers and include paths, and code generation options).

One conceptual way that -arch, -m32, and -m64 could fit into this world would by being "shortcut" options which find the "best" available target. In that model, -triple could also be added as another useful shortcut.
Comment 4 Sean Hunt 2010-02-24 00:03:40 PST
Random thoughts:

 - Each option should, ideally, be configurable on its own. If you need LLP64 to port some terribly-written Windows code to Linux, you should be able to specify it (no guarantees as to how this would interact with the hosted portion standard library, of course. Freestanding code should always work).
 - Note that many options will depend on other options; it makes no sense to enable SSE on an AMD.
 - Triples/targets should merely be preset defaults.
 - Ideally, the system (OS) and architecture components would be distinct. I don't personally see a particular reason to make the vendor and OS components of the triple be distinct entities.
Comment 5 Chris Lattner 2010-02-24 00:17:13 PST
I really don't think we want target triples to be the "key" anyway.  Ideally, there would be a config file which would specify things like the gnu target triple, header paths, assembler to use, abi-changing compiler-flags, etc.  When you use 'clang --target=foo' it would go load the foo.config file to get the details of what 'foo' means.  There is no reason for the "key" that the user reasons about be a gnu triple.
Comment 6 Traveler Hauptman 2010-08-07 08:18:46 PDT
(In reply to comment #5)

As a potential user, I like Chris Lattner's suggestion for '--target=configfile-entry-alias'. 

One relavant use-case I have is cross-compiling two versions of the same triple. One with a set of stable/safe system libraries and one with bleeding edge or modified system libraries. 

I'm more interested in getting work done that what compiler I'm using, so being able to point the 'universal-driver' to a gcc crosscompile toolchain (cc,ld,ar,strip etc) is something I'd look for. 

Below are some notes from my first experience setting up a cross-compile build environment. May or may not be helpful.
-----------------
Notes on setting up and using a cross-compiler environment.

The following are notes and thoughts from setting up a cross-compiler build environment
for ARM on Linux/gcc. 

Host-Target-Build confusion: (Gnu Terminology)

I had trouble understanding the specifics of these three terms. It seems like there is too much information here...

When I compile I want to take source code and create object/executable files. When I cross-compile, I want to create object/executable files for a different Processor+OS. That's all. I have the following naive assumptions:
* The source is valid for the Host
* Object files linked in are valid for the Host. If I try to link in the wrong kind, linking should fail.
* If I provide no information about the Host, assume that Host=Build

Thoughts on Host-Target-Build terminology.
* My first guess at the meanings was wrong. I thought Host was Build, Target was Host and Build was also host. Whatever the correct terminology it's ambiguous enough to warrant short definitions in the output of 'compiler --help' invocation.
* "Build" is something that should never need to be stated... The environment I am building in is inherent and the compiler should be able to figure out what this is.
* "Target" is silly and should not be part of the high-level cross-compiler discussion. In the end it's a Define variable specific to the source of a compiler and if I'm building a compiler I'll worry about it then and not before... 
* "Host" is the only info I should need to provide the compiler. A config file or a set of environment variables that describe the system I'm building for and where to find include/lib files for that system.


Ideally for me, setting up a new cross-compile host involves adding information to my local config file for the compiler driver, rather than editing Make files. It's true that Autoconf and CMake have decent support for cross-compiling, but I also have lots of source that uses hand-made build scripts or Make files and altering them with all the info for specific Hosts creates extra work. 


Difficulties I had (setting up gcc cross compiler for ARM):

Being sure that the compiler was using the correct default search paths for include and lib files.

After getting set up on one Build system, I duplicated it on another system. I got cryptic link errors about the Host configuration that I could not find the cause of. Eventually after some work and serendipity I discovered that the duplication had missed some Host library files. Useful and detailed error messages are always helpful.
Comment 7 Anton Korobeynikov 2011-10-05 03:14:01 PDT
*** Bug 11060 has been marked as a duplicate of this bug. ***
Comment 8 Sebastian Pop 2011-10-05 15:29:17 PDT
I don't want to fix all the problems linked to cross compilation
with clang, although I do want to fix a small problem I ran into:
as I explained in Bug 11060, the default target the configure
script is either given with the --target option or that configure
is inferring from the host if --target is not specified, should
be what clang will generate code for (when not instructed otherwise.)

To fix this we have to use the value set by configure in $target.
$target has to be used instead of the host information that is
currently used by clang.  To set up the target driver, I propose
that we change all the places where clang calls
llvm::sys::getHostTriple() with a call to
llvm::sys::getDefaultTargetTriple() that will return the default
target clang was configured for.

Do other people find something to say against doing this?
Should I go ahead and post a patch that implements this?

To remove the confusion on "Host-Target-Build confusion: (Gnu Terminology)":
- build = the machine on which the compiler is built
- host = the machine on which the compiler runs
- target = the machine on which the compiled code will run
A cross compiler has a target different than host.

Thanks,
Sebastian Pop
--
Qualcomm Innovation Center, Inc is a member of Code Aurora Forum
Comment 9 Anton Korobeynikov 2012-01-22 05:12:10 PST
*** Bug 11824 has been marked as a duplicate of this bug. ***
Comment 10 salvatore benedetto 2012-07-24 02:38:38 PDT
Has there be any progress about this?

Recently I started using clang for cross-compiling, and from a user point of view
it wasn't very easy to figure out the necessary flags.

On linux, in order to compile for cortex-m3 I had to use the following

clang++ -ccc-gcc-name arm-none-linux-gnueabi-g++ -ccc-host-triple thumbv7m-none-gnueabi sourceCode.cpp -c -mcpu=cortex-m3 -mthumb

I like the idea of --target=foo, which looks for a foo.config file.
Comment 11 Paul Smith 2013-05-22 19:15:07 PDT
It would be good to define more clearly what the objections are to GCC's handling of cross-compilation, before dismissing it.  Admittedly GCC/binutils has had a rocky road getting to its current position, but the current model is, IMO, a good one: a simple flag (--sysroot) to choose the sysroot, and separate compiler binaries for each architecture type.  Note that you can use the same compiler binaries with many different sysroots.

GCC implemented idea of a universal front-end with a flag to select the proper architecture, but it's never caught on.  Even though it's still there, everyone I know who does cross-compilation invokes the "back-end" compiler directly rather than using the universal front-end.  I think LLVM should pay careful attention to that experience before dismissing it.  Universal front-ends are simple in concept but they also create problems.  For example, tools which checksum the compiler to determine whether it has changed will fail, as they will checksum the universal driver rather than the real compiler.  It also means that your compiler invocation is a multi-word command with spaces and options, rather than a simple command, and this can cause problems for some tools which are expecting the latter as their compiler "name".

Just my $0.02, cheers!
Comment 12 Marcus Johnson 2017-08-22 17:51:15 PDT
It's kind of a huge PITA to have to keep separate libraries for each platform, why not just recompile them when cross compiling?
Comment 13 Renato Golin 2017-08-23 02:12:52 PDT
This bug is almost 10 years old and Clang has support for cross compilation for good part of that time already. I'm closing this bug and anything else will need to be a different bug from now on.

We already have plenty of bugs open for configuration files and cross-compiling libraries (also endless discussions on the list ever since), so I don't think we need any additional actions while closing this one.

cheers,
--renato