Skip to content

Commit 11908ed

Browse files
authored
Merge pull request #4618 from kinke/android_tls
Android: Switch to native ELF TLS & latest LTS NDK, and enable shared druntime/Phobos
2 parents dad00ad + 75130c5 commit 11908ed

File tree

13 files changed

+56
-60
lines changed

13 files changed

+56
-60
lines changed

.github/actions/3-build-cross/action.yml

+9-11
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ inputs:
1414
default: false
1515
android_ndk_version:
1616
required: false
17-
default: r21e
17+
default: r26d
1818
android_api_level:
1919
required: false
20-
default: 21
20+
default: 29
2121
runs:
2222
using: composite
2323
steps:
@@ -92,32 +92,30 @@ runs:
9292
cd ..
9393
version='${{ inputs.android_ndk_version }}'
9494
curl -fL --retry 3 --max-time 300 -o android-ndk.zip \
95-
https://dl.google.com/android/repository/android-ndk-$version-linux-x86_64.zip
95+
https://dl.google.com/android/repository/android-ndk-$version-linux.zip
9696
unzip android-ndk.zip >/dev/null
9797
mv "android-ndk-$version" android-ndk
9898
rm android-ndk.zip
9999
100-
# The NDK toolchain file enforces `-g` as base C[XX] flag - remove it to
101-
# *significantly* reduce executable sizes
102-
toolchainFile="$PWD/android-ndk/build/cmake/android.toolchain.cmake"
103-
sed -i 's|^ -g$||' "$toolchainFile"
104-
105100
arch='${{ inputs.arch }}'
106101
apiLevel='${{ inputs.android_api_level }}'
107102
cmakeFlags="-DTARGET_SYSTEM='Android;Linux;UNIX'"
108103
if [[ "$arch" == armv7a ]]; then
109104
triple="$arch-linux-androideabi$apiLevel"
110105
cmakeFlags+=' -DANDROID_ABI=armeabi-v7a'
111106
elif [[ "$arch" == aarch64 ]]; then
107+
# FIXME: as of NDK rc26d, libc.a has __tls_get_addr, but libc.so only since API level 30 (Android v11)
108+
apiLevel=30
112109
triple="$arch-linux-android$apiLevel"
113110
cmakeFlags+=' -DANDROID_ABI=arm64-v8a'
114111
fi
115112
cmakeFlags+=" -DANDROID_NATIVE_API_LEVEL=$apiLevel"
116113
cmakeFlags+=" -DANDROID_STL=c++_static"
117-
cmakeFlags+=" -DCMAKE_TOOLCHAIN_FILE=$toolchainFile"
118-
cmakeFlags+=" -DLDC_LINK_MANUALLY=ON -DD_LINKER_ARGS='-fuse-ld=bfd;-L$PWD/build-cross-libs/lib;-lphobos2-ldc;-ldruntime-ldc'"
114+
cmakeFlags+=" -DCMAKE_TOOLCHAIN_FILE=$PWD/android-ndk/build/cmake/android.toolchain.cmake"
115+
cmakeFlags+=" -DANDROID_USE_LEGACY_TOOLCHAIN_FILE=OFF"
116+
cmakeFlags+=" -DLDC_LINK_MANUALLY=ON -DD_LINKER_ARGS='-L$PWD/build-cross-libs/lib;-lphobos2-ldc;-ldruntime-ldc'"
119117
120-
echo "DFLAGS=-mtriple=$triple -fvisibility=hidden -L-L$PWD/build-cross-libs/lib -gcc=$PWD/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/$triple-clang" >> $GITHUB_ENV
118+
echo "DFLAGS=-mtriple=$triple -L-L$PWD/build-cross-libs/lib -gcc=$PWD/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/$triple-clang" >> $GITHUB_ENV
121119
echo "CROSS_TRIPLE=$triple" >> $GITHUB_ENV
122120
echo "CROSS_CMAKE_FLAGS=$cmakeFlags" >> $GITHUB_ENV
123121

.github/actions/3-build-cross/android-llvm-config.in

