Testing out the new cross-compilation support in ldc master

Joakim via digitalmars-d-ldc digitalmars-d-ldc at puremagic.com
Fri Aug 18 00:34:04 PDT 2017


I merged kinke's pull two weeks ago that adds a small D build 
tool which makes it easy to download and cross-compile the 
standard libary for other platforms, so you can easily use the 
official ldc releases for {Mac,Win,Linux}/{x86,x64} as a 
cross-compiler for newer platforms that ldc is coming to, like 
Android/ARM or Linux/PPC.  It can also be used for LTO or 
sanitizer-enabled builds of the standard library, basically 
anything where you want the stdlib built differently:

https://github.com/ldc-developers/ldc/pull/2253

Right now, it has to be built from the git repo, as the first 
official release it will ship with is the upcoming ldc 1.4 beta, 
would be good if more people tried it out and let us know how 
it's working. Generally speaking, you need all the same dev tools 
you'd need if you were building from source before, such as git, 
CMake, Make or Ninja, and a C cross-compiler/linker toolchain for 
the platform you want to target (needed because of a few 
C/assembly files in the stdlib).

Specifically, I'm interested in how well it works on Mac and 
Windows to cross-compile for Android/ARM, as I haven't used 
Mac/Windows in years and don't have those platforms available.  
You can wait till the ldc 1.4 beta is out, but if you're 
comfortable building ldc master from source, here are some 
instructions on how to try it.  You will be following the same 
routine as the first third of this wiki page, except you won't be 
limited to cross-compiling from linux anymore:

https://wiki.dlang.org/Build_LDC_for_Android

The first three steps are the differences from that wiki page, 
then instructions on building and using the new tool:

1. All the same prerequisites, except you don't need the Android 
SDK nor obviously the linux/x64 shell.  See the steps to download 
the NDK for Windows 10, for a simple way on how to get it.
2. For Android/ARM, you need to compile a lightly tweaked llvm, 
as shown in the instructions there (with one exception, leave off 
the default target triple option).  For other targets, like 
Linux/PPC, a stock llvm is fine.
3. Build ldc and druntime/phobos as you would normally and shown 
there, except using the master branch and no need to apply those 
Android patches.
4. Once you've built ldc, druntime and phobos, build kinke's new 
tool with this command:

make ldc-build-runtime

5. Finally, you use this new tool to cross-compile the standard 
library and possibly the test runners for your target.  Here's an 
example from the comments of that PR, for Android/ARM, all one 
command that I've expanded for legibility:

CC=/home/joakim/ndk-r15c/toolchains/llvm/prebuilt/linux-x86_64/bin/clang

./bin/ldc-build-runtime --ldcSrcDir=/home/joakim/ldc 
BUILD_SHARED_LIBS=OFF C_SYSTEM_LIBS="m;c"

--cFlags="-gcc-toolchain;/home/joakim/ndk-r15c/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;/home/joakim/ndk-r15c/platforms/android-21/arch-arm/usr/include"

--linkerFlags="-Wl,-z,nocopyreloc;--sysroot=/home/joakim/ndk-r15c/platforms/android-21/arch-arm;-lgcc;-gcc-toolchain;/home/joakim/ndk-r15c/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

CC specifies the path to your C cross-compiler, which is assumed 
to invoke the right linker for your target.  For Android/ARM, 
replace all uses of /home/joakim/ndk-r15c with the path to your 
NDK.  I think you have to specify --ldcSrcDir, the path to your 
ldc source, since you're building from the git repo.  The Android 
port doesn't support building the stdlib as a shared library yet, 
so I turn it off.  It also uses a different set of C system 
libraries, because Android includes pthreads in libc, for example.

The --cFlags and --linkerFlags were taken from running the 
Android ndk-build script in verbose mode.  Use --dFlags to set 
the llvm target triple for your platform, as I do here for 
Android/ARM.  Leave off --ninja if you'd like to use Make 
instead, same for --testrunners if you don't want to run the 
stdlib tests.  Run ./ldc-build-runtime -h to see the full list of 
flags.

Once that builds, assuming all goes well, try downloading 
druntime-test-runner and phobos2-test-runner to a terminal 
emulator on your Android/ARM device and running them, if you 
built the test runners.  Otherwise, you can follow the 
instructions here to cross-compile a sample D program, though 
you'll need to add the -mtriple=armv7-none-linux-android flag 
when calling ldc:

https://wiki.dlang.org/Build_D_for_Android#Build_a_command-line_executable

kinke, will setting CC first work on Windows and other shells?  
If not, I guess it will work if passed after the invocation of 
ldc-build-runtime, like all the other flags.

I'll build a native ldc 1.4 for Android/ARM, to make available 
with the upcoming official beta release, just as I do now for ldc 
1.3 on my own github repo.  Maybe that termux-packages build 
script can be merged into the official packaging ldc-scripts 
eventually.

I'd like to make it easier to cross-compile for supported 
platforms, by being able to pass a target OS and architecture 
alone to this build tool and CMake, which would call some default 
C and linker flags in the official CMake config.  You will still 
be able to override the defaults with custom C/linker flags.  
I'll submit a PR for Android/ARM, hopefully we'll have more 
defaults for Linux/PPC, Linux/armhf, and other more well-tested 
platforms.  I hope you're not waiting on that PR to push the ldc 
1.4 beta out, kinke.


More information about the digitalmars-d-ldc mailing list