mirror of
https://github.com/reactos/CMake.git
synced 2024-11-27 13:30:39 +00:00
Swift: Propagate Swift_MODULE_DIRECTORY as include directory
Teach include directory computation for Swift to implicitly propagate the `Swift_MODULE_DIRECTORY` of all linked targets as include directories. This is required to ensure that the swiftmodule of a linked target is accessible to the compiler of the current target. Fixes: #19272
This commit is contained in:
parent
cb8227ecbf
commit
2026915f8f
@ -1282,6 +1282,86 @@ std::string cmGeneratorTarget::EvaluateInterfaceProperty(
|
||||
}
|
||||
|
||||
namespace {
|
||||
std::string AddSwiftInterfaceIncludeDirectories(
|
||||
const cmGeneratorTarget* root, const cmGeneratorTarget* target,
|
||||
const std::string& config, cmGeneratorExpressionDAGChecker* context)
|
||||
{
|
||||
cmGeneratorExpressionDAGChecker dag{ target->GetBacktrace(), target,
|
||||
"Swift_MODULE_DIRECTORY", nullptr,
|
||||
context };
|
||||
switch (dag.Check()) {
|
||||
case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
|
||||
dag.ReportError(nullptr,
|
||||
"$<TARGET_PROPERTY:" + target->GetName() +
|
||||
",Swift_MODULE_DIRECTORY>");
|
||||
return "";
|
||||
case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE:
|
||||
// No error. We just skip cyclic references.
|
||||
return "";
|
||||
case cmGeneratorExpressionDAGChecker::ALREADY_SEEN:
|
||||
// No error. We have already seen this transitive property.
|
||||
return "";
|
||||
case cmGeneratorExpressionDAGChecker::DAG:
|
||||
break;
|
||||
}
|
||||
|
||||
std::string directories;
|
||||
if (const auto* interface =
|
||||
target->GetLinkInterfaceLibraries(config, root, true)) {
|
||||
for (const cmLinkItem& library : interface->Libraries) {
|
||||
if (const cmGeneratorTarget* dependency = library.Target) {
|
||||
if (cmContains(dependency->GetAllConfigCompileLanguages(), "Swift")) {
|
||||
std::string value =
|
||||
dependency->GetSafeProperty("Swift_MODULE_DIRECTORY");
|
||||
if (value.empty()) {
|
||||
value =
|
||||
dependency->GetLocalGenerator()->GetCurrentBinaryDirectory();
|
||||
}
|
||||
|
||||
if (!directories.empty()) {
|
||||
directories += ";";
|
||||
}
|
||||
directories += value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return directories;
|
||||
}
|
||||
|
||||
void AddSwiftImplicitIncludeDirectories(
|
||||
const cmGeneratorTarget* target, const std::string& config,
|
||||
std::vector<EvaluatedTargetPropertyEntry>& entries)
|
||||
{
|
||||
if (const auto* libraries = target->GetLinkImplementationLibraries(config)) {
|
||||
cmGeneratorExpressionDAGChecker dag{ target->GetBacktrace(), target,
|
||||
"Swift_MODULE_DIRECTORY", nullptr,
|
||||
nullptr };
|
||||
|
||||
for (const cmLinkImplItem& library : libraries->Libraries) {
|
||||
if (const cmGeneratorTarget* dependency = library.Target) {
|
||||
if (cmContains(dependency->GetAllConfigCompileLanguages(), "Swift")) {
|
||||
EvaluatedTargetPropertyEntry entry{ library, library.Backtrace };
|
||||
|
||||
if (const char* val =
|
||||
dependency->GetProperty("Swift_MODULE_DIRECTORY")) {
|
||||
entry.Values.emplace_back(val);
|
||||
} else {
|
||||
entry.Values.emplace_back(
|
||||
dependency->GetLocalGenerator()->GetCurrentBinaryDirectory());
|
||||
}
|
||||
|
||||
cmExpandList(AddSwiftInterfaceIncludeDirectories(target, dependency,
|
||||
config, &dag),
|
||||
entry.Values);
|
||||
|
||||
entries.emplace_back(std::move(entry));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AddInterfaceEntries(cmGeneratorTarget const* headTarget,
|
||||
std::string const& config, std::string const& prop,
|
||||
std::string const& lang,
|
||||
@ -3177,6 +3257,10 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories(
|
||||
EvaluateTargetPropertyEntries(this, config, lang, &dagChecker,
|
||||
this->IncludeDirectoriesEntries);
|
||||
|
||||
if (lang == "Swift") {
|
||||
AddSwiftImplicitIncludeDirectories(this, config, entries);
|
||||
}
|
||||
|
||||
AddInterfaceEntries(this, config, "INTERFACE_INCLUDE_DIRECTORIES", lang,
|
||||
&dagChecker, entries);
|
||||
|
||||
|
@ -1,4 +1,16 @@
|
||||
cmake_minimum_required(VERSION 3.3)
|
||||
|
||||
# NOTE: Force the Release mode configuration as there are some issues with the
|
||||
# debug information handling on macOS on certain Xcode builds.
|
||||
if(NOT CMAKE_CONFIGURATION_TYPES)
|
||||
set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build" FORCE)
|
||||
endif()
|
||||
|
||||
# NOTE: enable shared libraries by default. Older Xcode releases do not play
|
||||
# well with static libraries, and Windows does not currently support static
|
||||
# libraries in Swift.
|
||||
set(BUILD_SHARED_LIBS YES)
|
||||
|
||||
project(SwiftOnly Swift)
|
||||
|
||||
if(NOT XCODE_VERSION VERSION_LESS 10.2)
|
||||
@ -7,7 +19,19 @@ elseif(NOT XCODE_VERSION VERSION_LESS 8.0)
|
||||
set(CMAKE_Swift_LANGUAGE_VERSION 3.0)
|
||||
endif()
|
||||
|
||||
set(CMAKE_Swift_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/swift)
|
||||
|
||||
add_executable(SwiftOnly main.swift)
|
||||
|
||||
add_library(L L.swift)
|
||||
|
||||
add_library(M M.swift)
|
||||
target_link_libraries(M PUBLIC
|
||||
L)
|
||||
|
||||
add_library(N N.swift)
|
||||
target_link_libraries(N PUBLIC
|
||||
M)
|
||||
|
||||
# Dummy to make sure generation works with such targets.
|
||||
add_library(SwiftIface INTERFACE)
|
||||
|
1
Tests/SwiftOnly/L.swift
Normal file
1
Tests/SwiftOnly/L.swift
Normal file
@ -0,0 +1 @@
|
||||
public let ThirtyTwo: Int = 32
|
2
Tests/SwiftOnly/M.swift
Normal file
2
Tests/SwiftOnly/M.swift
Normal file
@ -0,0 +1,2 @@
|
||||
import L
|
||||
public let SixtyFour: Int = ThirtyTwo * 2
|
2
Tests/SwiftOnly/N.swift
Normal file
2
Tests/SwiftOnly/N.swift
Normal file
@ -0,0 +1,2 @@
|
||||
import M
|
||||
public let OneTwentyEight = SixtyFour * 2
|
Loading…
Reference in New Issue
Block a user