+9-9
Original file line numberDiff line numberDiff line change
@@ -53,25 +53,25 @@ LIBFILE="${prefix}/lib/libLLVM-$version.so"
5353
components="aarch64 aarch64asmparser aarch64codegen aarch64desc aarch64disassembler aarch64info aarch64utils \
5454
aggressiveinstcombine all all-targets analysis arm armasmparser armcodegen armdesc armdisassembler arminfo armutils \
5555
asmparser asmprinter binaryformat bitreader bitstreamreader bitwriter cfguard codegen codegentypes core coroutines coverage \
56-
debuginfobtf debuginfocodeview debuginfodwarf debuginfogsym debuginfologicalview debuginfomsf debuginfopdb demangle dlltooldriver dwarflinker dwarflinkerparallel dwp \
57-
engine executionengine extensions filecheck frontendhlsl frontendopenacc frontendopenmp fuzzercli fuzzmutate globalisel instcombine \
56+
debuginfobtf debuginfocodeview debuginfodwarf debuginfogsym debuginfologicalview debuginfomsf debuginfopdb demangle dlltooldriver dwarflinker dwarflinkerclassic dwarflinkerparallel dwp \
57+
engine executionengine extensions filecheck frontenddriver frontendhlsl frontendoffloading frontendopenacc frontendopenmp fuzzercli fuzzmutate globalisel hipstdpar instcombine \
5858
instrumentation interfacestub interpreter ipo irprinter irreader jitlink libdriver lineeditor linker lto mc mca mcdisassembler \
59-
mcjit mcparser mirparser native nativecodegen objcarcopts objcopy object objectyaml option orcjit orcshared orctargetprocess \
59+
mcjit mcparser mirparser native nativecodegen objcarcopts objcopy object objectyaml option orcdebugging orcjit orcshared orctargetprocess \
6060
passes profiledata remarks runtimedyld scalaropts selectiondag spirv spirvcodegen spirvdesc spirvinfo support symbolize tablegen target targetparser textapi \
61-
transformutils vectorize webassembly webassemblyasmparser webassemblycodegen webassemblydesc webassemblydisassembler \
61+
textapibinaryreader transformutils vectorize webassembly webassemblyasmparser webassemblycodegen webassemblydesc webassemblydisassembler \
6262
webassemblyinfo webassemblyutils windowsdriver windowsmanifest x86 x86asmparser x86codegen x86desc x86disassembler x86info \
6363
x86targetmca xray"
64-
static_libs="-lLLVMWindowsManifest -lLLVMXRay -lLLVMLibDriver -lLLVMDlltoolDriver -lLLVMCoverage -lLLVMLineEditor \
64+
static_libs="-lLLVMWindowsManifest -lLLVMXRay -lLLVMLibDriver -lLLVMDlltoolDriver -lLLVMTextAPIBinaryReader -lLLVMCoverage -lLLVMLineEditor \
6565
-lLLVMSPIRVCodeGen -lLLVMSPIRVDesc -lLLVMSPIRVInfo \
6666
-lLLVMX86TargetMCA -lLLVMX86Disassembler -lLLVMX86AsmParser -lLLVMX86CodeGen -lLLVMX86Desc -lLLVMX86Info -lLLVMWebAssemblyDisassembler \
6767
-lLLVMWebAssemblyAsmParser -lLLVMWebAssemblyCodeGen -lLLVMWebAssemblyUtils -lLLVMWebAssemblyDesc -lLLVMWebAssemblyInfo -lLLVMARMDisassembler \
6868
-lLLVMARMAsmParser -lLLVMARMCodeGen -lLLVMARMDesc -lLLVMARMUtils -lLLVMARMInfo -lLLVMAArch64Disassembler \
69-
-lLLVMAArch64AsmParser -lLLVMAArch64CodeGen -lLLVMAArch64Desc -lLLVMAArch64Utils -lLLVMAArch64Info -lLLVMOrcJIT \
69+
-lLLVMAArch64AsmParser -lLLVMAArch64CodeGen -lLLVMAArch64Desc -lLLVMAArch64Utils -lLLVMAArch64Info -lLLVMOrcDebugging -lLLVMOrcJIT \
7070
-lLLVMWindowsDriver -lLLVMMCJIT -lLLVMJITLink -lLLVMInterpreter -lLLVMExecutionEngine -lLLVMRuntimeDyld -lLLVMOrcTargetProcess -lLLVMOrcShared \
7171
-lLLVMDWP -lLLVMDebugInfoLogicalView -lLLVMDebugInfoGSYM -lLLVMOption -lLLVMObjectYAML -lLLVMObjCopy -lLLVMMCA \
72-
-lLLVMMCDisassembler -lLLVMLTO -lLLVMPasses -lLLVMCFGuard -lLLVMCoroutines -lLLVMipo \
73-
-lLLVMVectorize -lLLVMLinker -lLLVMInstrumentation -lLLVMFrontendOpenMP -lLLVMFrontendOpenACC -lLLVMFrontendHLSL -lLLVMExtensions \
74-
-lLLVMDWARFLinkerParallel -lLLVMDWARFLinker -lLLVMGlobalISel -lLLVMMIRParser -lLLVMAsmPrinter -lLLVMSelectionDAG \
72+
-lLLVMMCDisassembler -lLLVMLTO -lLLVMPasses -lLLVMHipStdPar -lLLVMCFGuard -lLLVMCoroutines -lLLVMipo \
73+
-lLLVMVectorize -lLLVMLinker -lLLVMInstrumentation -lLLVMFrontendOpenMP -lLLVMFrontendOffloading -lLLVMFrontendOpenACC -lLLVMFrontendHLSL -lLLVMFrontendDriver -lLLVMExtensions \
74+
-lLLVMDWARFLinkerParallel -lLLVMDWARFLinkerClassic -lLLVMDWARFLinker -lLLVMGlobalISel -lLLVMMIRParser -lLLVMAsmPrinter -lLLVMSelectionDAG \
7575
-lLLVMCodeGen -lLLVMTarget -lLLVMObjCARCOpts -lLLVMCodeGenTypes -lLLVMIRPrinter -lLLVMInterfaceStub -lLLVMFileCheck -lLLVMFuzzMutate \
7676
-lLLVMScalarOpts -lLLVMInstCombine -lLLVMAggressiveInstCombine -lLLVMTransformUtils -lLLVMBitWriter -lLLVMAnalysis \
7777
-lLLVMProfileData -lLLVMSymbolize -lLLVMDebugInfoBTF -lLLVMDebugInfoPDB -lLLVMDebugInfoMSF -lLLVMDebugInfoDWARF -lLLVMObject -lLLVMTextAPI -lLLVMMCParser -lLLVMIRReader -lLLVMAsmParser -lLLVMMC -lLLVMDebugInfoCodeView \

