CrossCompilation.rst 9.3 KB

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