mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-10 07:40:03 -06:00
Swift: Use per-config module file locations in multi-config generators
Place `.swiftmodule` files a subdirectory named after the configuration. Fixes: #25864 Fixes: #25997 - Swift/RunCMakeTest.cmake: - CMP0157-OLD was enabled for Xcode, where it works. - A test was added that verifies .swiftmodule's are generated into separate directories with multi-config generators. - Tests/SwiftOnly/CMakeLists.txt: tests were added that validate that cross-subdirectory module dependencies (via target_link_libraries) work.
This commit is contained in:
@@ -544,6 +544,12 @@ public:
|
|||||||
the given configuration. */
|
the given configuration. */
|
||||||
std::string GetSwiftModulePath(std::string const& config) const;
|
std::string GetSwiftModulePath(std::string const& config) const;
|
||||||
|
|
||||||
|
/** Return the directory containing Swift module interface
|
||||||
|
descriptions for this target (including its `.swiftmodule`,
|
||||||
|
`.abi.json`, and `.swiftdoc`) in the given configuration. */
|
||||||
|
std::string GetSwiftModuleDirectory(std::string const& config) const;
|
||||||
|
|
||||||
|
private:
|
||||||
/** Return the given property of this target if it exists; otherwise
|
/** Return the given property of this target if it exists; otherwise
|
||||||
return defaultValue. */
|
return defaultValue. */
|
||||||
std::string GetPropertyOrDefault(std::string const& property,
|
std::string GetPropertyOrDefault(std::string const& property,
|
||||||
@@ -552,12 +558,6 @@ public:
|
|||||||
/** Return the name of the `.swiftmodule` file for this target. */
|
/** Return the name of the `.swiftmodule` file for this target. */
|
||||||
std::string GetSwiftModuleFileName() const;
|
std::string GetSwiftModuleFileName() const;
|
||||||
|
|
||||||
private:
|
|
||||||
/** Return the directory containing Swift module interface
|
|
||||||
descriptions for this target (including its `.swiftmodule`,
|
|
||||||
`.abi.json`, and `.swiftdoc`) in the given configuration. */
|
|
||||||
std::string GetSwiftModuleDirectory(std::string const& config) const;
|
|
||||||
|
|
||||||
using ConfigAndLanguage = std::pair<std::string, std::string>;
|
using ConfigAndLanguage = std::pair<std::string, std::string>;
|
||||||
using ConfigAndLanguageToBTStrings =
|
using ConfigAndLanguageToBTStrings =
|
||||||
std::map<ConfigAndLanguage, std::vector<BT<std::string>>>;
|
std::map<ConfigAndLanguage, std::vector<BT<std::string>>>;
|
||||||
|
|||||||
@@ -114,7 +114,10 @@ void AddLangSpecificImplicitIncludeDirectories(
|
|||||||
auto* lg = dependency->GetLocalGenerator();
|
auto* lg = dependency->GetLocalGenerator();
|
||||||
EvaluatedTargetPropertyEntry entry{ library, library.Backtrace };
|
EvaluatedTargetPropertyEntry entry{ library, library.Backtrace };
|
||||||
|
|
||||||
if (cmValue val = dependency->GetProperty(propertyName)) {
|
if (lang == "Swift") {
|
||||||
|
entry.Values.emplace_back(
|
||||||
|
dependency->GetSwiftModuleDirectory(config));
|
||||||
|
} else if (cmValue val = dependency->GetProperty(propertyName)) {
|
||||||
entry.Values.emplace_back(*val);
|
entry.Values.emplace_back(*val);
|
||||||
} else {
|
} else {
|
||||||
if (mode == IncludeDirectoryFallBack::BINARY) {
|
if (mode == IncludeDirectoryFallBack::BINARY) {
|
||||||
|
|||||||
@@ -1078,19 +1078,6 @@ void cmNinjaNormalTargetGenerator::WriteNvidiaDeviceLinkStatement(
|
|||||||
this->WriteNvidiaDeviceLinkRule(usedResponseFile, config);
|
this->WriteNvidiaDeviceLinkRule(usedResponseFile, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compute the swift module path for the target, sans any config-specific
|
|
||||||
/// subdirectory.
|
|
||||||
/// The returned path will need to be converted to the generator path
|
|
||||||
static std::string GetSwiftModulePathTree(cmGeneratorTarget const* target)
|
|
||||||
{
|
|
||||||
std::string moduleName = target->GetSwiftModuleName();
|
|
||||||
std::string moduleDirectory = target->GetPropertyOrDefault(
|
|
||||||
"Swift_MODULE_DIRECTORY",
|
|
||||||
target->LocalGenerator->GetCurrentBinaryDirectory());
|
|
||||||
std::string moduleFileName = target->GetSwiftModuleFileName();
|
|
||||||
return moduleDirectory + "/" + moduleFileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
void cmNinjaNormalTargetGenerator::WriteLinkStatement(
|
void cmNinjaNormalTargetGenerator::WriteLinkStatement(
|
||||||
const std::string& config, const std::string& fileConfig,
|
const std::string& config, const std::string& fileConfig,
|
||||||
bool firstForConfig)
|
bool firstForConfig)
|
||||||
@@ -1205,7 +1192,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
|
|||||||
|
|
||||||
vars["SWIFT_MODULE_NAME"] = gt->GetSwiftModuleName();
|
vars["SWIFT_MODULE_NAME"] = gt->GetSwiftModuleName();
|
||||||
vars["SWIFT_MODULE"] = this->GetLocalGenerator()->ConvertToOutputFormat(
|
vars["SWIFT_MODULE"] = this->GetLocalGenerator()->ConvertToOutputFormat(
|
||||||
this->ConvertToNinjaPath(GetSwiftModulePathTree(gt)),
|
this->ConvertToNinjaPath(gt->GetSwiftModulePath(config)),
|
||||||
cmOutputConverter::SHELL);
|
cmOutputConverter::SHELL);
|
||||||
|
|
||||||
vars["SWIFT_SOURCES"] = [this, config]() -> std::string {
|
vars["SWIFT_SOURCES"] = [this, config]() -> std::string {
|
||||||
@@ -1538,7 +1525,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
|
|||||||
if (dependency.Target &&
|
if (dependency.Target &&
|
||||||
dependency.Target->GetLinkerLanguage(config) == "Swift") {
|
dependency.Target->GetLinkerLanguage(config) == "Swift") {
|
||||||
std::string swiftmodule = this->ConvertToNinjaPath(
|
std::string swiftmodule = this->ConvertToNinjaPath(
|
||||||
GetSwiftModulePathTree(dependency.Target));
|
dependency.Target->GetSwiftModulePath(config));
|
||||||
linkBuild.ImplicitDeps.emplace_back(swiftmodule);
|
linkBuild.ImplicitDeps.emplace_back(swiftmodule);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1961,15 +1961,9 @@ void cmNinjaTargetGenerator::WriteSwiftObjectBuildStatement(
|
|||||||
// changes to input files (e.g. addition of a comment).
|
// changes to input files (e.g. addition of a comment).
|
||||||
vars.emplace("restat", "1");
|
vars.emplace("restat", "1");
|
||||||
|
|
||||||
std::string const moduleName =
|
std::string const moduleName = target.GetSwiftModuleName();
|
||||||
target.GetPropertyOrDefault("Swift_MODULE_NAME", target.GetName());
|
|
||||||
std::string const moduleDirectory = target.GetPropertyOrDefault(
|
|
||||||
"Swift_MODULE_DIRECTORY",
|
|
||||||
target.LocalGenerator->GetCurrentBinaryDirectory());
|
|
||||||
std::string const moduleFilename = target.GetPropertyOrDefault(
|
|
||||||
"Swift_MODULE", cmStrCat(moduleName, ".swiftmodule"));
|
|
||||||
std::string const moduleFilepath =
|
std::string const moduleFilepath =
|
||||||
this->ConvertToNinjaPath(cmStrCat(moduleDirectory, '/', moduleFilename));
|
this->ConvertToNinjaPath(target.GetSwiftModulePath(config));
|
||||||
|
|
||||||
vars.emplace("description",
|
vars.emplace("description",
|
||||||
cmStrCat("Building Swift Module '", moduleName, "' with ",
|
cmStrCat("Building Swift Module '", moduleName, "' with ",
|
||||||
@@ -2087,15 +2081,8 @@ void cmNinjaTargetGenerator::WriteSwiftObjectBuildStatement(
|
|||||||
// If the dependency emits a swiftmodule, add a dependency edge on that
|
// If the dependency emits a swiftmodule, add a dependency edge on that
|
||||||
// swiftmodule to the ninja build graph.
|
// swiftmodule to the ninja build graph.
|
||||||
if (isImportableTarget(*dep)) {
|
if (isImportableTarget(*dep)) {
|
||||||
std::string const depModuleName =
|
std::string const depModuleFilepath =
|
||||||
dep->GetPropertyOrDefault("Swift_MODULE_NAME", dep->GetName());
|
this->ConvertToNinjaPath(dep->GetSwiftModulePath(config));
|
||||||
std::string const depModuleDir = dep->GetPropertyOrDefault(
|
|
||||||
"Swift_MODULE_DIRECTORY",
|
|
||||||
dep->LocalGenerator->GetCurrentBinaryDirectory());
|
|
||||||
std::string const depModuleFilename = dep->GetPropertyOrDefault(
|
|
||||||
"Swift_MODULE", cmStrCat(depModuleName, ".swiftmodule"));
|
|
||||||
std::string const depModuleFilepath = this->ConvertToNinjaPath(
|
|
||||||
cmStrCat(depModuleDir, '/', depModuleFilename));
|
|
||||||
objBuild.ImplicitDeps.push_back(depModuleFilepath);
|
objBuild.ImplicitDeps.push_back(depModuleFilepath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,9 +19,7 @@ block()
|
|||||||
run_cmake(CMP0157-NEW)
|
run_cmake(CMP0157-NEW)
|
||||||
run_cmake(CMP0157-WARN)
|
run_cmake(CMP0157-WARN)
|
||||||
|
|
||||||
if(RunCMake_GENERATOR MATCHES "Ninja.*")
|
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CMP0157-OLD-build)
|
||||||
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CMP0157-OLD-build)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
run_cmake(CMP0157-OLD)
|
run_cmake(CMP0157-OLD)
|
||||||
|
|
||||||
@@ -32,9 +30,25 @@ block()
|
|||||||
endif()
|
endif()
|
||||||
endblock()
|
endblock()
|
||||||
|
|
||||||
if(RunCMake_GENERATOR MATCHES "Ninja")
|
block()
|
||||||
|
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/SwiftSimple-build)
|
||||||
run_cmake(SwiftSimple)
|
run_cmake(SwiftSimple)
|
||||||
|
if(RunCMake_GENERATOR_IS_MULTI_CONFIG AND
|
||||||
|
# Older Xcode versions didn't support Swift static libraries.
|
||||||
|
NOT (RunCMake_GENERATOR STREQUAL "Xcode" AND XCODE_VERSION VERSION_LESS 9.0))
|
||||||
|
# Check that .swiftmodule files get their own directories
|
||||||
|
set(RunCMake_TEST_NO_CLEAN 1)
|
||||||
|
run_cmake_command(SwiftSimple-build-Debug ${CMAKE_COMMAND} --build . --config Debug)
|
||||||
|
run_cmake_command(SwiftSimple-build-Release ${CMAKE_COMMAND} --build . --config Release)
|
||||||
|
|
||||||
|
# Will fail if either path doesn't exist. Passing -r because Xcode
|
||||||
|
# generates .swiftmodule directories.
|
||||||
|
run_cmake_command(SwiftSimple-verify ${CMAKE_COMMAND} -E
|
||||||
|
rm -r Debug/L.swiftmodule Release/L.swiftmodule)
|
||||||
|
endif()
|
||||||
|
endblock()
|
||||||
|
|
||||||
|
if(RunCMake_GENERATOR MATCHES "Ninja")
|
||||||
block()
|
block()
|
||||||
if (CMAKE_SYSTEM_NAME MATCHES "Windows")
|
if (CMAKE_SYSTEM_NAME MATCHES "Windows")
|
||||||
run_cmake_with_options(Win32ExecutableDisallowed)
|
run_cmake_with_options(Win32ExecutableDisallowed)
|
||||||
|
|||||||
@@ -28,6 +28,10 @@ endif()
|
|||||||
add_subdirectory(SubA)
|
add_subdirectory(SubA)
|
||||||
add_subdirectory(SubB)
|
add_subdirectory(SubB)
|
||||||
|
|
||||||
|
add_subdirectory(SubC)
|
||||||
|
add_subdirectory(SubD)
|
||||||
|
add_subdirectory(SubE)
|
||||||
|
|
||||||
set(CMAKE_Swift_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/swift)
|
set(CMAKE_Swift_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/swift)
|
||||||
|
|
||||||
add_executable(SwiftOnly main.swift)
|
add_executable(SwiftOnly main.swift)
|
||||||
|
|||||||
2
Tests/SwiftOnly/SubC/CMakeLists.txt
Normal file
2
Tests/SwiftOnly/SubC/CMakeLists.txt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
add_library(SubC SubC.swift)
|
||||||
|
target_link_libraries(SubC PUBLIC SubD)
|
||||||
1
Tests/SwiftOnly/SubC/SubC.swift
Normal file
1
Tests/SwiftOnly/SubC/SubC.swift
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import SubD
|
||||||
1
Tests/SwiftOnly/SubD/CMakeLists.txt
Normal file
1
Tests/SwiftOnly/SubD/CMakeLists.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
add_library(SubD SubD.swift)
|
||||||
1
Tests/SwiftOnly/SubD/SubD.swift
Normal file
1
Tests/SwiftOnly/SubD/SubD.swift
Normal file
@@ -0,0 +1 @@
|
|||||||
|
public let x = 42
|
||||||
2
Tests/SwiftOnly/SubE/CMakeLists.txt
Normal file
2
Tests/SwiftOnly/SubE/CMakeLists.txt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
add_executable(SubE main.swift)
|
||||||
|
target_link_libraries(SubE PUBLIC SubD)
|
||||||
1
Tests/SwiftOnly/SubE/main.swift
Normal file
1
Tests/SwiftOnly/SubE/main.swift
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import SubD
|
||||||
Reference in New Issue
Block a user