summaryrefslogtreecommitdiffstats
path: root/Source/cmNinjaTargetGenerator.cxx
diff options
context:
space:
mode:
authorEvan Wilde <etceterawilde@gmail.com>2023-12-02 02:23:16 (GMT)
committerEvan Wilde <etceterawilde@gmail.com>2024-01-03 22:57:46 (GMT)
commit44f29a4291c9de6f8a1ff9097cd36576d987da14 (patch)
tree23b24e51924f002deb2415b68ec35e165a8edc3b /Source/cmNinjaTargetGenerator.cxx
parent9090d340b45fa5092443d1abcf959a9a35a4d0e7 (diff)
downloadCMake-44f29a4291c9de6f8a1ff9097cd36576d987da14.zip
CMake-44f29a4291c9de6f8a1ff9097cd36576d987da14.tar.gz
CMake-44f29a4291c9de6f8a1ff9097cd36576d987da14.tar.bz2
Swift/Ninja: Fix multifile module compile commands
Swift compile commands need to have all source files in the module specified in the compile command or LSP systems will report errors on missing types that are defined in other source files in the same module. Issue: #25491
Diffstat (limited to 'Source/cmNinjaTargetGenerator.cxx')
-rw-r--r--Source/cmNinjaTargetGenerator.cxx98
1 files changed, 78 insertions, 20 deletions
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 7ea479e..2ea893d 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -1916,7 +1916,6 @@ void cmNinjaTargetGenerator::WriteSwiftObjectBuildStatement(
// indistinguishable from the old behavior.
//
// FIXME(#25490): Add response file support to Swift object build step
- // FIXME(#25491): Include all files in module in compile_commands.json
if (sources.empty()) {
return;
@@ -2027,15 +2026,7 @@ void cmNinjaTargetGenerator::WriteSwiftObjectBuildStatement(
std::string const sourceFilePath = this->GetCompiledSourceNinjaPath(sf);
objBuild.ExplicitDeps.push_back(sourceFilePath);
- if (isSingleOutput) {
- if (firstForConfig) {
- this->ExportObjectCompileCommand(
- language, sourceFilePath, objectDir, targetObjectFilename,
- cmSystemTools::GetFilenamePath(targetObjectFilename), vars["FLAGS"],
- vars["DEFINES"], vars["INCLUDES"],
- /*compile pdb*/ "", /*target pdb*/ "", config, WithScanning::No);
- }
- } else {
+ if (!isSingleOutput) {
// Object outputs
std::string const objectFilepath =
this->ConvertToNinjaPath(this->GetObjectFilePath(sf, config));
@@ -2045,16 +2036,6 @@ void cmNinjaTargetGenerator::WriteSwiftObjectBuildStatement(
// Add OFM data
this->EmitSwiftDependencyInfo(sf, config);
-
- // Emit compile commands
- if (firstForConfig) {
- this->ExportObjectCompileCommand(
- language, sourceFilePath, objectDir, objectFilepath,
- cmSystemTools::GetFilenamePath(objectFilepath), vars["FLAGS"],
- vars["DEFINES"], vars["INCLUDES"],
- /*compile pdb*/ "",
- /*target pdb*/ "", config, WithScanning::No);
- }
}
}
@@ -2062,6 +2043,12 @@ void cmNinjaTargetGenerator::WriteSwiftObjectBuildStatement(
this->GenerateSwiftOutputFileMap(config, vars["FLAGS"]);
}
+ if (firstForConfig) {
+ this->ExportSwiftObjectCompileCommand(
+ sources, targetObjectFilename, vars["FLAGS"], vars["DEFINES"],
+ vars["INCLUDES"], config, isSingleOutput);
+ }
+
for (cmTargetDepend const& dep :
this->GetGlobalGenerator()->GetTargetDirectDepends(&target)) {
if (!dep->IsLanguageUsed("Swift", config)) {
@@ -2326,6 +2313,77 @@ void cmNinjaTargetGenerator::ExportObjectCompileCommand(
objectFileName);
}
+void cmNinjaTargetGenerator::ExportSwiftObjectCompileCommand(
+ std::vector<cmSourceFile const*> const& moduleSourceFiles,
+ std::string const& moduleObjectFilename, std::string const& flags,
+ std::string const& defines, std::string const& includes,
+ std::string const& outputConfig, bool singleOutput)
+{
+ if (!this->GeneratorTarget->GetPropertyAsBool("EXPORT_COMPILE_COMMANDS")) {
+ return;
+ }
+
+ auto escapeSourceFileName = [this](std::string srcFilename) -> std::string {
+ if (!cmSystemTools::FileIsFullPath(srcFilename)) {
+ srcFilename =
+ cmSystemTools::CollapseFullPath(srcFilename,
+ this->GetGlobalGenerator()
+ ->GetCMakeInstance()
+ ->GetHomeOutputDirectory());
+ }
+
+ return this->LocalGenerator->ConvertToOutputFormat(
+ srcFilename, cmOutputConverter::SHELL);
+ };
+
+ cmRulePlaceholderExpander::RuleVariables compileObjectVars;
+ compileObjectVars.Language = "Swift";
+ compileObjectVars.Flags = flags.c_str();
+ compileObjectVars.Defines = defines.c_str();
+ compileObjectVars.Includes = includes.c_str();
+
+ // Build up the list of source files in the module
+ std::vector<std::string> filenames;
+ filenames.reserve(moduleSourceFiles.size());
+ for (cmSourceFile const* sf : moduleSourceFiles) {
+ filenames.emplace_back(
+ escapeSourceFileName(this->GetCompiledSourceNinjaPath(sf)));
+ }
+ // Note that `escapedSourceFilenames` must remain alive until the
+ // compileObjectVars is consumed or Source will be a dangling pointer.
+ std::string const escapedSourceFilenames = cmJoin(filenames, " ");
+ compileObjectVars.Source = escapedSourceFilenames.c_str();
+
+ std::string const& compileCommand =
+ this->Makefile->GetRequiredDefinition("CMAKE_Swift_COMPILE_OBJECT");
+ cmList compileCmds(compileCommand);
+
+ auto rulePlaceholderExpander =
+ this->GetLocalGenerator()->CreateRulePlaceholderExpander();
+
+ for (cmSourceFile const* sf : moduleSourceFiles) {
+ std::string const sourceFilename = this->GetCompiledSourceNinjaPath(sf);
+ std::string objectFilename = moduleObjectFilename;
+
+ if (!singleOutput) {
+ // If it's not single-output, each source file gets a separate object
+ objectFilename = this->GetObjectFilePath(sf, outputConfig);
+ }
+ compileObjectVars.Objects = objectFilename.c_str();
+
+ for (std::string& cmd : compileCmds) {
+ rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(),
+ cmd, compileObjectVars);
+ }
+
+ std::string commandLine = this->GetLocalGenerator()->BuildCommandLine(
+ compileCmds, outputConfig, outputConfig);
+
+ this->GetGlobalGenerator()->AddCXXCompileCommand(
+ commandLine, sourceFilename, objectFilename);
+ }
+}
+
void cmNinjaTargetGenerator::AdditionalCleanFiles(const std::string& config)
{
if (cmValue prop_value =