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