Skip to content

Commit 4cf228b

Browse files
joakim-noahkinke
authored andcommitted
Add preset configurations, such as C/D compiler and linker flags, for cross-compilation targets tried by the ldc developers, starting with Android-arm and Android-aarch64. (#2301)
1 parent e31a3d3 commit 4cf228b

File tree

3 files changed

+123
-4
lines changed

3 files changed

+123
-4
lines changed

runtime/CMakeLists.txt

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
project(runtime)
1+
project(runtime C)
22

33
cmake_minimum_required(VERSION 2.8.9)
44

5+
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR})
6+
57
include(CheckIncludeFile)
68

79
# Verify required variables if this CMake project is NOT embedded in the LDC CMake project.
@@ -43,11 +45,15 @@ set(RT_ARCHIVE_WITH_LDC AUTO CACHE STRING "Whet
4345
set(RT_CFLAGS "" CACHE STRING "Runtime extra C compiler flags, separated by ' '")
4446
set(LD_FLAGS "" CACHE STRING "Runtime extra C linker flags, separated by ' '")
4547
set(C_SYSTEM_LIBS AUTO CACHE STRING "C system libraries for linking shared libraries and test runners, separated by ';'")
46-
set(TARGET_SYSTEM AUTO CACHE STRING "Targeted platform for cross-compilation (e.g., 'Linux;UNIX', 'Darwin;APPLE;UNIX', 'Windows;MSVC')")
48+
set(TARGET_SYSTEM AUTO CACHE STRING "Target OS/toolchain for cross-compilation (e.g., 'Linux;UNIX', 'Darwin;APPLE;UNIX', 'Windows;MSVC')")
49+
set(LDC_TARGET_PRESET "" CACHE STRING "Use a preset target configuration for cross-compilation, by passing format OS-arch (e.g., 'Linux-arm', 'Mac-x64', 'Windows-aarch64', 'Android-x86')")
4750

4851
set(CMAKE_INSTALL_LIBDIR ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX})
4952

