Skip to content

Commit 728d21a

Browse files
committed
Merge pull request #1442 from SwiftAndroid/master
2 parents 0ac59a5 + 7c502b6 commit 728d21a

34 files changed

+592
-149
lines changed

CMakeLists.txt

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,20 @@ option(SWIFT_ENABLE_LTO
137137
# The following only works with the Ninja generator in CMake >= 3.0.
138138
set(SWIFT_PARALLEL_LINK_JOBS "" CACHE STRING
139139
"Define the maximum number of linker jobs for swift.")
140+
set(SWIFT_ANDROID_NDK_PATH "" CACHE STRING
141+
"Path to the directory that contains the Android NDK tools that are executable on the build machine")
142+
set(SWIFT_ANDROID_NDK_TOOLCHAIN_VERSION "" CACHE STRING
143+
"A version of the toolchain to use when building for Android. Use 4.8 for 32-bit builds, 4.9 for 64-bit builds")
144+
set(SWIFT_ANDROID_SDK_PATH "" CACHE STRING
145+
"Path to the directory that contains the Android SDK tools that will be passed to the swiftc frontend")
146+
set(SWIFT_ANDROID_ICU_UC "" CACHE STRING
147+
"Path to a directory containing libicuuc.so")
148+
set(SWIFT_ANDROID_ICU_UC_INCLUDE "" CACHE STRING
149+
"Path to a directory containing headers for libicuuc")
150+
set(SWIFT_ANDROID_ICU_I18N "" CACHE STRING
151+
"Path to a directory containing libicui18n.so")
152+
set(SWIFT_ANDROID_ICU_I18N_INCLUDE "" CACHE STRING
153+
"Path to a directory containing headers libicui18n")
140154

141155
#
142156
# User-configurable Darwin-specific options.
@@ -425,9 +439,31 @@ if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
425439

426440
# FIXME: This will not work while trying to cross-compile.
427441
if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64")
428-
configure_sdk_unix(LINUX "Linux" "linux" "linux" "x86_64" "x86_64-unknown-linux-gnu")
429442
set(SWIFT_HOST_VARIANT_ARCH "x86_64")
430443
set(SWIFT_PRIMARY_VARIANT_ARCH_default "x86_64")
444+
445+
if("${SWIFT_ANDROID_NDK_PATH}" STREQUAL "")
446+
set(swift_can_crosscompile_stdlib FALSE)
447+
else()
448+
set(swift_can_crosscompile_stdlib TRUE)
449+
endif()
450+
451+
is_sdk_requested(LINUX swift_build_linux)
452+
if(swift_build_linux)
453+
configure_sdk_unix(LINUX "Linux" "linux" "linux" "x86_64" "x86_64-unknown-linux-gnu")
454+
set(SWIFT_PRIMARY_VARIANT_SDK_default "LINUX")
455+
set(SWIFT_PRIMARY_VARIANT_ARCH_default "x86_64")
456+
endif()
457+
458+
is_sdk_requested(ANDROID swift_build_android)
459+
if(swift_build_android AND ${swift_can_crosscompile_stdlib})
460+
configure_sdk_unix(ANDROID "Android" "android" "android" "armv7" "armv7-none-linux-androideabi")
461+
set(SWIFT_SDK_ANDROID_PATH "${SWIFT_ANDROID_SDK_PATH}")
462+
463+
set(SWIFT_PRIMARY_VARIANT_SDK_default "ANDROID")
464+
set(SWIFT_PRIMARY_VARIANT_ARCH_default "armv7")
465+
endif()
466+
431467
# FIXME: This only matches ARMv6l (by far the most common variant).
432468
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv6l")
433469
configure_sdk_unix(LINUX "Linux" "linux" "linux" "armv6" "armv6-unknown-linux-gnueabihf")

cmake/modules/AddSwift.cmake

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,14 @@ function(_add_variant_c_compile_link_flags)
7373
list(APPEND result
7474
"-isysroot" "${SWIFT_SDK_${CFLAGS_SDK}_PATH}")
7575

76+
if("${CFLAGS_SDK}" STREQUAL "ANDROID")
77+
list(APPEND result
78+
"--sysroot=${SWIFT_ANDROID_SDK_PATH}"
79+
# Use the linker included in the Android NDK.
80+
"-B" "${SWIFT_ANDROID_NDK_PATH}/toolchains/arm-linux-androideabi-${SWIFT_ANDROID_NDK_TOOLCHAIN_VERSION}/prebuilt/linux-x86_64/arm-linux-androideabi/bin/")
81+
endif()
82+
83+
7684
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
7785

7886
# Check if there's a specific iOS deployment version needed for this invocation
@@ -156,6 +164,13 @@ function(_add_variant_c_compile_flags)
156164
"-fcoverage-mapping")
157165
endif()
158166

