mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[Glibc] Configure modulemap for target, not host
The current Glibc CMakeLists.txt uses the host machine to determine which modulemap to use. The same modulemap can't be used for all platforms because headers are available in different locations on different platforms. Using the host machine to determine which modulemap to configure and place at a specific path in the resource dir is fine, so long as: 1. Only one Glibc is being compiled in a single CMake invocation. 2. The target machine needs the same modulemap as the host. https://github.com/apple/swift/pull/1442 violates both of these assumptions: the Glibc module for both Linux and Android is compiled at the same time, and the Android target can't use the Linux modulemap. This commit instead uses the target(s) to determine which modulemap to use. The modulemap is configured and placed in an OS- and architecture-specific directory in the resource dir. The path to that modulemap is referenced by the ClangImporter (since it is no longer at a path that is automatically discovered as an implicit modulemap).
This commit is contained in:
committed by
Brian Gesiak
parent
7318060242
commit
04e1cd5bda
@@ -295,7 +295,7 @@ getNormalInvocationArguments(std::vector<std::string> &invocationArgStrs,
|
|||||||
// Enable modules.
|
// Enable modules.
|
||||||
"-fmodules",
|
"-fmodules",
|
||||||
|
|
||||||
// Enable implicit module maps
|
// Enable implicit module maps (this option is implied by "-fmodules").
|
||||||
"-fimplicit-module-maps",
|
"-fimplicit-module-maps",
|
||||||
|
|
||||||
// Don't emit LLVM IR.
|
// Don't emit LLVM IR.
|
||||||
@@ -358,6 +358,35 @@ getNormalInvocationArguments(std::vector<std::string> &invocationArgStrs,
|
|||||||
// Just use the most feature-rich C language mode.
|
// Just use the most feature-rich C language mode.
|
||||||
"-x", "c", "-std=gnu11",
|
"-x", "c", "-std=gnu11",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// The module map used for Glibc depends on the target we're compiling for,
|
||||||
|
// and is not included in the resource directory with the other implicit
|
||||||
|
// module maps. It's at {freebsd|linux}/{arch}/glibc.modulemap.
|
||||||
|
SmallString<128> GlibcModuleMapPath;
|
||||||
|
if (!importerOpts.OverrideResourceDir.empty()) {
|
||||||
|
GlibcModuleMapPath = importerOpts.OverrideResourceDir;
|
||||||
|
} else if (!searchPathOpts.RuntimeResourcePath.empty()) {
|
||||||
|
GlibcModuleMapPath = searchPathOpts.RuntimeResourcePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Running without a resource directory is not a supported configuration.
|
||||||
|
assert(!GlibcModuleMapPath.empty());
|
||||||
|
|
||||||
|
llvm::sys::path::append(
|
||||||
|
GlibcModuleMapPath,
|
||||||
|
swift::getPlatformNameForTriple(triple), triple.getArchName(),
|
||||||
|
"glibc.modulemap");
|
||||||
|
|
||||||
|
// Only specify the module map if that file actually exists.
|
||||||
|
// It may not--for example in the case that
|
||||||
|
// `swiftc -target x86_64-unknown-linux-gnu -emit-ir` is invoked using
|
||||||
|
// a Swift compiler not built for Linux targets.
|
||||||
|
if (llvm::sys::fs::exists(GlibcModuleMapPath)) {
|
||||||
|
invocationArgStrs.push_back(
|
||||||
|
(Twine("-fmodule-map-file=") + GlibcModuleMapPath).str());
|
||||||
|
} else {
|
||||||
|
// FIXME: Emit a warning of some kind.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (triple.isOSDarwin()) {
|
if (triple.isOSDarwin()) {
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ if(SWIFT_BUILD_STDLIB)
|
|||||||
add_subdirectory(stubs)
|
add_subdirectory(stubs)
|
||||||
add_subdirectory(core)
|
add_subdirectory(core)
|
||||||
add_subdirectory(SwiftOnoneSupport)
|
add_subdirectory(SwiftOnoneSupport)
|
||||||
|
add_subdirectory(Glibc)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||||
@@ -38,7 +39,3 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
|||||||
add_subdirectory(SDK)
|
add_subdirectory(SDK)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
|
|
||||||
add_subdirectory(Glibc)
|
|
||||||
endif()
|
|
||||||
|
|||||||
@@ -3,44 +3,56 @@ set(sources
|
|||||||
Misc.c
|
Misc.c
|
||||||
)
|
)
|
||||||
|
|
||||||
set(output_dir "${SWIFTLIB_DIR}/glibc")
|
# When cross-compiling the stdlib on Unix platforms, we'll need a separate
|
||||||
|
# glibc for each target.
|
||||||
|
foreach(SDK ${SWIFT_SDKS})
|
||||||
|
foreach(arch ${SWIFT_SDK_${SDK}_ARCHITECTURES})
|
||||||
|
set(output_dir "${SWIFTLIB_DIR}/${SWIFT_SDK_${SDK}_LIB_SUBDIR}/${arch}")
|
||||||
|
|
||||||
# Set correct paths to glibc headers
|
# Determine the location of glibc based on the target.
|
||||||
set(GLIBC_INCLUDE_PATH "/usr/include")
|
set(GLIBC_INCLUDE_PATH "/usr/include")
|
||||||
if(CMAKE_LIBRARY_ARCHITECTURE)
|
set(GLIBC_ARCH_INCLUDE_PATH "${GLIBC_INCLUDE_PATH}")
|
||||||
set(GLIBC_ARCH_INCLUDE_PATH "${GLIBC_INCLUDE_PATH}/${CMAKE_LIBRARY_ARCHITECTURE}")
|
if(("${SDK}" STREQUAL "LINUX" OR "${SDK}" STREQUAL "FREEBSD") AND CMAKE_LIBRARY_ARCHITECTURE)
|
||||||
else()
|
# FIXME: Some distributions install headers in
|
||||||
set(GLIBC_ARCH_INCLUDE_PATH "${GLIBC_INCLUDE_PATH}")
|
# "/usr/include/x86_64-linux-gnu/sys/...". Here we use the host
|
||||||
endif()
|
# machine's path, regardless of the SDK target we're building for.
|
||||||
if (NOT EXISTS "${GLIBC_ARCH_INCLUDE_PATH}/sys")
|
# This will break if cross-compiling from a distro that uses the
|
||||||
message(FATAL_ERROR "Glibc headers were not found.")
|
# architecture as part of the path to a distro that does not.
|
||||||
endif()
|
set(GLIBC_ARCH_INCLUDE_PATH "${GLIBC_INCLUDE_PATH}/${CMAKE_LIBRARY_ARCHITECTURE}")
|
||||||
|
endif()
|
||||||
|
|
||||||
# Generate module.map
|
# Configure the modulemap based on the target. Each platform needs to
|
||||||
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
# reference different headers, based on what's available in their glibc.
|
||||||
configure_file(module.map.in "${CMAKE_CURRENT_BINARY_DIR}/module.map" @ONLY)
|
set(modulemap_path "${CMAKE_CURRENT_BINARY_DIR}/${SWIFT_SDK_${SDK}_LIB_SUBDIR}/${arch}/module.map")
|
||||||
endif()
|
if("${SDK}" STREQUAL "FREEBSD")
|
||||||
if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
|
configure_file(module.freebsd.map.in "${modulemap_path}" @ONLY)
|
||||||
configure_file(module.freebsd.map.in "${CMAKE_CURRENT_BINARY_DIR}/module.map" @ONLY)
|
else()
|
||||||
endif()
|
configure_file(module.map.in "${modulemap_path}" @ONLY)
|
||||||
|
endif()
|
||||||
|
|
||||||
add_custom_command_target(unused_var
|
set(VARIANT_SUFFIX "-${SWIFT_SDK_${SDK}_LIB_SUBDIR}-${arch}")
|
||||||
COMMAND
|
add_custom_command_target(unused_var
|
||||||
"${CMAKE_COMMAND}" "-E" "make_directory" "${output_dir}"
|
COMMAND
|
||||||
COMMAND
|
"${CMAKE_COMMAND}" "-E" "make_directory" "${output_dir}"
|
||||||
"${CMAKE_COMMAND}" "-E" "copy_if_different"
|
COMMAND
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/module.map"
|
"${CMAKE_COMMAND}" "-E" "copy_if_different"
|
||||||
"${output_dir}/module.map"
|
"${modulemap_path}"
|
||||||
CUSTOM_TARGET_NAME "copy_glibc_module"
|
"${output_dir}/glibc.modulemap"
|
||||||
OUTPUT "${output_dir}/module.map" "${output_dir}"
|
CUSTOM_TARGET_NAME "copy_glibc_module${VARIANT_SUFFIX}"
|
||||||
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/module.map"
|
OUTPUT "${output_dir}/glibc.modulemap" "${output_dir}"
|
||||||
COMMENT "Copying Glibc module to ${output_dir}")
|
DEPENDS "${modulemap_path}"
|
||||||
|
COMMENT "Copying Glibc module to ${output_dir}")
|
||||||
|
|
||||||
swift_install_in_component(stdlib
|
swift_install_in_component(stdlib
|
||||||
FILES "${output_dir}/module.map"
|
FILES "${output_dir}/glibc.modulemap"
|
||||||
DESTINATION "lib/swift/glibc")
|
DESTINATION "${output_dir}")
|
||||||
|
|
||||||
add_swift_library(swiftGlibc IS_SDK_OVERLAY
|
if("${SDK}" STREQUAL "LINUX" OR "${SDK}" STREQUAL "${FREEBSD}")
|
||||||
${sources}
|
add_swift_library(swiftGlibc IS_SDK_OVERLAY
|
||||||
FILE_DEPENDS copy_glibc_module "${output_dir}"
|
${sources}
|
||||||
INSTALL_IN_COMPONENT stdlib-experimental)
|
FILE_DEPENDS "copy_glibc_module${VARIANT_SUFFIX}" "${output_dir}"
|
||||||
|
TARGET_SDKS "${SDK}"
|
||||||
|
INSTALL_IN_COMPONENT stdlib-experimental)
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
endforeach()
|
||||||
|
|||||||
@@ -153,10 +153,20 @@ int modulewrap_main(ArrayRef<const char *> Args, const char *Argv0,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wrap the bitstream in an object file.
|
// Wrap the bitstream in a module object file. To use the ClangImporter to
|
||||||
|
// create the module loader, we need to properly set the runtime library path.
|
||||||
|
SearchPathOptions SearchPathOpts;
|
||||||
|
// FIXME: This logic has been duplicated from
|
||||||
|
// CompilerInvocation::setMainExecutablePath. ModuleWrapInvocation
|
||||||
|
// should share its implementation.
|
||||||
|
SmallString<128> RuntimeResourcePath(MainExecutablePath);
|
||||||
|
llvm::sys::path::remove_filename(RuntimeResourcePath); // Remove /swift
|
||||||
|
llvm::sys::path::remove_filename(RuntimeResourcePath); // Remove /bin
|
||||||
|
llvm::sys::path::append(RuntimeResourcePath, "lib", "swift");
|
||||||
|
SearchPathOpts.RuntimeResourcePath = RuntimeResourcePath.str();
|
||||||
|
|
||||||
SourceManager SrcMgr;
|
SourceManager SrcMgr;
|
||||||
LangOptions LangOpts;
|
LangOptions LangOpts;
|
||||||
SearchPathOptions SearchPathOpts;
|
|
||||||
LangOpts.Target = Invocation.getTargetTriple();
|
LangOpts.Target = Invocation.getTargetTriple();
|
||||||
ASTContext ASTCtx(LangOpts, SearchPathOpts, SrcMgr, Instance.getDiags());
|
ASTContext ASTCtx(LangOpts, SearchPathOpts, SrcMgr, Instance.getDiags());
|
||||||
ClangImporterOptions ClangImporterOpts;
|
ClangImporterOptions ClangImporterOpts;
|
||||||
|
|||||||
Reference in New Issue
Block a user