.github/actions/5a-android-x86/action.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ runs:
2323
# use bootstrap-ldc, which is guaranteed to be native
2424
bootstrap-ldc/bin/ldc-build-runtime --ninja \
2525
--buildDir="build-libs-$arch" \
26-
--dFlags="-mtriple=$triple;-fvisibility=hidden" \
26+
--dFlags="-mtriple=$triple" \
2727
--ldcSrcDir="$PWD/ldc" \
2828
"${flags[@]}" \
2929
ANDROID_ABI="$abi" # override the one in CROSS_CMAKE_FLAGS
3030
3131
mkdir "installed/lib-$arch"
32-
cp "build-libs-$arch"/lib/*.a "installed/lib-$arch/"
32+
cp "build-libs-$arch"/lib/* "installed/lib-$arch/"

.github/workflows/main.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ jobs:
171171
-DD_COMPILER_FLAGS="-O -flto=full -defaultlib=phobos2-ldc-lto,druntime-ldc-lto -L-exported_symbol '-L__*' -L-w"
172172
-DEXTRA_CXXFLAGS=-flto=full
173173
with_pgo: true
174+
llvm_version: 17.0.6 # TODO
174175

175176
- job_name: Android armv7a
176177
host_os: ubuntu-20.04
@@ -192,7 +193,6 @@ jobs:
192193
timeout-minutes: 60
193194
env:
194195
MACOSX_DEPLOYMENT_TARGET: 11.0
195-
LLVM_VERSION: 17.0.6 # TODO
196196
steps:
197197
- uses: actions/checkout@v4
198198
with:
@@ -202,7 +202,7 @@ jobs:
202202
uses: ./.github/actions/1-setup
203203
with:
204204
clang_version: ${{ env.CLANG_VERSION }}
205-
llvm_version: ${{ env.LLVM_VERSION }}
205+
llvm_version: ${{ matrix.llvm_version || env.LLVM_VERSION }}
206206
arch: x86_64
207207
- name: Build bootstrap LDC
208208
uses: ./.github/actions/2-build-bootstrap
@@ -218,7 +218,7 @@ jobs:
218218
with:
219219
arch: ${{ matrix.arch }}
220220
os: ${{ matrix.os }}
221-
llvm_version: ${{ env.LLVM_VERSION }}
221+
llvm_version: ${{ matrix.llvm_version || env.LLVM_VERSION }}
222222
cmake_flags: ${{ matrix.extra_cmake_flags }}
223223
with_pgo: ${{ matrix.with_pgo }}
224224

CHANGELOG.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22

33
#### Big news
44
- Frontend, druntime and Phobos are at version [2.108.0+](https://dlang.org/changelog/2.108.0.html). (#4591, #4615, #4619)
5-
- Support for [LLVM 18](https://releases.llvm.org/18.1.0/docs/ReleaseNotes.html). The prebuilt packages use v18.1.3 (except for Android and macOS arm64). (#4599, #4605, #4607, #4604, #4622)
5+
- Support for [LLVM 18](https://releases.llvm.org/18.1.0/docs/ReleaseNotes.html). The prebuilt packages use v18.1.3 (except for macOS arm64). (#4599, #4605, #4607, #4604, #4622)
6+
- Android: Switch to native ELF TLS, supported since API level 29 (Android v10), dropping our former custom TLS emulation (requiring a modified LLVM and a legacy ld.bfd linker). The prebuilt packages themselves require Android v10+ (armv7a) / v11+ (aarch64) too, and are built with NDK r26d. Shared druntime and Phobos libraries are now available (`-link-defaultlib-shared`), as on regular Linux. (#4618)
67

78
#### Platform support
89
- Supports LLVM 11 - 18.
910

1011
#### Bug fixes
12+
- Android: Support the lld linker. (#3918)
1113

1214
# LDC 1.37.0 (2024-03-03)
1315

driver/linker-gcc.cpp

-8
Original file line numberDiff line numberDiff line change
@@ -621,14 +621,6 @@ void ArgsBuilder::build(llvm::StringRef outputPath,
621621
void ArgsBuilder::addLinker() {
622622
llvm::StringRef linker = opts::linker;
623623

624-
// Default to ld.bfd for Android (placing .tdata and .tbss sections adjacent
625-
// to each other as required by druntime's rt.sections_android, contrary to
626-
// gold and lld as of Android NDK r21d).
627-
if (global.params.targetTriple->getEnvironment() == llvm::Triple::Android &&
628-
opts::linker.getNumOccurrences() == 0) {
629-
linker = "bfd";
630-
}
631-
632624
if (!linker.empty())
633625
args.push_back(("-fuse-ld=" + linker).str());
634626
}

driver/main.d

-15
Original file line numberDiff line numberDiff line change
@@ -59,18 +59,3 @@ version (Windows)
5959
SetConsoleOutputCP(originalOutputCP);
6060
}
6161
}
62-
63-
// TLS bracketing symbols required for our custom TLS emulation on Android
64-
// as we don't have a D main() function for LDC and LDMD.
65-
version (Android)
66-
{
67-
import ldc.attributes;
68-
69-
extern(C) __gshared
70-
{
71-
@section(".tdata")
72-
int _tlsstart = 0;
73-
@section(".tcommon")
74-
int _tlsend = 0;
75-
}
76-
}

driver/targetmachine.cpp

+5-3
Original file line numberDiff line numberDiff line change
@@ -639,12 +639,14 @@ createTargetMachine(const std::string targetTriple, const std::string arch,
639639
targetOptions.DataSections = true;
640640
}
641641

642-
// On Android, we depend on a custom TLS emulation scheme implemented in our
643-
// LLVM fork. LLVM 7+ enables regular emutls by default; prevent that.
642+
// On Android, enforce native ELF TLS (supported since API level 29 = Android
643+
// v10), as required by druntime. (Some older LLVM versions might default to
644+
// EmuTLS).
644645
if (triple.getEnvironment() == llvm::Triple::Android) {
645646
targetOptions.EmulatedTLS = false;
646647
#if LDC_LLVM_VER < 1700
647-
// Removed in this commit: https://github.com/llvm/llvm-project/commit/0d333bf0e3aa37e2e6ae211e3aa80631c3e01b85
648+
// Removed in this commit:
649+
// https://github.com/llvm/llvm-project/commit/0d333bf0e3aa37e2e6ae211e3aa80631c3e01b85
648650
targetOptions.ExplicitEmulatedTLS = true;
649651
#endif
650652
}

runtime/CMakeLists.txt

+1-2
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,7 @@ else()
8989
endif()
9090

9191
set(SHARED_LIBS_SUPPORTED OFF)
92-
if("${TARGET_SYSTEM}" MATCHES "Windows|Linux|FreeBSD|DragonFly|APPLE"
93-
AND (NOT "${TARGET_SYSTEM}" MATCHES "Android"))
92+
if("${TARGET_SYSTEM}" MATCHES "Windows|Linux|FreeBSD|DragonFly|APPLE")
9493
set(SHARED_LIBS_SUPPORTED ON)
9594
endif()
9695

runtime/druntime/src/core/sys/posix/dlfcn.d

+13-5
Original file line numberDiff line numberDiff line change
@@ -372,12 +372,20 @@ else version (Solaris)
372372
}
373373
else version (CRuntime_Bionic)
374374
{
375-
enum
375+
enum RTLD_LOCAL = 0;
376+
enum RTLD_LAZY = 0x00001;
377+
enum RTLD_NOLOAD = 0x00004;
378+
enum RTLD_NODELETE = 0x01000;
379+
380+
version (D_LP64)
381+
{
382+
enum RTLD_NOW = 0x00002;
383+
enum RTLD_GLOBAL = 0x00100;
384+
}
385+
else // NDK: 'LP32 is broken for historical reasons'
376386
{
377-
RTLD_NOW = 0,
378-
RTLD_LAZY = 1,
379-
RTLD_LOCAL = 0,
380-
RTLD_GLOBAL = 2
387+
enum RTLD_NOW = 0;
388+
enum RTLD_GLOBAL = 0x00002;
381389
}
382390

383391
int dladdr(const scope void*, Dl_info*);

runtime/druntime/src/rt/sections.d

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ else version (CRuntime_Microsoft)
6464
public import rt.sections_win64;
6565
}
6666
else version (CRuntime_Bionic)
67-
public import rt.sections_android;
67+
public import rt.sections_elf_shared;
6868
else version (CRuntime_UClibc)
6969
public import rt.sections_elf_shared;
7070
else

runtime/druntime/src/rt/sections_android.d

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
module rt.sections_android;
1212

13+
version (LDC) { /* implemented in rt.sections_elf_shared */ } else:
14+
1315
version (CRuntime_Bionic):
1416

