Building LDC runtime libraries

From D Wiki
Revision as of 11:06, 2 September 2017 by JohanEngelen (talk | contribs) (Usage)
Jump to: navigation, search

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++, …
  • tar (can be worked around on Windows via --ldcSrcDir=/path/to/ldc-src)

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

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.

Basic usage:

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

Basic usage for cross-compilation:

CC=cross-gcc ldc-build-runtime -j4 --dFlags="-mtriple=…;…" --cFlags=… --linkerFlags=… TARGET_SYSTEM=… …

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:

export NDK=/path/to/your/android-ndk-r15c
export CC=$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin/clang

ldc-build-runtime BUILD_SHARED_LIBS=OFF C_SYSTEM_LIBS="m;c" TARGET_SYSTEM="Android;Linux;UNIX" 

--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"

--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"

--dFlags="-w;-mtriple=armv7-none-linux-android" --ninja --testrunners

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 --ldcSrcDir=/path/to/ldc-src option to reuse your source tree.


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=thin' --cFlags='-flto=thin' 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