Swift: Expand generator expressions in Swift_MODULE_DIRECTORY

This patch makes the `Swift_MODULE_DIRECTORY` property behave more like
the other output directory properties, allowing generator expressions
and fixing the behavior with multi-config generators.

Issue: #26010
This commit is contained in:
Evan Wilde 2024-12-02 16:03:31 -08:00
parent 41cd84174a
commit e1d635e71c
No known key found for this signature in database
10 changed files with 75 additions and 25 deletions

View File

@ -11,14 +11,14 @@ placed in the build directory corresponding to the target's source directory.
If the variable :variable:`CMAKE_Swift_MODULE_DIRECTORY` is set when a target is
created its value is used to initialize this property.
.. versionadded:: 3.32
The property value may use
:manual:`generator expressions <cmake-generator-expressions(7)>`.
Multi-configuration generators (:generator:`Ninja Multi-Config`) append a
per-configuration subdirectory to the specified directory unless a generator
expression is used.
.. warning::
This property does not currently provide a way to express per-config
module directories, so use with multi-config generators is problematic:
* The :generator:`Xcode` generator does not implement the property at all.
* The :generator:`Ninja Multi-Config` generator implements this property,
but module files generated for different build configurations have the
same path, which can lead to subtle problems when building more than
one configuration.
The :generator:`Xcode` generator ignores this property.

View File

@ -0,0 +1,5 @@
swift-module-dir-genex
----------------------
* The :prop_tgt:`Swift_MODULE_DIRECTORY` target property now supports
:manual:`generator expressions <cmake-generator-expressions(7)>`.

View File

@ -6011,15 +6011,27 @@ std::string cmGeneratorTarget::GetSwiftModuleFileName() const
std::string cmGeneratorTarget::GetSwiftModuleDirectory(
std::string const& config) const
{
std::string moduleDirectory =
this->GetPropertyOrDefault("Swift_MODULE_DIRECTORY", "");
// This is like the *_OUTPUT_DIRECTORY properties except that we don't have a
// separate per-configuration target property.
//
// The property expands generator expressions. Multi-config generators append
// a per-configuration subdirectory to the specified directory unless a
// generator expression is used.
bool appendConfigDir = true;
std::string moduleDirectory;
if (cmValue value = this->GetProperty("Swift_MODULE_DIRECTORY")) {
moduleDirectory = cmGeneratorExpression::Evaluate(
*value, this->LocalGenerator, config, this);
appendConfigDir = *value == moduleDirectory;
}
if (moduleDirectory.empty()) {
moduleDirectory = this->LocalGenerator->GetCurrentBinaryDirectory();
}
if (appendConfigDir) {
this->LocalGenerator->GetGlobalGenerator()->AppendDirectoryForConfig(
"/", config, "", moduleDirectory);
}
return moduleDirectory;
}

View File

@ -11,13 +11,13 @@ set(expected_compile_commands
"directory": ".*(/Tests/RunCMake/Swift/CompileCommands-build|\\\\Tests\\\\RunCMake\\\\Swift\\\\CompileCommands-build)",
"command": ".*swiftc .* (\\")?.*(/Tests/RunCMake/Swift/E.swift|\\\\Tests\\\\RunCMake\\\\Swift\\\\E.swift)(\\")? (\\")?.*(/Tests/RunCMake/Swift/L.swift|\\\\Tests\\\\RunCMake\\\\Swift\\\\L.swift)(\\")?",
"file": ".*(/Tests/RunCMake/Swift/E.swift|\\\\Tests\\\\RunCMake\\\\Swift\\\\E.swift)",
"output": "CMakeFiles/CompileCommandLib.dir/(Debug(/|\\))?E.swift.o|CMakeFiles\\\\CompileCommandLib.dir\\\\E.swift.obj"
"output": "CMakeFiles/CompileCommandLib.dir/(Debug(/|\\))?E.swift.o|CMakeFiles\\\\CompileCommandLib.dir\\\\(Debug\\\\|Release\\\\)?E.swift.obj"
},
{
"directory": ".*(/Tests/RunCMake/Swift/CompileCommands-build|\\\\Tests\\\\RunCMake\\\\Swift\\\\CompileCommands-build)",
"command": ".*swiftc .* (\\")?.*(/Tests/RunCMake/Swift/E.swift|\\\\Tests\\\\RunCMake\\\\Swift\\\\E.swift)(\\")? (\\")?.*(/Tests/RunCMake/Swift/L.swift|\\\\Tests\\\\RunCMake\\\\Swift\\\\L.swift)(\\")?",
"file": ".*/Tests/RunCMake/Swift/L.swift",
"output": "CMakeFiles/CompileCommandLib.dir/(Debug(/|\\))?L.swift.o|CMakeFiles\\\\CompileCommandLib.dir\\\\L.swift.obj"
"output": "CMakeFiles/CompileCommandLib.dir/(Debug(/|\\))?L.swift.o|CMakeFiles\\\\CompileCommandLib.dir\\\\(Debug\\\\|Release\\\\)?L.swift.obj"
}
]$]==]
)

View File

@ -1 +1 @@
.*-implib:lib\\L.lib
.*-implib:lib\\(Debug\\|Release\\)?L.lib

