-
-
Notifications
You must be signed in to change notification settings - Fork 270
Add LDC_TARGET_PRESET CMake variable for runtime, to make cross-compilation easier #2301
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,97 @@ | ||
| # - Preset cross-compilation configurations for C/ASM and D compilation | ||
| # and linking, for supported targets | ||
| # | ||
| # This module sets compiler flags for a few C and assembly files in | ||
| # DRuntime and Phobos, and linker flags to link the standard library as | ||
| # a shared library and build the test runners, for various | ||
| # cross-compilation targets that the LDC developers have tried out. | ||
| # | ||
| # It is enabled by setting LDC_TARGET_PRESET to a supported platform, | ||
| # after which the appropriate TARGET_SYSTEM is set and a target triple | ||
| # is appended to D_FLAGS. | ||
| # | ||
| # You can pass in custom RT_CFLAGS and LD_FLAGS of your choosing, but | ||
| # if they're left unconfigured, they will also be set to sensible | ||
| # defaults. | ||
|
|
||
| if(NOT LDC_TARGET_PRESET STREQUAL "") | ||
| if(LDC_TARGET_PRESET MATCHES "Android") | ||
| set(ANDROID_API "21") | ||
| endif() | ||
| # This initial RT_CFLAGS/LD_FLAGS configuration for Android is a | ||
| # convenience for natively compiling, because CMake cannot detect | ||
| # Android as a separate platform from Linux. | ||
| if(RT_CFLAGS STREQUAL "" AND LDC_TARGET_PRESET MATCHES "Android") | ||
| set(RT_CFLAGS_UNCONFIGURED True) | ||
| 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") | ||
|
|
||
| if(LDC_TARGET_PRESET MATCHES "arm") | ||
| append("-target armv7-none-linux-androideabi${ANDROID_API} -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -mthumb -Os" RT_CFLAGS) | ||
| elseif(LDC_TARGET_PRESET MATCHES "aarch64") | ||
| append("-target aarch64-none-linux-android -O2" RT_CFLAGS) | ||
| endif() | ||
| endif() | ||
|
|
||
| if(LD_FLAGS STREQUAL "" AND LDC_TARGET_PRESET MATCHES "Android") | ||
| set(LD_FLAGS_UNCONFIGURED True) | ||
| 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") | ||
|
|
||
| if(LDC_TARGET_PRESET MATCHES "arm") | ||
| append("-target armv7-none-linux-androideabi${ANDROID_API} -Wl,--fix-cortex-a8" LD_FLAGS) | ||
| elseif(LDC_TARGET_PRESET MATCHES "aarch64") | ||
| append("-target aarch64-none-linux-android" LD_FLAGS) | ||
| endif() | ||
| endif() | ||
|
|
||
| if(LDC_TARGET_PRESET MATCHES "Windows") | ||
| set(TARGET_SYSTEM "Windows;MSVC") | ||
| if(LDC_TARGET_PRESET MATCHES "x64") | ||
| # stub example, fill in with the rest | ||
| list(APPEND D_FLAGS "-mtriple=x86_64-pc-windows-msvc") | ||
| endif() | ||
| elseif(LDC_TARGET_PRESET MATCHES "Android") | ||
| set(TARGET_SYSTEM "Android;Linux;UNIX") | ||
|
|
||
| # Check if we're using the NDK by looking for the toolchains | ||
| # directory in CC | ||
| if(CMAKE_C_COMPILER MATCHES "toolchains") | ||
| # Extract the NDK path and platform from CC | ||
| string(REGEX REPLACE ".toolchains.+" "" NDK_PATH ${CMAKE_C_COMPILER}) | ||
| string(REGEX REPLACE ".+/prebuilt/([^/]+)/.+" "\\1" NDK_HOST_PLATFORM ${CMAKE_C_COMPILER}) | ||
|
|
||
| if(LDC_TARGET_PRESET MATCHES "arm") | ||
| set(TARGET_ARCH "arm") | ||
| set(LLVM_TARGET_TRIPLE "armv7-none-linux-android") | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is, but only for llvm 5.0. I figured that since we're shipping 1.4 with 4.0.1, I'll worry about that later. |
||
| set(TOOLCHAIN_TARGET_TRIPLE "arm-linux-androideabi") | ||
| elseif(LDC_TARGET_PRESET MATCHES "aarch64") | ||
| set(TARGET_ARCH "arm64") | ||
| set(LLVM_TARGET_TRIPLE "aarch64-none-linux-android") | ||
| set(TOOLCHAIN_TARGET_TRIPLE "aarch64-linux-android") | ||
| else() | ||
| message(FATAL_ERROR "Android platform ${LDC_TARGET_PRESET} is not supported.") | ||
| endif() | ||
| list(APPEND D_FLAGS "-mtriple=${LLVM_TARGET_TRIPLE}") | ||
| set(TOOLCHAIN_VERSION "4.9") | ||
|
|
||
| if(RT_CFLAGS_UNCONFIGURED) | ||
| 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) | ||
|
|
||
| if(LDC_TARGET_PRESET MATCHES "arm") | ||
| append("-fno-integrated-as" RT_CFLAGS) | ||
| endif() | ||
| endif() | ||
|
|
||
| if(LD_FLAGS_UNCONFIGURED) | ||
| set(LD_BFD "-fuse-ld=bfd") | ||
| # work around Windows bug, android-ndk/ndk#75 | ||
| if(NDK_HOST_PLATFORM MATCHES "windows") | ||
| set(LD_BFD "${LD_BFD}.exe") | ||
| endif() | ||
|
|
||
| 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) | ||
| endif() | ||
| endif() | ||
| else() | ||
| message(FATAL_ERROR "LDC_TARGET_PRESET ${LDC_TARGET_PRESET} is not supported yet, pull requests to add common flags are welcome.") | ||
| endif() | ||
| endif() | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,6 +12,8 @@ struct Config { | |
| string ldcSourceDir; | ||
| bool ninja; | ||
| bool buildTestrunners; | ||
| string targetPreset; | ||
| string[] targetSystem; | ||
| string[] dFlags; | ||
| string[] cFlags; | ||
| string[] linkerFlags; | ||
|
|
@@ -138,20 +140,31 @@ void prepareLdcSource() { | |
| } | ||
|
|
||
| void runCMake() { | ||
| import std.array : byPair, join; | ||
| import std.array : empty, byPair, join; | ||
| import std.regex : matchFirst; | ||
|
|
||
| const wd = WorkingDirScope(config.buildDir); | ||
|
|
||
| if(config.dFlags.empty) | ||
| config.dFlags ~= "-w"; | ||
|
|
||
| if(config.targetSystem.empty) | ||
| config.targetSystem ~= "AUTO"; | ||
|
|
||
| string[] args = [ | ||
| "cmake", | ||
| "-DLDC_EXE_FULL=" ~ config.ldcExecutable, | ||
| "-DD_VERSION=@D_VERSION@", | ||
| "-DDMDFE_MINOR_VERSION=@DMDFE_MINOR_VERSION@", | ||
| "-DDMDFE_PATCH_VERSION=@DMDFE_PATCH_VERSION@", | ||
| "-DLDC_TARGET_PRESET=" ~ config.targetPreset, | ||
| "-DTARGET_SYSTEM=" ~ config.targetSystem.join(";"), | ||
| "-DD_FLAGS=" ~ config.dFlags.join(";"), | ||
| "-DRT_CFLAGS=" ~ config.cFlags.join(" "), | ||
| "-DLD_FLAGS=" ~ config.linkerFlags.join(" "), | ||
| ]; | ||
| if(config.targetPreset.matchFirst("^Android")) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's fine like that, but FYI, |
||
| args ~= ["-DCMAKE_SYSTEM_NAME=Linux", "-DCMAKE_C_COMPILER_WORKS=True"]; | ||
| foreach (pair; config.cmakeVars.byPair) | ||
| args ~= "-D" ~ pair[0] ~ '=' ~ pair[1]; | ||
| if (config.ninja) | ||
|
|
@@ -226,6 +239,8 @@ void parseCommandLine(string[] args) { | |
| "ldcSrcDir", "Path to LDC source directory (if not specified: downloads & extracts source archive into '<buildDir>/ldc-src')", &config.ldcSourceDir, | ||
| "ninja", "Use Ninja as CMake build system", &config.ninja, | ||
| "testrunners", "Build the testrunner executables too", &config.buildTestrunners, | ||
| "targetPreset","Target configuration preset by LDC devs, e.g. Android-arm", &config.targetPreset, | ||
| "targetSystem","Target OS/toolchain (separated by ';'), e.g. Windows;MSVC", &config.targetSystem, | ||
| "dFlags", "LDC flags for the D modules (separated by ';')", &config.dFlags, | ||
| "cFlags", "C/ASM compiler flags for the handful of C/ASM files (separated by ';')", &config.cFlags, | ||
| "linkerFlags", "C linker flags for shared libraries and testrunner executables (separated by ';')", &config.linkerFlags, | ||
|
|
@@ -251,6 +266,7 @@ void parseCommandLine(string[] args) { | |
| " * CMake\n" ~ | ||
| " * either Make or Ninja (recommended, enable with '--ninja')\n" ~ | ||
| " * C toolchain (compiler and linker)\n" ~ | ||
| "--targetPreset currently supports Android-arm or Android-aarch64.\n" ~ | ||
| "All arguments are optional.\n" ~ | ||
| "CMake variables (see runtime/CMakeLists.txt in LDC source) can be specified via arguments like 'VAR=value'.\n", | ||
| helpInformation.options | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The default is
CandCXX, but since we don't use C++ in the runtime, took it out. Otherwise, CMake insists on a C++ compiler and then runs some tests that break.