1517
// debug = PRINTF;

runtime/druntime/src/rt/sections_elf_shared.d

+8
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ else version (CRuntime_Musl) enum SharedELF = true;
2424
else version (FreeBSD) enum SharedELF = true;
2525
else version (NetBSD) enum SharedELF = true;
2626
else version (DragonFlyBSD) enum SharedELF = true;
27+
else version (CRuntime_Bionic) enum SharedELF = true;
2728
else version (CRuntime_UClibc) enum SharedELF = true;
2829
else enum SharedELF = false;
2930

@@ -1171,6 +1172,8 @@ else
11711172

11721173
version (LDC)
11731174
{
1175+
version (Android) version (X86) version = Android_X86;
1176+
11741177
version (PPC)
11751178
{
11761179
extern(C) void* __tls_get_addr_opt(tls_index* ti) nothrow @nogc;
@@ -1181,6 +1184,11 @@ version (LDC)
11811184
extern(C) void* __tls_get_addr_opt(tls_index* ti) nothrow @nogc;
11821185
alias __tls_get_addr = __tls_get_addr_opt;
11831186
}
1187+
else version (Android_X86) // extra underscore
1188+
{
1189+
extern(C) void* ___tls_get_addr(tls_index* ti) nothrow @nogc;
1190+
alias __tls_get_addr = ___tls_get_addr;
1191+
}
11841192
else
11851193
extern(C) void* __tls_get_addr(tls_index* ti) nothrow @nogc;
11861194
}

0 commit comments

Comments
 (0)