167+
if("${CFLAGS_SDK}" STREQUAL "ANDROID")
168+
list(APPEND result
169+
"-I${SWIFT_ANDROID_NDK_PATH}/sources/cxx-stl/llvm-libc++/libcxx/include"
170+
"-I${SWIFT_ANDROID_NDK_PATH}/sources/cxx-stl/llvm-libc++abi/libcxxabi/include"
171+
"-I${SWIFT_ANDROID_NDK_PATH}/sources/android/support/include")
172+
endif()
173+
159174
set("${CFLAGS_RESULT_VAR_NAME}" "${result}" PARENT_SCOPE)
160175
endfunction()
161176

@@ -224,7 +239,13 @@ function(_add_variant_link_flags)
224239
elseif("${LFLAGS_SDK}" STREQUAL "FREEBSD")
225240
list(APPEND result "-lpthread")
226241
elseif("${LFLAGS_SDK}" STREQUAL "CYGWIN")
227-
# NO extra libraries required.
242+
# No extra libraries required.
243+
elseif("${LFLAGS_SDK}" STREQUAL "ANDROID")
244+
list(APPEND result
245+
"-ldl"
246+
"-L${SWIFT_ANDROID_NDK_PATH}/toolchains/arm-linux-androideabi-${SWIFT_ANDROID_NDK_TOOLCHAIN_VERSION}/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/${SWIFT_ANDROID_NDK_TOOLCHAIN_VERSION}"
247+
"${SWIFT_ANDROID_NDK_PATH}/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libc++_shared.so"
248+
"-L${SWIFT_ANDROID_ICU_UC}" "-L${SWIFT_ANDROID_ICU_I18N}")
228249
else()
229250
list(APPEND result "-lobjc")
230251
endif()
@@ -1001,7 +1022,7 @@ function(_add_swift_library_single target name)
10011022
set_target_properties("${target}"
10021023
PROPERTIES
10031024
INSTALL_NAME_DIR "${install_name_dir}")
1004-
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
1025+
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux" AND NOT "${SWIFTLIB_SINGLE_SDK}" STREQUAL "ANDROID")
10051026
set_target_properties("${target}"
10061027
PROPERTIES
10071028
INSTALL_RPATH "$ORIGIN:/usr/lib/swift/linux")

cmake/modules/FindICU.cmake

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,12 @@ foreach(MODULE ${ICU_FIND_COMPONENTS})
2525
endif()
2626
endforeach()
2727

28+
if(NOT "${SWIFT_ANDROID_ICU_UC_INCLUDE}" STREQUAL "")
29+
set(ICU_UC_INCLUDE_DIR "${SWIFT_ANDROID_ICU_UC_INCLUDE}")
30+
endif()
31+
if(NOT "${SWIFT_ANDROID_ICU_I18N_INCLUDE}" STREQUAL "")
32+
set(ICU_I18N_INCLUDE_DIR "${SWIFT_ANDROID_ICU_I18N_INCLUDE}")
33+
endif()
34+
2835
find_package_handle_standard_args(ICU DEFAULT_MSG ${ICU_REQUIRED})
2936
mark_as_advanced(${ICU_REQUIRED})

