Difference between revisions of "Building LDC runtime libraries"

From D Wiki
Jump to: navigation, search
m (Prerequisites)
(Usage)
Line 23: Line 23:
 
* Invoking Make/Ninja to build the runtime libraries
 
* Invoking Make/Ninja to build the runtime libraries
  
== Usage ==
+
== Basic usage ==
  
 
The primary aim is to allow specifying additional compiler/linker command-line options and customizing [https://github.com/ldc-developers/ldc/blob/master/runtime/CMakeLists.txt CMake variables].<br>Run <tt>ldc-build-runtime -h</tt> for the full list of command-line options.
 
The primary aim is to allow specifying additional compiler/linker command-line options and customizing [https://github.com/ldc-developers/ldc/blob/master/runtime/CMakeLists.txt CMake variables].<br>Run <tt>ldc-build-runtime -h</tt> for the full list of command-line options.
 
Basic usage:
 
  
 
<pre>
 
<pre>
ldc-build-runtime -j4 [--testrunners] --dFlags=… --cFlags=… --linkerFlags=… CMAKE_VAR1=value1 CMAKE_VAR2=value2 …
+
ldc-build-runtime [--ninja] [-j4] [--testrunners] [--dFlags=…] [--cFlags=…] [--linkerFlags=…] [CMAKE_VAR1=value1] [CMAKE_VAR2=value2 …]
 
</pre>
 
</pre>
  
Basic usage for cross-compilation:
+
E.g., to enable Link-Time-Optimization between your user code and the runtime libraries, you can recompile the libraries via:
  
 
<pre>
 
<pre>
CC=cross-gcc ldc-build-runtime -j4 --dFlags="-mtriple=…;…" --cFlags=… --linkerFlags=… TARGET_SYSTEM=… …
+
ldc-build-runtime --ninja --dFlags="-flto=full" BUILD_SHARED_LIBS=OFF
 
</pre>
 
</pre>
  
Here's an actual command used to cross-compile the standard library and test runners for Android/ARM, by using the Android NDK.  First, you set the path to your NDK and cross-compiler, then you run this ldc-build-runtime command, all one command which has been split up for legibility:
+
== Usage for cross-compilation ==
 +
 
 
<pre>
 
<pre>
export NDK=/path/to/your/android-ndk-r15c
+
CC=cross-gcc ldc-build-runtime [--ninja] [-j4] --dFlags="-mtriple=…;…" [--cFlags=…] [--linkerFlags=…] --targetSystem=… …
export CC=$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin/clang
+
</pre>
  
ldc-build-runtime BUILD_SHARED_LIBS=OFF C_SYSTEM_LIBS="m;c" TARGET_SYSTEM="Android;Linux;UNIX"
+
For example, to cross-compile from Linux/x86_64 to Linux/ARM:
  
--cFlags="-gcc-toolchain;$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64;-fpic;-ffunction-sections;-funwind-tables;-fstack-protector-strong;-Wno-invalid-command-line-argument;-Wno-unused-command-line-argument;-no-canonical-prefixes;-fno-integrated-as;-target;armv7-none-linux-androideabi;-march=armv7-a;-mfloat-abi=softfp;-mfpu=vfpv3-d16;-mthumb;-Os;-g;-DNDEBUG;-fomit-frame-pointer;-fno-strict-aliasing;-DANDROID;-Wa,--noexecstack;-Wformat;-Werror=format-security;-isystem;$NDK/platforms/android-21/arch-arm/usr/include"
+
<pre>
 +
CC=arm-linux-gnueabihf-gcc ldc-build-runtime --ninja --dFlags="-w;-mtriple=arm-linux-gnueabihf" --targetSystem="Linux;UNIX"
 +
</pre>
  
--linkerFlags="-Wl,-z,nocopyreloc;--sysroot=$NDK/platforms/android-21/arch-arm;-lgcc;-gcc-toolchain;$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64;-target;armv7-none-linux-androideabi;-no-canonical-prefixes;-fuse-ld=bfd;-Wl,--fix-cortex-a8;-Wl,--no-undefined;-Wl,-z,noexecstack;-Wl,-z,relro;-Wl,-z,now;-Wl,--warn-shared-textrel;-Wl,--fatal-warnings;-fPIE;-pie"
+
From Windows to Linux/ARM, e.g., by using an official [Raspberry PI toolchain](http://gnutoolchains.com/raspberry/):
  
--dFlags="-w;-mtriple=armv7-none-linux-android" --ninja --testrunners
+
<pre>
 +
set CC=arm-linux-gnueabihf-gcc
 +
ldc-build-runtime --ninja --dFlags=-w;-mtriple=arm-linux-gnueabihf --targetSystem=Linux;UNIX CMAKE_C_COMPILER_WORKS=True CMAKE_SYSTEM_NAME=Linux BUILD_SHARED_LIBS=OFF
 
</pre>
 
</pre>
  
If you built LDC yourself from a non-tagged source, you will most likely get an error when trying to download the LDC source archive. In that case, use the <tt>--ldcSrcDir=/path/to/ldc-src</tt> option to reuse your source tree.
+
Cross-compiling to Android/ARM using the Android NDK is more involved, so ldc-build-runtime features a target preset for it. First, you set the path to your NDK and cross-compiler, and then you simply specify the target preset:
  
 +
<pre>
 +
export NDK=/path/to/your/android-ndk-r15c
 +
export CC=$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin/clang
 +
ldc-build-runtime --ninja [--testrunners] --targetPreset=Android-arm
 +
</pre>
  
 
== Usage with LTO ==
 
== Usage with LTO ==

Revision as of 00:37, 12 September 2017

Starting with version 1.4, LDC ships with a small build tool to allow you to recompile the runtime standard library (and optionally the accompanying testrunners) the way you want, ldc-build-runtime.

Use cases

  • Enabling Link-Time Optimization (LTO) for the runtime libraries by recompiling them with -flto. Linking against these may result in significant performance gains and smaller binaries.
  • Enabling sanitizer checks via -fsanitize.
  • Cross-compilation/linking, as a set of existing druntime/Phobos libraries for the selected target platform is required to cross-compile and link D executables and shared libraries.
    • This scenario also includes porting LDC to a new target platform, i.e., working on the runtime libraries on an arbitrary already supported host platform while possibly patching the host LDC in parallel (ABI etc.) until the runtime libraries can be successfully cross-built to the new target and ideally all testrunners run successfully (in an emulator or natively on the target).

Prerequisites

  • CMake
  • Either Make or Ninja (recommended, enable with --ninja)
  • C toolchain (compiler, linker and libraries): gcc, clang, Microsoft Visual C++, …

How it works

If run without special command-line options, ldc-build-runtime automates:

  • Creating a build directory
  • Downloading & extracting the LDC source archive matching the LDC version
  • Invoking CMake to generate the Makefile for the runtime libraries
  • Invoking Make/Ninja to build the runtime libraries

Basic usage

The primary aim is to allow specifying additional compiler/linker command-line options and customizing CMake variables.
Run ldc-build-runtime -h for the full list of command-line options.

ldc-build-runtime [--ninja] [-j4] [--testrunners] [--dFlags=…] [--cFlags=…] [--linkerFlags=…] [CMAKE_VAR1=value1] [CMAKE_VAR2=value2 …]

E.g., to enable Link-Time-Optimization between your user code and the runtime libraries, you can recompile the libraries via:

ldc-build-runtime --ninja --dFlags="-flto=full" BUILD_SHARED_LIBS=OFF

Usage for cross-compilation

CC=cross-gcc ldc-build-runtime [--ninja] [-j4] --dFlags="-mtriple=…;…" [--cFlags=…] [--linkerFlags=…] --targetSystem=… …

For example, to cross-compile from Linux/x86_64 to Linux/ARM:

CC=arm-linux-gnueabihf-gcc ldc-build-runtime --ninja --dFlags="-w;-mtriple=arm-linux-gnueabihf" --targetSystem="Linux;UNIX" 

From Windows to Linux/ARM, e.g., by using an official [Raspberry PI toolchain](http://gnutoolchains.com/raspberry/):

set CC=arm-linux-gnueabihf-gcc
ldc-build-runtime --ninja --dFlags=-w;-mtriple=arm-linux-gnueabihf --targetSystem=Linux;UNIX CMAKE_C_COMPILER_WORKS=True CMAKE_SYSTEM_NAME=Linux BUILD_SHARED_LIBS=OFF

Cross-compiling to Android/ARM using the Android NDK is more involved, so ldc-build-runtime features a target preset for it. First, you set the path to your NDK and cross-compiler, and then you simply specify the target preset:

export NDK=/path/to/your/android-ndk-r15c
export CC=$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin/clang
ldc-build-runtime --ninja [--testrunners] --targetPreset=Android-arm

Usage with LTO

(very brief documentation that should be improved and expanded)

It is likely that your system's ranlib+ar cannot handle the LTO object files that LDC produces. To solve this, you will have to direct CMake to the LLVM tools that _can_ handle them. E.g.

./ldc-build-runtime --dFlags='-flto=full' --cFlags='-flto=full' BUILD_SHARED_LIBS=OFF LD_FLAGS="-lto_library=/Users/johan/ldc/johan/build50/lib/libLTO-ldc.dylib" --ninja CMAKE_AR=/Users/johan/llvm/llvm50/install/bin/llvm-ar CMAKE_RANLIB=/Users/johan/llvm/llvm50/install/bin/llvm-ranlib

This issue should be fixed after LDC is used to link the runtime, see https://github.com/ldc-developers/ldc/issues/2309.

OSX only: another issue is that a ThinLTO version of the standard library will result in linker errors due to this issue: https://github.com/ldc-developers/ldc/issues/2312 . (this is not an issue if gold or lld is used)