Skip to content

Commit

Permalink
[android] add an android NDK Swift overlay module, and use it instead…
Browse files Browse the repository at this point in the history
… of Glibc
  • Loading branch information
hyp committed Mar 29, 2024
1 parent fc69722 commit 89534bb
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 16 deletions.
31 changes: 19 additions & 12 deletions lib/ClangImporter/ClangIncludePaths.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ static bool shouldInjectLibcModulemap(const llvm::Triple &triple) {

static SmallVector<std::pair<std::string, std::string>, 2>
getLibcFileMapping(ASTContext &ctx, StringRef modulemapFileName,
std::optional<StringRef> maybeHeaderFileName,
std::optional<ArrayRef<StringRef>> maybeHeaderFileNames,
const llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> &vfs) {
const llvm::Triple &triple = ctx.LangOpts.Target;
if (!shouldInjectLibcModulemap(triple))
Expand Down Expand Up @@ -227,18 +227,20 @@ getLibcFileMapping(ASTContext &ctx, StringRef modulemapFileName,
SmallVector<std::pair<std::string, std::string>, 2> vfsMappings{
{std::string(injectedModuleMapPath), std::string(actualModuleMapPath)}};

if (maybeHeaderFileName) {
// TODO: remove the SwiftGlibc.h header and reference all Glibc headers
// directly from the modulemap.
Path actualHeaderPath = actualModuleMapPath;
llvm::sys::path::remove_filename(actualHeaderPath);
llvm::sys::path::append(actualHeaderPath, maybeHeaderFileName.value());
if (maybeHeaderFileNames) {
for (const auto &filename: *maybeHeaderFileNames) {
// TODO: remove the SwiftGlibc.h header and reference all Glibc headers
// directly from the modulemap.
Path actualHeaderPath = actualModuleMapPath;
llvm::sys::path::remove_filename(actualHeaderPath);
llvm::sys::path::append(actualHeaderPath, filename);

Path injectedHeaderPath(libcDir);
llvm::sys::path::append(injectedHeaderPath, maybeHeaderFileName.value());
Path injectedHeaderPath(libcDir);
llvm::sys::path::append(injectedHeaderPath, filename);

vfsMappings.push_back(
{std::string(injectedHeaderPath), std::string(actualHeaderPath)});
vfsMappings.push_back(
{std::string(injectedHeaderPath), std::string(actualHeaderPath)});
}
}

return vfsMappings;
Expand Down Expand Up @@ -534,8 +536,13 @@ ClangInvocationFileMapping swift::getClangInvocationFileMapping(
// WASI Mappings
libcFileMapping =
getLibcFileMapping(ctx, "wasi-libc.modulemap", std::nullopt, vfs);
} else if (triple.isAndroid()) {
// Android uses the android-specific module map that overlays the NDK.
StringRef headerFiles[] = { "SwiftAndroidNDK.h", "SwiftBionic.h" };
libcFileMapping = getLibcFileMapping(ctx, "android.modulemap",
headerFiles, vfs);
} else {
// Android/BSD/Linux Mappings
// BSD/Linux Mappings
libcFileMapping = getLibcFileMapping(ctx, "glibc.modulemap",
StringRef("SwiftGlibc.h"), vfs);
}
Expand Down
7 changes: 6 additions & 1 deletion stdlib/cmake/modules/AddSwiftStdlib.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -1833,6 +1833,7 @@ function(add_swift_target_library name)
SWIFT_COMPILE_FLAGS_WATCHOS
SWIFT_COMPILE_FLAGS_LINUX
SWIFT_MODULE_DEPENDS
SWIFT_MODULE_DEPENDS_ANDROID
SWIFT_MODULE_DEPENDS_CYGWIN
SWIFT_MODULE_DEPENDS_FREEBSD
SWIFT_MODULE_DEPENDS_FREESTANDING
Expand Down Expand Up @@ -2024,9 +2025,12 @@ function(add_swift_target_library name)
elseif(sdk STREQUAL "OPENBSD")
list(APPEND swiftlib_module_depends_flattened
${SWIFTLIB_SWIFT_MODULE_DEPENDS_OPENBSD})
elseif(sdk STREQUAL "LINUX" OR sdk STREQUAL "ANDROID")
elseif(sdk STREQUAL "LINUX")
list(APPEND swiftlib_module_depends_flattened
${SWIFTLIB_SWIFT_MODULE_DEPENDS_LINUX})
elseif(sdk STREQUAL "ANDROID")
list(APPEND swiftlib_module_depends_flattened
${SWIFTLIB_SWIFT_MODULE_DEPENDS_ANDROID})
elseif(sdk STREQUAL "CYGWIN")
list(APPEND swiftlib_module_depends_flattened
${SWIFTLIB_SWIFT_MODULE_DEPENDS_CYGWIN})
Expand Down Expand Up @@ -2819,6 +2823,7 @@ function(add_swift_target_executable name)
DEPENDS
LINK_LIBRARIES
SWIFT_MODULE_DEPENDS
SWIFT_MODULE_DEPENDS_ANDROID
SWIFT_MODULE_DEPENDS_CYGWIN
SWIFT_MODULE_DEPENDS_FREEBSD
SWIFT_MODULE_DEPENDS_FREESTANDING
Expand Down
1 change: 1 addition & 0 deletions stdlib/public/Concurrency/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ add_swift_target_library(swift_Concurrency ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} I
${SWIFT_RUNTIME_CONCURRENCY_C_SOURCES}
${SWIFT_RUNTIME_CONCURRENCY_SWIFT_SOURCES}

SWIFT_MODULE_DEPENDS_ANDROID Android
SWIFT_MODULE_DEPENDS_LINUX Glibc
SWIFT_MODULE_DEPENDS_FREEBSD Glibc
SWIFT_MODULE_DEPENDS_OPENBSD Glibc
Expand Down
88 changes: 88 additions & 0 deletions stdlib/public/Platform/Android.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

@_exported import Android // Clang module

@available(swift, deprecated: 3.0, message: "Please use 'Double.pi' or '.pi' to get the value of correct type and avoid casting.")
public let M_PI = Double.pi
@available(swift, deprecated: 3.0, message: "Please use 'Double.pi / 2' or '.pi / 2' to get the value of correct type and avoid casting.")
public let M_PI_2 = Double.pi / 2
@available(swift, deprecated: 3.0, message: "Please use 'Double.pi / 4' or '.pi / 4' to get the value of correct type and avoid casting.")
public let M_PI_4 = Double.pi / 4

@available(swift, deprecated: 3.0, message: "Please use 2.squareRoot()'.")
public let M_SQRT2 = 2.squareRoot()

@available(swift, deprecated: 3.0, message: "Please use 0.5.squareRoot()'.")
public let M_SQRT1_2 = 0.5.squareRoot()

@available(swift, deprecated: 3.0, message: "Please use 'T.radix' to get the radix of a FloatingPoint type 'T'.")
public let FLT_RADIX = Double.radix

// Where does the 1 come from? C counts the usually-implicit leading
// significand bit, but Swift does not. Neither is really right or wrong.
@available(swift, deprecated: 3.0, message: "Please use 'Float.significandBitCount + 1'.")
public let FLT_MANT_DIG = Float.significandBitCount + 1

// Where does the 1 come from? C models floating-point numbers as having a
// significand in [0.5, 1), but Swift (following IEEE 754) considers the
// significand to be in [1, 2). This rationale applies to FLT_MIN_EXP
// as well.
@available(swift, deprecated: 3.0, message: "Please use 'Float.greatestFiniteMagnitude.exponent + 1'.")
public let FLT_MAX_EXP = Float.greatestFiniteMagnitude.exponent + 1

@available(swift, deprecated: 3.0, message: "Please use 'Float.leastNormalMagnitude.exponent + 1'.")
public let FLT_MIN_EXP = Float.leastNormalMagnitude.exponent + 1

@available(swift, deprecated: 3.0, message: "Please use 'Float.greatestFiniteMagnitude' or '.greatestFiniteMagnitude'.")
public let FLT_MAX = Float.greatestFiniteMagnitude

@available(swift, deprecated: 3.0, message: "Please use 'Float.ulpOfOne' or '.ulpOfOne'.")
public let FLT_EPSILON = Float.ulpOfOne

@available(swift, deprecated: 3.0, message: "Please use 'Float.leastNormalMagnitude' or '.leastNormalMagnitude'.")
public let FLT_MIN = Float.leastNormalMagnitude

@available(swift, deprecated: 3.0, message: "Please use 'Float.leastNonzeroMagnitude' or '.leastNonzeroMagnitude'.")
public let FLT_TRUE_MIN = Float.leastNonzeroMagnitude


// Where does the 1 come from? C counts the usually-implicit leading
// significand bit, but Swift does not. Neither is really right or wrong.
@available(swift, deprecated: 3.0, message: "Please use 'Double.significandBitCount + 1'.")
public let DBL_MANT_DIG = Double.significandBitCount + 1

// Where does the 1 come from? C models floating-point numbers as having a
// significand in [0.5, 1), but Swift (following IEEE 754) considers the
// significand to be in [1, 2). This rationale applies to DBL_MIN_EXP
// as well.
@available(swift, deprecated: 3.0, message: "Please use 'Double.greatestFiniteMagnitude.exponent + 1'.")
public let DBL_MAX_EXP = Double.greatestFiniteMagnitude.exponent + 1

@available(swift, deprecated: 3.0, message: "Please use 'Double.leastNormalMagnitude.exponent + 1'.")
public let DBL_MIN_EXP = Double.leastNormalMagnitude.exponent + 1

@available(swift, deprecated: 3.0, message: "Please use 'Double.greatestFiniteMagnitude' or '.greatestFiniteMagnitude'.")
public let DBL_MAX = Double.greatestFiniteMagnitude

@available(swift, deprecated: 3.0, message: "Please use 'Double.ulpOfOne' or '.ulpOfOne'.")
public let DBL_EPSILON = Double.ulpOfOne

@available(swift, deprecated: 3.0, message: "Please use 'Double.leastNormalMagnitude' or '.leastNormalMagnitude'.")
public let DBL_MIN = Double.leastNormalMagnitude

@available(swift, deprecated: 3.0, message: "Please use 'Double.leastNonzeroMagnitude' or '.leastNonzeroMagnitude'.")
public let DBL_TRUE_MIN = Double.leastNonzeroMagnitude

public let M_LN2 = Android.M_LN2
public let M_LOG10E = Android.M_LOG10E
public let M_2_SQRTPI = Android.M_2_SQRTPI
38 changes: 36 additions & 2 deletions stdlib/public/Platform/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,9 @@ if(SWIFT_SHOULD_BUILD_EMBEDDED_STDLIB)
endforeach()
endif()

set(swiftGlibc_target_sdks ANDROID CYGWIN FREEBSD OPENBSD LINUX HAIKU)
set(swiftGlibc_target_sdks CYGWIN FREEBSD OPENBSD LINUX HAIKU)
if(SWIFT_FREESTANDING_FLAVOR STREQUAL "linux")
set(swiftGlibc_target_sdks ANDROID CYGWIN FREEBSD OPENBSD LINUX HAIKU FREESTANDING)
set(swiftGlibc_target_sdks CYGWIN FREEBSD OPENBSD LINUX HAIKU FREESTANDING)
endif()
add_swift_target_library(swiftGlibc ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
${swift_platform_sources}
Expand Down Expand Up @@ -197,6 +197,22 @@ add_swift_target_library(swiftCRT ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} IS_SDK_OVE
TARGET_SDKS WINDOWS
INSTALL_IN_COMPONENT sdk-overlay)

add_swift_target_library(swiftAndroid ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
Android.swift
${swift_platform_sources}
POSIXError.swift

GYB_SOURCES
${swift_platform_gyb_sources}

SWIFT_COMPILE_FLAGS
${SWIFT_RUNTIME_SWIFT_COMPILE_FLAGS}
${SWIFT_STANDARD_LIBRARY_SWIFT_FLAGS}
${swift_platform_compile_flags}
LINK_FLAGS "${SWIFT_RUNTIME_SWIFT_LINK_FLAGS}"
TARGET_SDKS "ANDROID"
INSTALL_IN_COMPONENT sdk-overlay)

set(glibc_modulemap_target_list)
foreach(sdk ${SWIFT_SDKS})
if(NOT "${sdk}" STREQUAL "LINUX" AND
Expand All @@ -213,6 +229,24 @@ foreach(sdk ${SWIFT_SDKS})
set(module_dir "${SWIFTLIB_DIR}/${arch_subdir}")
set(module_dir_static "${SWIFTSTATICLIB_DIR}/${arch_subdir}")

if ("${sdk}" STREQUAL "ANDROID")
swift_install_in_component(FILES
"android.modulemap"
DESTINATION "lib/swift/${arch_subdir}"
COMPONENT sdk-overlay)
swift_install_in_component(FILES
"SwiftAndroidNDK.h"
DESTINATION "lib/swift/${arch_subdir}"
COMPONENT sdk-overlay)
swift_install_in_component(FILES
"SwiftBionic.h"
DESTINATION "lib/swift/${arch_subdir}"
COMPONENT sdk-overlay)

# Do not build Glibc for Android.
continue()
endif()

set(glibc_modulemap_source "glibc.modulemap.gyb")
set(glibc_modulemap_out "${module_dir}/glibc.modulemap")
set(glibc_modulemap_out_static "${module_dir_static}/glibc.modulemap")
Expand Down
2 changes: 1 addition & 1 deletion stdlib/public/Platform/Platform.swift
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ public var S_IFIFO: Int32 { return Int32(0x1000) }
public var S_IREAD: Int32 { return Int32(0x0100) }
public var S_IWRITE: Int32 { return Int32(0x0080) }
public var S_IEXEC: Int32 { return Int32(0x0040) }
#else
#elseif !os(Android)
public var S_IFMT: mode_t { return mode_t(0o170000) }
public var S_IFIFO: mode_t { return mode_t(0o010000) }
public var S_IFCHR: mode_t { return mode_t(0o020000) }
Expand Down

0 comments on commit 89534bb

Please sign in to comment.