50-
# Auto-detect TARGET_SYSTEM
53+
# Use LDC_TARGET_PRESET to configure target runtime
54+
include(PresetRuntimeConfiguration)
55+
56+
# Auto-detect TARGET_SYSTEM from host
5157
if("${TARGET_SYSTEM}" STREQUAL "AUTO")
5258
set(TARGET_SYSTEM ${CMAKE_SYSTEM_NAME})
5359
# Additionally add MSVC, APPLE and/or UNIX
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# - Preset cross-compilation configurations for C/ASM and D compilation
2+
# and linking, for supported targets
3+
#
4+
# This module sets compiler flags for a few C and assembly files in
5+
# DRuntime and Phobos, and linker flags to link the standard library as
6+
# a shared library and build the test runners, for various
7+
# cross-compilation targets that the LDC developers have tried out.
8+
#
9+
# It is enabled by setting LDC_TARGET_PRESET to a supported platform,
10+
# after which the appropriate TARGET_SYSTEM is set and a target triple
11+
# is appended to D_FLAGS.
12+
#
13+
# You can pass in custom RT_CFLAGS and LD_FLAGS of your choosing, but
14+
# if they're left unconfigured, they will also be set to sensible
15+
# defaults.
16+
17+
if(NOT LDC_TARGET_PRESET STREQUAL "")
18+
if(LDC_TARGET_PRESET MATCHES "Android")
19+
set(ANDROID_API "21")
20+
endif()
21+
# This initial RT_CFLAGS/LD_FLAGS configuration for Android is a
22+
# convenience for natively compiling, because CMake cannot detect
23+
# Android as a separate platform from Linux.
24+
if(RT_CFLAGS STREQUAL "" AND LDC_TARGET_PRESET MATCHES "Android")
25+
set(RT_CFLAGS_UNCONFIGURED True)
26+
set(RT_CFLAGS "-ffunction-sections -funwind-tables -fstack-protector-strong -Wno-invalid-command-line-argument -Wno-unused-command-line-argument -no-canonical-prefixes -g -DNDEBUG -DANDROID -D__ANDROID_API__=${ANDROID_API} -Wa,--noexecstack -Wformat -Werror=format-security -fpie")
27+
28+
if(LDC_TARGET_PRESET MATCHES "arm")
29+
append("-target armv7-none-linux-androideabi${ANDROID_API} -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -mthumb -Os" RT_CFLAGS)
30+
elseif(LDC_TARGET_PRESET MATCHES "aarch64")
31+
append("-target aarch64-none-linux-android -O2" RT_CFLAGS)
32+
endif()
33+
endif()
34+
35+
if(LD_FLAGS STREQUAL "" AND LDC_TARGET_PRESET MATCHES "Android")
36+
set(LD_FLAGS_UNCONFIGURED True)
37+
set(LD_FLAGS "-Wl,--gc-sections -Wl,-z,nocopyreloc -no-canonical-prefixes -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--warn-shared-textrel -Wl,--fatal-warnings -fpie -pie")
38+
39+
if(LDC_TARGET_PRESET MATCHES "arm")
40+
append("-target armv7-none-linux-androideabi${ANDROID_API} -Wl,--fix-cortex-a8" LD_FLAGS)
41+
elseif(LDC_TARGET_PRESET MATCHES "aarch64")
42+
append("-target aarch64-none-linux-android" LD_FLAGS)
43+
endif()
44+
endif()
45+
46+
if(LDC_TARGET_PRESET MATCHES "Windows")
47+
set(TARGET_SYSTEM "Windows;MSVC")
48+
if(LDC_TARGET_PRESET MATCHES "x64")
49+
# stub example, fill in with the rest
50+
list(APPEND D_FLAGS "-mtriple=x86_64-pc-windows-msvc")
51+
endif()
52+
elseif(LDC_TARGET_PRESET MATCHES "Android")
53+
set(TARGET_SYSTEM "Android;Linux;UNIX")
54+
55+
# Check if we're using the NDK by looking for the toolchains
56+
# directory in CC
57+
if(CMAKE_C_COMPILER MATCHES "toolchains")
58+
# Extract the NDK path and platform from CC
59+
string(REGEX REPLACE ".toolchains.+" "" NDK_PATH ${CMAKE_C_COMPILER})
60+
string(REGEX REPLACE ".+/prebuilt/([^/]+)/.+" "\\1" NDK_HOST_PLATFORM ${CMAKE_C_COMPILER})
61+
62+
if(LDC_TARGET_PRESET MATCHES "arm")
63+
set(TARGET_ARCH "arm")
64+
set(LLVM_TARGET_TRIPLE "armv7-none-linux-android")
65+
set(TOOLCHAIN_TARGET_TRIPLE "arm-linux-androideabi")
66+
elseif(LDC_TARGET_PRESET MATCHES "aarch64")
67+
set(TARGET_ARCH "arm64")
68+
set(LLVM_TARGET_TRIPLE "aarch64-none-linux-android")
69+
set(TOOLCHAIN_TARGET_TRIPLE "aarch64-linux-android")
70+
else()
71+
message(FATAL_ERROR "Android platform ${LDC_TARGET_PRESET} is not supported.")
72+
endif()
73+
list(APPEND D_FLAGS "-mtriple=${LLVM_TARGET_TRIPLE}")
74+
set(TOOLCHAIN_VERSION "4.9")
75+
76+
if(RT_CFLAGS_UNCONFIGURED)
77+
append("-gcc-toolchain ${NDK_PATH}/toolchains/${TOOLCHAIN_TARGET_TRIPLE}-${TOOLCHAIN_VERSION}/prebuilt/${NDK_HOST_PLATFORM} --sysroot ${NDK_PATH}/sysroot -isystem ${NDK_PATH}/sysroot/usr/include/${TOOLCHAIN_TARGET_TRIPLE}" RT_CFLAGS)
78+
79+
if(LDC_TARGET_PRESET MATCHES "arm")
80+
append("-fno-integrated-as" RT_CFLAGS)
81+
endif()
82+
endif()
83+
84+
if(LD_FLAGS_UNCONFIGURED)
85+
set(LD_BFD "-fuse-ld=bfd")
86+
# work around Windows bug, android-ndk/ndk#75
87+
if(NDK_HOST_PLATFORM MATCHES "windows")
88+
set(LD_BFD "${LD_BFD}.exe")
89+
endif()
90+
91+
append("--sysroot=${NDK_PATH}/platforms/android-${ANDROID_API}/arch-${TARGET_ARCH} -gcc-toolchain ${NDK_PATH}/toolchains/${TOOLCHAIN_TARGET_TRIPLE}-${TOOLCHAIN_VERSION}/prebuilt/${NDK_HOST_PLATFORM} ${LD_BFD}" LD_FLAGS)
92+
endif()
93+
endif()
94+
else()
95+
message(FATAL_ERROR "LDC_TARGET_PRESET ${LDC_TARGET_PRESET} is not supported yet, pull requests to add common flags are welcome.")
96+
endif()
97+
endif()