include/swift/Basic/LangOptions.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ namespace swift {
184184
} else if (Target.isWatchOS()) {
185185
Target.getOSVersion(major, minor, revision);
186186
} else if (Target.isOSLinux() || Target.isOSFreeBSD() ||
187-
Target.isOSWindows() ||
187+
Target.isAndroid() || Target.isOSWindows() ||
188188
Target.getTriple().empty())
189189
{
190190
major = minor = revision = 0;

lib/Basic/LangOptions.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ static const StringRef SupportedConditionalCompilationOSs[] = {
3030
"iOS",
3131
"Linux",
3232
"FreeBSD",
33-
"Windows"
33+
"Windows",
34+
"Android"
3435
};
3536

3637
static const StringRef SupportedConditionalCompilationArches[] = {
@@ -105,6 +106,8 @@ std::pair<bool, bool> LangOptions::setTarget(llvm::Triple triple) {
105106
addPlatformConditionValue("os", "watchOS");
106107
else if (triple.isiOS())
107108
addPlatformConditionValue("os", "iOS");
109+
else if (triple.isAndroid())
110+
addPlatformConditionValue("os", "Android");
108111
else if (triple.isOSLinux())
109112
addPlatformConditionValue("os", "Linux");
110113
else if (triple.isOSFreeBSD())

lib/Basic/Platform.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ StringRef swift::getPlatformNameForTriple(const llvm::Triple &triple) {
8888
if (triple.isOSDarwin())
8989
return getPlatformNameForDarwin(getDarwinPlatformKind(triple));
9090

91+
if (triple.isAndroid())
92+
return "android";
93+
9194
if (triple.isOSLinux())
9295
return "linux";
9396

lib/ClangImporter/MappedTypes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ MAP_STDLIB_TYPE("u_int64_t", UnsignedInt, 64, "UInt64", false, DoNothing)
127127
// FIXME: why does this not catch va_list on x86_64?
128128
MAP_STDLIB_TYPE("va_list", VaList, 0, "CVaListPointer", false, DoNothing)
129129
MAP_STDLIB_TYPE("__gnuc_va_list", VaList, 0, "CVaListPointer", false, DoNothing)
130+
MAP_STDLIB_TYPE("__va_list", VaList, 0, "CVaListPointer", false, DoNothing)
130131

131132
// libkern/OSTypes.h types.
132133
MAP_STDLIB_TYPE("UInt", UnsignedInt, 32, "CUnsignedInt", false, DoNothing)

lib/Driver/Driver.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2031,6 +2031,12 @@ const ToolChain *Driver::getToolChain(const ArgList &Args) const {
20312031
TC = new toolchains::Darwin(*this, Target);
20322032
break;
20332033
case llvm::Triple::Linux:
2034+
if (Target.isAndroid()) {
2035+
TC = new toolchains::Android(*this, Target);
2036+
} else {
2037+
TC = new toolchains::GenericUnix(*this, Target);
2038+
}
2039+
break;
20342040
case llvm::Triple::FreeBSD:
20352041
TC = new toolchains::GenericUnix(*this, Target);
20362042
break;

lib/Driver/ToolChains.cpp

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1210,11 +1210,11 @@ std::string toolchains::GenericUnix::getDefaultLinker() const {
12101210
}
12111211
}
12121212

1213-
bool toolchains::GenericUnix::shouldProvideRPathToLinker() const {
1214-
return true;
1213+
std::string toolchains::GenericUnix::getTargetForLinker() const {
1214+
return getTriple().str();
12151215
}
12161216

1217-
bool toolchains::GenericUnix::shouldSpecifyTargetTripleToLinker() const {
1217+
bool toolchains::GenericUnix::shouldProvideRPathToLinker() const {
12181218
return true;
12191219
}
12201220

@@ -1266,9 +1266,10 @@ toolchains::GenericUnix::constructInvocation(const LinkJobAction &job,
12661266
Arguments.push_back(context.Args.MakeArgString("-fuse-ld=" + Linker));
12671267
}
12681268

1269-
// Explicitly pass the target to the linker
1270-
if (shouldSpecifyTargetTripleToLinker()) {
1271-
Arguments.push_back(context.Args.MakeArgString("--target=" + getTriple().str()));
1269+
std::string Target = getTargetForLinker();
1270+
if (!Target.empty()) {
1271+
Arguments.push_back("-target");
1272+
Arguments.push_back(context.Args.MakeArgString(Target));
12721273
}
12731274

12741275
// Add the runtime library link path, which is platform-specific and found
@@ -1340,13 +1341,29 @@ toolchains::GenericUnix::constructInvocation(const LinkJobAction &job,
13401341
return {"clang++", Arguments};
13411342
}
13421343

1344+
std::string
1345+
toolchains::Android::getTargetForLinker() const {
1346+
// Explicitly set the linker target to "androideabi", as opposed to the
1347+
// llvm::Triple representation of "armv7-none-linux-android".
1348+
// This is the only ABI we currently support for Android.
1349+
assert(
1350+
getTriple().getArch() == llvm::Triple::arm &&
1351+
getTriple().getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v7 &&
1352+
"Only armv7 targets are supported for Android");
1353+
return "armv7-none-linux-androideabi";
1354+
}
1355+
1356+
bool toolchains::Android::shouldProvideRPathToLinker() const {
1357+
return false;
1358+
}
1359+
13431360
std::string toolchains::Cygwin::getDefaultLinker() const {
13441361
// Cygwin uses the default BFD linker, even on ARM.
13451362
return "";
13461363
}
13471364

1348-
bool toolchains::Cygwin::shouldSpecifyTargetTripleToLinker() const {
1349-
return false;
1365+
std::string toolchains::Cygwin::getTargetForLinker() const {
1366+
return "";
13501367
}
13511368

13521369
std::string toolchains::Cygwin::getPreInputObjectPath(

lib/Driver/ToolChains.h

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,17 +53,17 @@ class LLVM_LIBRARY_VISIBILITY GenericUnix : public ToolChain {
5353
/// and to not provide a specific linker otherwise.
5454
virtual std::string getDefaultLinker() const;
5555

56+
/// The target to be passed to the compiler invocation. By default, this
57+
/// is the target triple, but this may be overridden to accomodate some
58+
/// platforms.
59+
virtual std::string getTargetForLinker() const;
60+
5661
/// Whether to specify a linker -rpath to the Swift runtime library path.
5762
/// -rpath is not supported on all platforms, and subclasses may override
5863
/// this method to return false on platforms that don't support it. The
5964
/// default is to return true (and so specify an -rpath).
6065
virtual bool shouldProvideRPathToLinker() const;
6166

62-
/// Whether to explicitly specify the target triple as the linker
63-
/// '--target'. This is not desirable on all platforms, and subclasses may
64-
/// override this method to return false in those cases.
65-
virtual bool shouldSpecifyTargetTripleToLinker() const;
66-
6767
/// Provides a path to an object that should be linked first. On platforms
6868
/// that use ELF binaries, an object that provides markers and sizes for
6969
/// metadata sections must be linked first. Platforms that do not need this
@@ -96,11 +96,21 @@ class LLVM_LIBRARY_VISIBILITY GenericUnix : public ToolChain {
9696
~GenericUnix() = default;
9797
};
9898

99+
class LLVM_LIBRARY_VISIBILITY Android : public GenericUnix {
100+
protected:
101+
std::string getTargetForLinker() const override;
102+
103+
bool shouldProvideRPathToLinker() const override;
104+
public:
105+
Android(const Driver &D, const llvm::Triple &Triple) : GenericUnix(D, Triple) {}
106+
~Android() = default;
107+
};
108+
99109
class LLVM_LIBRARY_VISIBILITY Cygwin : public GenericUnix {
100110
protected:
101111
std::string getDefaultLinker() const override;
102112

103-
bool shouldSpecifyTargetTripleToLinker() const override;
113+
std::string getTargetForLinker() const override;
104114

105115
std::string getPreInputObjectPath(
106116
StringRef RuntimeLibraryPath) const override;

stdlib/private/StdlibUnittest/RaceTest.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ import SwiftPrivate
4040
import SwiftPrivatePthreadExtras
4141
#if os(OSX) || os(iOS)
4242
import Darwin
43-
#elseif os(Linux) || os(FreeBSD)
43+
#elseif os(Linux) || os(FreeBSD) || os(Android)
4444
import Glibc
4545
#endif
4646

stdlib/private/StdlibUnittest/StdlibCoreExtras.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import SwiftPrivate
1414
import SwiftPrivateLibcExtras
1515
#if os(OSX) || os(iOS)
1616
import Darwin
17-
#elseif os(Linux) || os(FreeBSD)
17+
#elseif os(Linux) || os(FreeBSD) || os(Android)
1818
import Glibc
1919
#endif
2020

stdlib/private/StdlibUnittest/StdlibUnittest.swift.gyb

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import SwiftPrivateLibcExtras
1616

1717
#if os(OSX) || os(iOS) || os(watchOS) || os(tvOS)
1818
import Darwin
19-
#elseif os(Linux) || os(FreeBSD)
19+
#elseif os(Linux) || os(FreeBSD) || os(Android)
2020
import Glibc
2121
#endif
2222

@@ -1168,6 +1168,7 @@ public enum OSVersion : CustomStringConvertible {
11681168
case watchOSSimulator
11691169
case linux
11701170
case freeBSD
1171+
case android
11711172

11721173
public var description: String {
11731174
switch self {
@@ -1189,6 +1190,8 @@ public enum OSVersion : CustomStringConvertible {
11891190
return "Linux"
11901191
case freeBSD:
11911192
return "FreeBSD"
1193+
case android:
1194+
return "Android"
11921195
}
11931196
}
11941197
}
@@ -1223,6 +1226,8 @@ func _getOSVersion() -> OSVersion {
12231226
return .linux
12241227
#elseif os(FreeBSD)
12251228
return .freeBSD
1229+
#elseif os(Android)
1230+
return .android
12261231
#else
12271232
let productVersion = _stdlib_getSystemVersionPlistProperty("ProductVersion")!
12281233
let (major, minor, bugFix) = _parseDottedVersionTriple(productVersion)
@@ -1297,6 +1302,8 @@ public enum TestRunPredicate : CustomStringConvertible {
12971302

12981303
case freeBSDAny(reason: String)
12991304

1305+
case androidAny(reason: String)
1306+
13001307
case objCRuntime(/*reason:*/ String)
13011308
case nativeRuntime(/*reason:*/ String)
13021309

@@ -1374,6 +1381,9 @@ public enum TestRunPredicate : CustomStringConvertible {
13741381
case linuxAny(reason: let reason):
13751382
return "linuxAny(*, reason: \(reason))"
13761383

1384+
case androidAny(reason: let reason):
1385+
return "androidAny(*, reason: \(reason))"
1386+
13771387
case freeBSDAny(reason: let reason):
13781388
return "freeBSDAny(*, reason: \(reason))"
13791389

@@ -1618,6 +1628,14 @@ public enum TestRunPredicate : CustomStringConvertible {
16181628
return false
16191629
}
16201630

1631+
case androidAny:
1632+
switch _getRunningOSVersion() {
1633+
case .android:
1634+
return true
1635+
default:
1636+
return false
1637+
}
1638+
16211639
case freeBSDAny:
16221640
switch _getRunningOSVersion() {
16231641
case .freeBSD:

0 commit comments

Comments
 (0)