Swift: Omit output-file-map when used as a linker

Swift is used as the linker for non-swift files because it needs to pull
files like swiftrt.o in when swift symbols are present to ensure that
the swift runtime is linked.

The swift driver uses clang as the underlying linker, which pulls in
crtbegin.o and friends when appropriate, so using Swift as a linker for
C/C++ libraries is fine.

The output-file-map was getting passed to all Swift invocations,
regardless of whether or not we generated one. This patch changes it so
that we only include the output-file-map in the Swift compiler
invocation if we have actually generated the file.
This commit is contained in:
Evan Wilde 2022-10-26 16:11:51 -07:00
parent bcf203226a
commit e88509d0e8
No known key found for this signature in database
8 changed files with 48 additions and 38 deletions

View File

@ -103,7 +103,7 @@ if(NOT CMAKE_Swift_NUM_THREADS MATCHES "^[0-9]+$")
endif()
if(NOT CMAKE_Swift_CREATE_SHARED_LIBRARY)
set(CMAKE_Swift_CREATE_SHARED_LIBRARY "<CMAKE_Swift_COMPILER> -output-file-map <SWIFT_OUTPUT_FILE_MAP> -j ${CMAKE_Swift_NUM_THREADS} -num-threads ${CMAKE_Swift_NUM_THREADS} -emit-library -o <TARGET> -module-name <SWIFT_MODULE_NAME> -module-link-name <SWIFT_LIBRARY_NAME> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <SONAME_FLAG> <TARGET_INSTALLNAME_DIR><TARGET_SONAME> ${CMAKE_Swift_IMPLIB_LINKER_FLAGS} <LINK_LIBRARIES>")
set(CMAKE_Swift_CREATE_SHARED_LIBRARY "<CMAKE_Swift_COMPILER> -j ${CMAKE_Swift_NUM_THREADS} -num-threads ${CMAKE_Swift_NUM_THREADS} -emit-library -o <TARGET> -module-name <SWIFT_MODULE_NAME> -module-link-name <SWIFT_LIBRARY_NAME> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <SONAME_FLAG> <TARGET_INSTALLNAME_DIR><TARGET_SONAME> ${CMAKE_Swift_IMPLIB_LINKER_FLAGS} <LINK_LIBRARIES>")
endif()
if(NOT CMAKE_Swift_CREATE_SHARED_MODULE)
@ -111,11 +111,11 @@ if(NOT CMAKE_Swift_CREATE_SHARED_MODULE)
endif()
if(NOT CMAKE_Swift_LINK_EXECUTABLE)
set(CMAKE_Swift_LINK_EXECUTABLE "<CMAKE_Swift_COMPILER> -output-file-map <SWIFT_OUTPUT_FILE_MAP> -j ${CMAKE_Swift_NUM_THREADS} -num-threads ${CMAKE_Swift_NUM_THREADS} -emit-executable -o <TARGET> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <LINK_LIBRARIES>")
set(CMAKE_Swift_LINK_EXECUTABLE "<CMAKE_Swift_COMPILER> -j ${CMAKE_Swift_NUM_THREADS} -num-threads ${CMAKE_Swift_NUM_THREADS} -emit-executable -o <TARGET> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <LINK_LIBRARIES>")
endif()
if(NOT CMAKE_Swift_CREATE_STATIC_LIBRARY)
set(CMAKE_Swift_CREATE_STATIC_LIBRARY "<CMAKE_Swift_COMPILER> -output-file-map <SWIFT_OUTPUT_FILE_MAP> -j ${CMAKE_Swift_NUM_THREADS} -num-threads ${CMAKE_Swift_NUM_THREADS} -emit-library -static -o <TARGET> -module-name <SWIFT_MODULE_NAME> -module-link-name <SWIFT_LIBRARY_NAME> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <LINK_LIBRARIES>")
set(CMAKE_Swift_CREATE_STATIC_LIBRARY "<CMAKE_Swift_COMPILER> -j ${CMAKE_Swift_NUM_THREADS} -num-threads ${CMAKE_Swift_NUM_THREADS} -emit-library -static -o <TARGET> -module-name <SWIFT_MODULE_NAME> -module-link-name <SWIFT_LIBRARY_NAME> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <LINK_LIBRARIES>")
set(CMAKE_Swift_ARCHIVE_CREATE "<CMAKE_AR> crs <TARGET> <OBJECTS>")
set(CMAKE_Swift_ARCHIVE_FINISH "")

View File

