Merge pull request #1442 from SwiftAndroid/master · swiftlang/swift@728d21a

5 min read Original article ↗

34 files changed

lines changed

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")

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")

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})

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;

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())

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
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)

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;

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(

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;