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