runtime/ldc-build-runtime.d.in

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ struct Config {
1212
string ldcSourceDir;
1313
bool ninja;
1414
bool buildTestrunners;
15+
string targetPreset;
16+
string[] targetSystem;
1517
string[] dFlags;
1618
string[] cFlags;
1719
string[] linkerFlags;
@@ -138,20 +140,31 @@ void prepareLdcSource() {
138140
}
139141

140142
void runCMake() {
141-
import std.array : byPair, join;
143+
import std.array : empty, byPair, join;
144+
import std.regex : matchFirst;
142145

143146
const wd = WorkingDirScope(config.buildDir);
144147

148+
if(config.dFlags.empty)
149+
config.dFlags ~= "-w";
150+
151+
if(config.targetSystem.empty)
152+
config.targetSystem ~= "AUTO";
153+
145154
string[] args = [
146155
"cmake",
147156
"-DLDC_EXE_FULL=" ~ config.ldcExecutable,
148157
"-DD_VERSION=@D_VERSION@",
149158
"-DDMDFE_MINOR_VERSION=@DMDFE_MINOR_VERSION@",
150159
"-DDMDFE_PATCH_VERSION=@DMDFE_PATCH_VERSION@",
160+
"-DLDC_TARGET_PRESET=" ~ config.targetPreset,
161+
"-DTARGET_SYSTEM=" ~ config.targetSystem.join(";"),
151162
"-DD_FLAGS=" ~ config.dFlags.join(";"),
152163
"-DRT_CFLAGS=" ~ config.cFlags.join(" "),
153164
"-DLD_FLAGS=" ~ config.linkerFlags.join(" "),
154165
];
166+
if(config.targetPreset.matchFirst("^Android"))
167+
args ~= ["-DCMAKE_SYSTEM_NAME=Linux", "-DCMAKE_C_COMPILER_WORKS=True"];
155168
foreach (pair; config.cmakeVars.byPair)
156169
args ~= "-D" ~ pair[0] ~ '=' ~ pair[1];
157170
if (config.ninja)
@@ -226,6 +239,8 @@ void parseCommandLine(string[] args) {
226239
"ldcSrcDir", "Path to LDC source directory (if not specified: downloads & extracts source archive into '<buildDir>/ldc-src')", &config.ldcSourceDir,
227240
"ninja", "Use Ninja as CMake build system", &config.ninja,
228241
"testrunners", "Build the testrunner executables too", &config.buildTestrunners,
242+
"targetPreset","Target configuration preset by LDC devs, e.g. Android-arm", &config.targetPreset,
243+
"targetSystem","Target OS/toolchain (separated by ';'), e.g. Windows;MSVC", &config.targetSystem,
229244
"dFlags", "LDC flags for the D modules (separated by ';')", &config.dFlags,
230245
"cFlags", "C/ASM compiler flags for the handful of C/ASM files (separated by ';')", &config.cFlags,
231246
"linkerFlags", "C linker flags for shared libraries and testrunner executables (separated by ';')", &config.linkerFlags,
@@ -251,6 +266,7 @@ void parseCommandLine(string[] args) {
251266
" * CMake\n" ~
252267
" * either Make or Ninja (recommended, enable with '--ninja')\n" ~
253268
" * C toolchain (compiler and linker)\n" ~
269+
"--targetPreset currently supports Android-arm or Android-aarch64.\n" ~
254270
"All arguments are optional.\n" ~
255271
"CMake variables (see runtime/CMakeLists.txt in LDC source) can be specified via arguments like 'VAR=value'.\n",
256272
helpInformation.options

0 commit comments

Comments
 (0)