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:
parent
b2e042d77a
commit
5bb7f8a4dd
@ -544,6 +544,12 @@ public:
|
||||
the given configuration. */
|
||||
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 defaultValue. */
|
||||
std::string GetPropertyOrDefault(std::string const& property,
|
||||
@ -552,12 +558,6 @@ public:
|
||||
/** Return the name of the `.swiftmodule` file for this target. */
|
||||
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 ConfigAndLanguageToBTStrings =
|
||||
std::map<ConfigAndLanguage, std::vector<BT<std::string>>>;
|
||||
|
@ -114,7 +114,10 @@ void AddLangSpecificImplicitIncludeDirectories(
|
||||
auto* lg = dependency->GetLocalGenerator();
|
||||
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);
|
||||
} else {
|
||||
if (mode == IncludeDirectoryFallBack::BINARY) {
|
||||
|
@ -1078,19 +1078,6 @@ void cmNinjaNormalTargetGenerator::WriteNvidiaDeviceLinkStatement(
|
||||
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(
|
||||
const std::string& config, const std::string& fileConfig,
|
||||
bool firstForConfig)
|
||||
@ -1205,7 +1192,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
|
||||
|
||||
vars["SWIFT_MODULE_NAME"] = gt->GetSwiftModuleName();
|
||||
vars["SWIFT_MODULE"] = this->GetLocalGenerator()->ConvertToOutputFormat(
|
||||
this->ConvertToNinjaPath(GetSwiftModulePathTree(gt)),
|
||||
this->ConvertToNinjaPath(gt->GetSwiftModulePath(config)),
|
||||
cmOutputConverter::SHELL);
|
||||
|
||||
vars["SWIFT_SOURCES"] = [this, config]() -> std::string {
|
||||
@ -1538,7 +1525,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
|
||||
if (dependency.Target &&
|
||||
dependency.Target->GetLinkerLanguage(config) == "Swift") {
|
||||
std::string swiftmodule = this->ConvertToNinjaPath(
|
||||
GetSwiftModulePathTree(dependency.Target));
|
||||
dependency.Target->GetSwiftModulePath(config));
|
||||
linkBuild.ImplicitDeps.emplace_back(swiftmodule);
|
||||
}
|
||||
}
|
||||
|
@ -1961,15 +1961,9 @@ void cmNinjaTargetGenerator::WriteSwiftObjectBuildStatement(
|
||||
// changes to input files (e.g. addition of a comment).
|
||||
vars.emplace("restat", "1");
|
||||
|
||||
std::string const moduleName =
|
||||
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 moduleName = target.GetSwiftModuleName();
|
||||
std::string const moduleFilepath =
|
||||
this->ConvertToNinjaPath(cmStrCat(moduleDirectory, '/', moduleFilename));
|
||||
this->ConvertToNinjaPath(target.GetSwiftModulePath(config));
|
||||
|
||||
vars.emplace("description",
|
||||
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
|
||||
// swiftmodule to the ninja build graph.
|
||||
if (isImportableTarget(*dep)) {
|
||||
std::string const depModuleName =
|
||||
dep->GetPropertyOrDefault("Swift_MODULE_NAME", dep->GetName());
|
||||
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));
|
||||
std::string const depModuleFilepath =
|
||||
this->ConvertToNinjaPath(dep->GetSwiftModulePath(config));
|
||||
objBuild.ImplicitDeps.push_back(depModuleFilepath);
|
||||
}
|
||||
}
|
||||
|
@ -19,9 +19,7 @@ block()
|
||||
run_cmake(CMP0157-NEW)
|
||||
run_cmake(CMP0157-WARN)
|
||||
|
||||
if(RunCMake_GENERATOR MATCHES "Ninja.*")
|
||||
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CMP0157-OLD-build)
|
||||
endif()
|
||||
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CMP0157-OLD-build)
|
||||
|
||||
run_cmake(CMP0157-OLD)
|
||||
|
||||
@ -32,9 +30,25 @@ block()
|
||||
endif()
|
||||
endblock()
|
||||
|
||||
if(RunCMake_GENERATOR MATCHES "Ninja")
|
||||
block()
|
||||
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/SwiftSimple-build)
|
||||
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()
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Windows")
|
||||
run_cmake_with_options(Win32ExecutableDisallowed)
|
||||
|
@ -28,6 +28,10 @@ endif()
|
||||
add_subdirectory(SubA)
|
||||
add_subdirectory(SubB)
|
||||
|
||||
add_subdirectory(SubC)
|
||||
add_subdirectory(SubD)
|
||||
add_subdirectory(SubE)
|
||||
|
||||
set(CMAKE_Swift_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/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
|
Loading…
Reference in New Issue
Block a user