Skip to content
This repository was archived by the owner on Nov 1, 2021. It is now read-only.

Commit f54e02f

Browse files
committed
Adding cross-compilation instructions to Clang
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@190281 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 14e25c0 commit f54e02f

File tree

2 files changed

+204
-0
lines changed

2 files changed

+204
-0
lines changed

docs/CrossCompilation.rst

+203
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
===================================================================
2+
Cross-compilation using Clang/LLVM
3+
===================================================================
4+
5+
Introduction
6+
============
7+
8+
This document will guide you in choosing the right cross-compilation options
9+
to hopefully help you target your code to a different architecture. It assumes
10+
you already know how to compile the code in question for the host architecture,
11+
and that you know how to choose additional include and library paths.
12+
13+
However, this document is `not` a `HowTo` and wont help you setting your build
14+
system or Makefiles, nor choosing the right CMake options. Also, it does not
15+
cover all the possible options, nor it contains specific examples for specific
16+
architectures. There are other documents in LLVM that do that in greater
17+
details (ex. http://llvm.org/docs/HowToCrossCompileLLVM.html).
18+
19+
After reading this document, you should be familiar with the main issues
20+
related to, and what main compiler options Clang provides for performing
21+
cross-compilation.
22+
23+
Cross compilation issues
24+
========================
25+
26+
In GCC world, every host/target combination has its own set of binaries,
27+
headers, libraries, etc. So, it's usually simple to download a package
28+
with all files in, unzip to a directory and point the build system to
29+
that compiler, that will know about its location and find all it needs to
30+
when compiling your code.
31+
32+
On the other hand, Clang/LLVM is natively a cross-compiler, meaning that
33+
one set of programs can compile to all targets by setting the -target
34+
option. That makes it a lot easier to programers wishing to compile to
35+
different platforms and architectures, and to compiler developers that
36+
only have to maintain one build system, and to OS distributions, that
37+
need only one set of main packages.
38+
39+
But, as is true to any cross-compiler, and given the complexity of
40+
different architectures, OSs and options, it's not always easy finding
41+
the headers, libraries or binutils to generate target specific code.
42+
So you'll need special options to help Clang understand what target
43+
you're compiling to, where are your tools, etc.
44+
45+
Another problem is that compilers come with standard libraries only (like
46+
icompiler-rt, libcxx, libgcc, libm, etc), so you'll have to find and make
47+
available to the build system, every other library required to build your
48+
software, that is specific to your target. It's not enough to have your
49+
host's libraries installed.
50+
51+
Finally, not all toolchains are the same, and consequently, not every Clang
52+
option will work magically. Some options, like --sysroot (which
53+
effectively changes the logical root for headers and libraries), assume
54+
all your binaries and libraries are in the same directory, which may not
55+
true when your cross-compiler was installed by the distribution's package
56+
management. So, for each specific case, you may use more than one
57+
option, and in most cases, you'll end up setting include paths (-I) and
58+
library paths (-L) manually.
59+
60+
To sum up, different toolchains can:
61+
* be host/target specific or more flexible
62+
* be in a single directory, or spread out your system
63+
* have different sets of libraries and headers by default
64+
* need special options, which your build system won't be able to figure
65+
out by itself
66+
67+
General Cross-Compilation Options in Clang
68+
==========================================
69+
70+
Target Triple
71+
-------------
72+
73+
The basic option is to define the target architecture. For that, use
74+
``-target <triple>``. If you don't specify the target, CPU names won't
75+
match (since Clang assumes the host triple), and the compilation will
76+
go ahead, creating code for the host platform, which will break later
77+
on when assembling or linking.
78+
79+
The triple has the general format ``<arch><sub>-<vendor>-<sys>-<abi>``, where:
80+
* ``arch`` = x86, arm, thumb, mips, etc.
81+
* ``sub`` = for ex. on ARM: v5, v6m, v7a, v7m, etc.
82+
* ``vendor`` = pc, apple, nvidia, ibm, etc.
83+
* ``sys`` = none, linux, win32, darwin, cuda, etc.
84+
* ``abi`` = eabi, gnu, android, macho, elf, etc.
85+
86+
The sub-architecture options are available for their own architectures,
87+
of course, so "x86v7a" doesn't make sense. The vendor needs to be
88+
specified only if there's a relevant change, for instance between PC
89+
and Apple. Most of the time it can be omitted (and Unknown)
90+
will be assumed, which sets the defaults for the specified architecture.
91+
The system name is generally the OS (linux, darwin), but could be special
92+
like the bare-metal "none".
93+
94+
When a parameter is not important, they can be omitted, or you can
95+
choose "unknown" and the defaults will be used. If you choose a parameter
96+
that Clang doesn't know, like "blerg", it'll ignore and assume `Unknown`,
97+
which is not always desired, so be careful.
98+
99+
Finally, the ABI option is something that will pick default CPU/FPU,
100+
define the specific behaviour of your code (PCS, extensions),
101+
and also choose the correct library calls, etc.
102+
103+
CPU, FPU, ABI
104+
-------------
105+
106+
Once your target is specified, it's time to pick the hardware you'll
107+
be compiling to. For every architecture, a default set of CPU/FPU/ABI
108+
will be chosen, so you'll almost always have to change it via flags.
109+
110+
Typical flags include:
111+
* ``-mcpu=<cpu-name>``, like x86-64, swift, cortex-a15
112+
* ``-fpu=<fpu-name>``, like SSE3, NEON, controlling the FP unit available
113+
* ``-mfloat-abi=<fabi>``, like soft, hard, controlling which registers
114+
to use for floating-point
115+
116+
The default is normally the common denominator, so that Clang doesn't
117+
generate code that breaks. But that also means you won't get the best
118+
code for your specific hardware, which may mean orders of magnitude
119+
slower than you expect.
120+
121+
For example, if your target is "arm-none-eabi", the default CPU will
122+
be "arm7tdmi" using soft float, which is extremely slow on modern cores,
123+
whereas if your triple is "armv7a-none-eabi", it'll be Cortex-A8 with
124+
NEON, but still using soft-float, which is much better, but still not
125+
great.
126+
127+
Toolchain Options
128+
-----------------
129+
130+
There are four main options to control access to your cross-compiler:
131+
``--sysroot``, ``-I`` and ``-L``. The two last ones are well known,
132+
but they're particularly important for additional libraries
133+
and headers that are specific to your target.
134+
135+
There are two main ways to have a cross-compiler:
136+
137+
#. When you have extracted your cross-compiler from a zip file into
138+
a directory, you have to use ``--sysroot=<path>``. The path is the
139+
root directory where you have unpacked your file, and Clang will
140+
look for the directories ``bin``, ``lib``, ``include`` in there.
141+
142+
In this case, your setup should be pretty much done (if no
143+
additional headers or libraries are needed), as Clang will find
144+
all binaries it needs (assembler, linker, etc) in there.
145+
146+
#. When you have installed via a package manager (modern Linux
147+
distributions have cross-compiler packages available), make
148+
sure the target triple you set is `also` the prefix of your
149+
cross-compiler toolchain.
150+
151+
In this case, Clang will find the other binaries (assembler,
152+
linker), but not always where the target headers and libraries
153+
are. People add system-specific clues to Clang often, but as
154+
things change, it's more likely that it won't find than the
155+
other way around.
156+
157+
So, here, you'll be a lot safer if you specify the include/library
158+
directories manually (via ``-I`` and ``-L``).
159+
160+
Target-Specific Libraries
161+
=========================
162+
163+
All libraries that you compile as part of your build will be
164+
cross-compiled to your target, and your build system will probably
165+
find them in the right place. But all dependencies that are
166+
normally checked against (like libxml or libz etc) will match
167+
against the host platform, not the target.
168+
169+
So, if the build system is not aware that you want to cross-compile
170+
your code, it will get every dependency wrong, and your compilation
171+
will fail during build time, not configure time.
172+
173+
Also, finding the libraries for your target are not as easy
174+
as for your host machine. There aren't many cross-libraries available
175+
as packages to most OSs, so you'll have to either cross-compile them
176+
from source, or download the package for your target platform,
177+
extract the libraries and headers, put them in specific directories
178+
and add ``-I`` and ``-L`` pointing to them.
179+
180+
Also, some libraries have different dependencies on different targets,
181+
so configuration tools to find dependencies in the host can get the
182+
list wrong for the target platform. This means that the configuration
183+
of your build can get things wrong when setting their own library
184+
paths, and you'll have to augment it via additional flags (configure,
185+
Make, CMake, etc).
186+
187+
Multilibs
188+
---------
189+
190+
When you want to cross-compile to more than one configuration, for
191+
example hard-float-ARM and soft-float-ARM, you'll have to have multiple
192+
copies of you libraries and (possibly) headers.
193+
194+
Some Linux distributions have support for Multilib, which handle that
195+
for you in an easier way, but if you're not careful and, for instance,
196+
forget to specify ``-ccc-gcc-name armv7l-linux-gnueabihf-gcc`` (which
197+
uses hard-float), Clang will pick the ``armv7l-linux-gnueabi-ld``
198+
(which uses soft-float) and linker errors will happen.
199+
200+
The same is true if you're compiling for different ABIs, like ``gnueabi``
201+
and ``androideabi``, and might even link and run, but produce run-time
202+
errors, which are much harder to track and fix.
203+

docs/index.rst

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Using Clang as a Compiler
1818

1919
UsersManual
2020
LanguageExtensions
21+
CrossCompilation
2122
AddressSanitizer
2223
ThreadSanitizer
2324
MemorySanitizer

0 commit comments

Comments
 (0)