@ -372,7 +372,6 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile,
vars.SwiftLibraryName = "$SWIFT_LIBRARY_NAME";
vars.SwiftModule = "$SWIFT_MODULE";
vars.SwiftModuleName = "$SWIFT_MODULE_NAME";
vars.SwiftOutputFileMap = "$SWIFT_OUTPUT_FILE_MAP";
vars.SwiftSources = "$SWIFT_SOURCES";
vars.Defines = "$DEFINES";
@ -1072,12 +1071,6 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
cmOutputConverter::SHELL);
}(vars["SWIFT_MODULE_NAME"]);
const std::string map = cmStrCat(gt->GetSupportDirectory(), '/', config,
'/', "output-file-map.json");
vars["SWIFT_OUTPUT_FILE_MAP"] =
this->GetLocalGenerator()->ConvertToOutputFormat(
this->ConvertToNinjaPath(map), cmOutputConverter::SHELL);
vars["SWIFT_SOURCES"] = [this, config]() -> std::string {
std::vector<cmSourceFile const*> sources;
std::stringstream oss;
@ -1101,6 +1094,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
vars["DEFINES"] = this->GetDefines("Swift", config);
vars["FLAGS"] = this->GetFlags("Swift", config);
vars["INCLUDES"] = this->GetIncludes("Swift", config);
this->GenerateSwiftOutputFileMap(config, vars["FLAGS"]);
}
// Compute specific libraries to link with.

View File

@ -1177,30 +1177,42 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements(
}
this->GetImplFileStream(fileConfig) << "\n";
}
if (!this->Configs[config].SwiftOutputMap.empty()) {
std::string const mapFilePath =
cmStrCat(this->GeneratorTarget->GetSupportDirectory(), '/', config, '/',
"output-file-map.json");
std::string const targetSwiftDepsPath = [this, config]() -> std::string {
cmGeneratorTarget const* target = this->GeneratorTarget;
if (cmValue name = target->GetProperty("Swift_DEPENDENCIES_FILE")) {
return *name;
}
return this->ConvertToNinjaPath(
cmStrCat(target->GetSupportDirectory(), '/', config, '/',
target->GetName(), ".swiftdeps"));
}();
// build the global target dependencies
// https://github.com/apple/swift/blob/master/docs/Driver.md#output-file-maps
Json::Value deps(Json::objectValue);
deps["swift-dependencies"] = targetSwiftDepsPath;
this->Configs[config].SwiftOutputMap[""] = deps;
cmGeneratedFileStream output(mapFilePath);
output << this->Configs[config].SwiftOutputMap;
void cmNinjaTargetGenerator::GenerateSwiftOutputFileMap(
const std::string& config, std::string& flags)
{
if (this->Configs[config].SwiftOutputMap.empty()) {
return;
}
std::string const targetSwiftDepsPath = [this, config]() -> std::string {
cmGeneratorTarget const* target = this->GeneratorTarget;
if (cmValue name = target->GetProperty("Swift_DEPENDENCIES_FILE")) {
return *name;
}
return this->ConvertToNinjaPath(cmStrCat(target->GetSupportDirectory(),
'/', config, '/',
target->GetName(), ".swiftdeps"));
}();
std::string mapFilePath =
cmStrCat(this->GeneratorTarget->GetSupportDirectory(), '/', config, '/',
"output-file-map.json");
// build the global target dependencies
// https://github.com/apple/swift/blob/master/docs/Driver.md#output-file-maps
Json::Value deps(Json::objectValue);
deps["swift-dependencies"] = targetSwiftDepsPath;
this->Configs[config].SwiftOutputMap[""] = deps;
cmGeneratedFileStream output(mapFilePath);
output << this->Configs[config].SwiftOutputMap;
// Add flag
this->LocalGenerator->AppendFlags(flags, "-output-file-map");
this->LocalGenerator->AppendFlagEscape(flags,
ConvertToNinjaPath(mapFilePath));
}
namespace {

View File

@ -163,6 +163,9 @@ protected:
void EmitSwiftDependencyInfo(cmSourceFile const* source,
const std::string& config);
void GenerateSwiftOutputFileMap(const std::string& config,
std::string& flags);
void ExportObjectCompileCommand(
std::string const& language, std::string const& sourceFileName,
std::string const& objectDir, std::string const& objectFileName,

View File

@ -119,11 +119,6 @@ std::string cmRulePlaceholderExpander::ExpandVariable(
return this->ReplaceValues->SwiftModuleName;
}
}
if (this->ReplaceValues->SwiftOutputFileMap) {
if (variable == "SWIFT_OUTPUT_FILE_MAP") {
return this->ReplaceValues->SwiftOutputFileMap;
}
}
if (this->ReplaceValues->SwiftSources) {
if (variable == "SWIFT_SOURCES") {
return this->ReplaceValues->SwiftSources;

View File

@ -64,7 +64,7 @@ public:
const char* SwiftLibraryName = nullptr;
const char* SwiftModule = nullptr;
const char* SwiftModuleName = nullptr;
const char* SwiftOutputFileMap = nullptr;
const char* SwiftOutputFileMapOption = nullptr;
const char* SwiftSources = nullptr;
const char* ISPCHeader = nullptr;
const char* CudaCompileMode = nullptr;

View File

@ -4,3 +4,6 @@ project(SwiftMixLib C CXX Swift)
add_library(SwiftMixedLib lib.c lib.cpp lib.swift)
add_executable(Swifty main.swift)
target_link_libraries(Swifty PUBLIC SwiftMixedLib)
add_executable(c_main main.c)
target_link_libraries(c_main PUBLIC SwiftMixedLib)

3
Tests/SwiftMixLib/main.c Normal file
View File

@ -0,0 +1,3 @@
int main(int argc, char* argv[])
{
}