View File

@ -1,13 +1,20 @@
.*swiftc(.exe)? [^
]* -parse-as-library -static -emit-module [^
]* -parse-as-library -static[^
]* -emit-module -emit-module-path (Debug/|Release/)?StaticLibrary.swiftmodule[^
]* -module-name StaticLibrary [^
]*
.*swiftc(.exe)? [^
]* -parse-as-library -emit-module [^
]* -parse-as-library[^
]* -emit-module -emit-module-path (debug|release)/modules/DynamicLibrary.swiftmodule[^
]* -module-name DynamicLibrary [^
]*
.*swiftc(.exe)? [^
]* -emit-library [^
]* -Xlinker -install_name -Xlinker @rpath/libDynamicLibrary.dylib -o ([A-Za-z]+/)?libDynamicLibrary.dylib [^
]*
.*swiftc(.exe)? [^
]* -parse-as-library[^
]* -emit-module -emit-module-path Modules/(Debug/|Release/)?DynamicLibrary2.swiftmodule[^
]* -module-name DynamicLibrary2[^
]*
.*swiftc(.exe)? -j [0-9]+ -num-threads [0-9]+ -c -module-name Executable

View File

@ -1,13 +1,20 @@
.*swiftc(.exe)? [^
]* -parse-as-library -static -emit-module [^
]* -parse-as-library -static[^
]* -emit-module -emit-module-path (Debug\\|Release\\)?StaticLibrary.swiftmodule[^
]* -module-name StaticLibrary [^
]*
.*swiftc(.exe)? [^
]* -parse-as-library -emit-module [^
]* -parse-as-library[^
]* -emit-module -emit-module-path (debug|release)\\modules\\DynamicLibrary.swiftmodule[^
]* -module-name DynamicLibrary [^
]*
.*swiftc(.exe)? [^
]* -emit-library [^
]* -Xlinker -implib:DynamicLibrary.lib +-o ([A-Za-z]+/)?DynamicLibrary.dll [^
]* -Xlinker -implib:(Debug\\|Release\\)?DynamicLibrary.lib +-o ([A-Za-z]+/)?(Debug\\|Release\\)?DynamicLibrary.dll [^
]*
.*swiftc(.exe)? [^
]* -parse-as-library[^
]* -emit-module -emit-module-path Modules\\(Debug\\|Release\\)?DynamicLibrary2.swiftmodule[^
]* -module-name DynamicLibrary2 [^
]*
.*swiftc(.exe)? -j [0-9]+ -num-threads [0-9]+ -c -module-name Executable

View File

@ -1,13 +1,20 @@
.*swiftc(.exe)? [^
]* -parse-as-library -static -emit-module [^
]* -parse-as-library -static[^
]* -emit-module -emit-module-path (Debug/|Release/)?StaticLibrary.swiftmodule[^
]* -module-name StaticLibrary [^
]*
.*swiftc(.exe)? [^
]* -parse-as-library -emit-module [^
]* -parse-as-library[^
]* -emit-module -emit-module-path (debug|release)/modules/DynamicLibrary.swiftmodule[^
]* -module-name DynamicLibrary [^
]*
.*swiftc(.exe)? [^
]* -emit-library [^
]* -Xlinker -soname -Xlinker libDynamicLibrary.so -o ([A-Za-z]+/)?libDynamicLibrary.so [^
]*
.*swiftc(.exe)? [^
]* -parse-as-library[^
]* -emit-module -emit-module-path Modules/(Debug/|Release/)?DynamicLibrary2.swiftmodule[^
]* -module-name DynamicLibrary2[^
]*
.*swiftc(.exe)? -j [0-9]+ -num-threads [0-9]+ -c -module-name Executable

View File

@ -6,8 +6,19 @@ enable_language(Swift)
add_library(StaticLibrary STATIC L.swift)
add_library(DynamicLibrary SHARED L.swift)
set_target_properties(DynamicLibrary PROPERTIES INSTALL_NAME_DIR "@rpath")
set_target_properties(DynamicLibrary
PROPERTIES
Swift_MODULE_DIRECTORY "$<IF:$<CONFIG:Release>,release/modules,debug/modules>"
INSTALL_NAME_DIR "@rpath")
add_library(DynamicLibrary2 SHARED L.swift)
set_target_properties(DynamicLibrary2
PROPERTIES
Swift_MODULE_DIRECTORY "Modules"
INSTALL_NAME_DIR "@rpath")
add_executable(Executable E.swift)
add_dependencies(DynamicLibrary2 DynamicLibrary)
add_dependencies(DynamicLibrary StaticLibrary)
add_dependencies(Executable DynamicLibrary)
add_dependencies(Executable DynamicLibrary2)

View File

@ -34,7 +34,8 @@ add_subdirectory(SubE)
add_subdirectory("Sub Space")
set(CMAKE_Swift_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/swift)
set(CMAKE_Swift_MODULE_DIRECTORY
"${CMAKE_BINARY_DIR}/modules/$<IF:$<CONFIG:Debug>,debug/,release/>swift")
add_executable(SwiftOnly main.swift)
target_compile_definitions(SwiftOnly PRIVATE SWIFTONLY)