mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-04 12:49:36 -06:00
Swift: Support module libraries with command-line build systems
Wire up the flags needed to support module libraries built and used with Swift. We need to pass `-bundle` to the linker when linking module libraries on Darwin, and we need to pass `-export-dynamic` to the linker when emitting an executable that exports symbols on Linux. This patch wires up `CMAKE_SHARED_MODULE_CREATE_Swift_FLAGS` and `CMAKE_SHARED_MODULE_LOADER_Swift_FLAG` on Darwin, and hooks up `CMAKE_EXE_EXPORTS_Swift_FLAG` on Linux in order to support passing things correctly. We can't expose `CMAKE_EXE_LINKER_FLAGS` to Swift, as it contains flags that the Swift compiler doesn't recognize, but the other language-specific variables are safe to expose.
This commit is contained in:
@@ -138,7 +138,7 @@ if(CMAKE_Swift_COMPILATION_MODE_DEFAULT)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT CMAKE_Swift_CREATE_SHARED_MODULE)
|
if(NOT CMAKE_Swift_CREATE_SHARED_MODULE)
|
||||||
set(CMAKE_Swift_CREATE_SHARED_MODULE ${CMAKE_Swift_CREATE_SHARED_LIBRARY})
|
set(CMAKE_Swift_CREATE_SHARED_MODULE "${CMAKE_Swift_CREATE_SHARED_LIBRARY} <CMAKE_SHARED_MODULE_CREATE_Swift_FLAGS>")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT CMAKE_Swift_LINK_EXECUTABLE)
|
if(NOT CMAKE_Swift_LINK_EXECUTABLE)
|
||||||
@@ -162,7 +162,7 @@ else()
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT CMAKE_Swift_CREATE_SHARED_MODULE)
|
if(NOT CMAKE_Swift_CREATE_SHARED_MODULE)
|
||||||
set(CMAKE_Swift_CREATE_SHARED_MODULE ${CMAKE_Swift_CREATE_SHARED_LIBRARY})
|
set(CMAKE_Swift_CREATE_SHARED_MODULE "${CMAKE_Swift_CREATE_SHARED_LIBRARY} <CMAKE_SHARED_MODULE_CREATE_Swift_FLAGS>")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT CMAKE_Swift_LINK_EXECUTABLE)
|
if(NOT CMAKE_Swift_LINK_EXECUTABLE)
|
||||||
|
|||||||
@@ -7,8 +7,11 @@ if("${CMAKE_GENERATOR}" STREQUAL Xcode)
|
|||||||
set(CMAKE_Swift_USING_LINKER_APPLE_CLASSIC "-fuse-ld=ld" "LINKER:-ld_classic")
|
set(CMAKE_Swift_USING_LINKER_APPLE_CLASSIC "-fuse-ld=ld" "LINKER:-ld_classic")
|
||||||
set(CMAKE_Swift_USING_LINKER_LLD "-fuse-ld=lld")
|
set(CMAKE_Swift_USING_LINKER_LLD "-fuse-ld=lld")
|
||||||
set(CMAKE_Swift_USING_LINKER_SYSTEM "-fuse-ld=ld")
|
set(CMAKE_Swift_USING_LINKER_SYSTEM "-fuse-ld=ld")
|
||||||
|
set(CMAKE_SHARED_MODULE_LOADER_Swift_FLAG "-Wl,-bundle_loader,")
|
||||||
else()
|
else()
|
||||||
set(CMAKE_Swift_USING_LINKER_APPLE_CLASSIC "-use-ld=ld" "LINKER:-ld_classic")
|
set(CMAKE_Swift_USING_LINKER_APPLE_CLASSIC "-use-ld=ld" "LINKER:-ld_classic")
|
||||||
set(CMAKE_Swift_USING_LINKER_LLD "-use-ld=lld")
|
set(CMAKE_Swift_USING_LINKER_LLD "-use-ld=lld")
|
||||||
set(CMAKE_Swift_USING_LINKER_SYSTEM "-use-ld=ld")
|
set(CMAKE_Swift_USING_LINKER_SYSTEM "-use-ld=ld")
|
||||||
|
set(CMAKE_SHARED_MODULE_LOADER_Swift_FLAG "-Xclang-linker -Wl,-bundle_loader,")
|
||||||
|
set(CMAKE_SHARED_MODULE_CREATE_Swift_FLAGS "-Xlinker -bundle")
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
set(CMAKE_EXE_EXPORTS_Swift_FLAG "-Xclang-linker -Wl,--export-dynamic")
|
||||||
|
|
||||||
# Linker Selection
|
# Linker Selection
|
||||||
# BFD is known to mislink Swift objects resulting in missing type info
|
# BFD is known to mislink Swift objects resulting in missing type info
|
||||||
set(CMAKE_Swift_USING_LINKER_SYSTEM "")
|
set(CMAKE_Swift_USING_LINKER_SYSTEM "")
|
||||||
|
|||||||
@@ -1478,7 +1478,7 @@ void cmLocalGenerator::GetTargetFlags(
|
|||||||
CM_FALLTHROUGH;
|
CM_FALLTHROUGH;
|
||||||
case cmStateEnums::SHARED_LIBRARY: {
|
case cmStateEnums::SHARED_LIBRARY: {
|
||||||
std::string sharedLibFlags;
|
std::string sharedLibFlags;
|
||||||
if (linkLanguage != "Swift") {
|
if (this->IsSplitSwiftBuild() || linkLanguage != "Swift") {
|
||||||
sharedLibFlags = cmStrCat(
|
sharedLibFlags = cmStrCat(
|
||||||
this->Makefile->GetSafeDefinition(libraryLinkVariable), ' ');
|
this->Makefile->GetSafeDefinition(libraryLinkVariable), ' ');
|
||||||
if (!configUpper.empty()) {
|
if (!configUpper.empty()) {
|
||||||
@@ -1521,6 +1521,13 @@ void cmLocalGenerator::GetTargetFlags(
|
|||||||
} break;
|
} break;
|
||||||
case cmStateEnums::EXECUTABLE: {
|
case cmStateEnums::EXECUTABLE: {
|
||||||
std::string exeFlags;
|
std::string exeFlags;
|
||||||
|
if (linkLanguage.empty()) {
|
||||||
|
cmSystemTools::Error(
|
||||||
|
"CMake can not determine linker language for target: " +
|
||||||
|
target->GetName());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (linkLanguage != "Swift") {
|
if (linkLanguage != "Swift") {
|
||||||
exeFlags = this->Makefile->GetSafeDefinition("CMAKE_EXE_LINKER_FLAGS");
|
exeFlags = this->Makefile->GetSafeDefinition("CMAKE_EXE_LINKER_FLAGS");
|
||||||
exeFlags += " ";
|
exeFlags += " ";
|
||||||
@@ -1529,28 +1536,22 @@ void cmLocalGenerator::GetTargetFlags(
|
|||||||
cmStrCat("CMAKE_EXE_LINKER_FLAGS_", configUpper));
|
cmStrCat("CMAKE_EXE_LINKER_FLAGS_", configUpper));
|
||||||
exeFlags += " ";
|
exeFlags += " ";
|
||||||
}
|
}
|
||||||
if (linkLanguage.empty()) {
|
}
|
||||||
cmSystemTools::Error(
|
|
||||||
"CMake can not determine linker language for target: " +
|
|
||||||
target->GetName());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target->IsWin32Executable(config)) {
|
if (target->IsWin32Executable(config)) {
|
||||||
exeFlags += this->Makefile->GetSafeDefinition(
|
exeFlags += this->Makefile->GetSafeDefinition(
|
||||||
cmStrCat("CMAKE_", linkLanguage, "_CREATE_WIN32_EXE"));
|
cmStrCat("CMAKE_", linkLanguage, "_CREATE_WIN32_EXE"));
|
||||||
exeFlags += " ";
|
exeFlags += " ";
|
||||||
} else {
|
} else {
|
||||||
exeFlags += this->Makefile->GetSafeDefinition(
|
exeFlags += this->Makefile->GetSafeDefinition(
|
||||||
cmStrCat("CMAKE_", linkLanguage, "_CREATE_CONSOLE_EXE"));
|
cmStrCat("CMAKE_", linkLanguage, "_CREATE_CONSOLE_EXE"));
|
||||||
exeFlags += " ";
|
exeFlags += " ";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target->IsExecutableWithExports()) {
|
if (target->IsExecutableWithExports()) {
|
||||||
exeFlags += this->Makefile->GetSafeDefinition(
|
exeFlags += this->Makefile->GetSafeDefinition(
|
||||||
cmStrCat("CMAKE_EXE_EXPORTS_", linkLanguage, "_FLAG"));
|
cmStrCat("CMAKE_EXE_EXPORTS_", linkLanguage, "_FLAG"));
|
||||||
exeFlags += " ";
|
exeFlags += " ";
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this->AddLanguageFlagsForLinking(flags, target, linkLanguage, config);
|
this->AddLanguageFlagsForLinking(flags, target, linkLanguage, config);
|
||||||
|
|||||||
@@ -54,16 +54,7 @@ endif()
|
|||||||
add_library(SwiftIface INTERFACE)
|
add_library(SwiftIface INTERFACE)
|
||||||
target_link_libraries(SwiftOnly PRIVATE SwiftIface)
|
target_link_libraries(SwiftOnly PRIVATE SwiftIface)
|
||||||
|
|
||||||
# @_alwaysEmitIntoClient ensures that the function body is inserted into the
|
add_subdirectory("SwiftPlugin")
|
||||||
# swiftmodule instead of as a symbol in the binary itself. I'm doing this to
|
|
||||||
# avoid having to link the executable. There are some flags required in order to
|
|
||||||
# link an executable into a library that I didn't see CMake emitting for Swift
|
|
||||||
# on macOS. AEIC is the easiest workaround that still tests this functionality.
|
|
||||||
# Unfortunately, AEIC was only added recently (~Swift 5.2), so we need to check
|
|
||||||
# that it is available before using it.
|
|
||||||
if(CMAKE_Swift_COMPILER_VERSION VERSION_GREATER_EQUAL 5.2)
|
|
||||||
add_subdirectory("SwiftPlugin")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
function(test_cmp0157_default mode)
|
function(test_cmp0157_default mode)
|
||||||
if(POLICY CMP0157)
|
if(POLICY CMP0157)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
add_executable(main main.swift)
|
add_executable(main main.swift)
|
||||||
set_target_properties(main PROPERTIES ENABLE_EXPORTS TRUE)
|
set_target_properties(main PROPERTIES ENABLE_EXPORTS TRUE)
|
||||||
|
|
||||||
add_library(plugin plugin.swift)
|
add_library(plugin MODULE plugin.swift)
|
||||||
target_link_libraries(plugin PRIVATE main)
|
target_link_libraries(plugin PRIVATE main)
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
@_alwaysEmitIntoClient
|
public func exported() -> Int { return 32 }
|
||||||
public func exported() -> Int { 32 }
|
|
||||||
|
|
||||||
print(exported())
|
print(exported())
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
import main
|
import main
|
||||||
|
|
||||||
public func importing() -> Int { main.exported() + 1 }
|
public func importing() -> Int { return main.exported() + 1 }
|
||||||
|
|||||||
Reference in New Issue
Block a user