mirror of
https://github.com/Kitware/CMake.git
synced 2026-11-06 05:16:58 +00:00
Ninja: Remove shell workaround from compilation database
Commit 1528113bdf (instrumentation: Prevent inherited process metrics in
chained commands, 2026-09-14) added an extra command to successfully
track process metrics for instrumentation, working around shell exec
optimizations . However, this workaround gets exported into
`compile_commands.json` when using the Ninja generator, which breaks
some tools that consume the database.
Append this no-op command only when generating the actual build files.
This commit is contained in:
1 parent
07ebd37501
commit
7690970a9c
5 files changed
+67
-6
No files matched your search
@@ -509,7 +509,7 @@ bool RuleNeedsCMD(std::string const& cmd)
|
||||
std::string cmLocalNinjaGenerator::BuildCommandLine(
|
||||
std::vector<std::string> const& cmdLines, std::string const& outputConfig,
|
||||
std::string const& commandConfig, std::string const& customStep,
|
||||
cmGeneratorTarget const* target) const
|
||||
cmGeneratorTarget const* target, CommandLineContext context) const
|
||||
{
|
||||
// If we have no commands but we need to build a command anyway, use noop.
|
||||
// This happens when building a POST_BUILD value for link targets that
|
||||
@@ -549,6 +549,7 @@ std::string cmLocalNinjaGenerator::BuildCommandLine(
|
||||
|
||||
std::ostringstream cmd;
|
||||
#ifdef _WIN32
|
||||
(void)context;
|
||||
cmGlobalNinjaGenerator const* gg = this->GetGlobalNinjaGenerator();
|
||||
bool const needCMD =
|
||||
cmdLines.size() > 1 || (customStep.empty() && RuleNeedsCMD(cmdLines[0]));
|
||||
@@ -577,12 +578,16 @@ std::string cmLocalNinjaGenerator::BuildCommandLine(
|
||||
cmd << *li;
|
||||
}
|
||||
# ifndef CMAKE_BOOTSTRAP
|
||||
if (this->GetCMakeInstance()->GetInstrumentation()->HasOption(
|
||||
if (context == CommandLineContext::Build &&
|
||||
this->GetCMakeInstance()->GetInstrumentation()->HasOption(
|
||||
cmInstrumentationQuery::Option::ProcessMetrics)) {
|
||||
// Prevent shell exec optimization from passing accumulated child resource
|
||||
// usage to the final instrumentation wrapper.
|
||||
// usage to the final instrumentation wrapper. Keep this build-only shell
|
||||
// syntax out of compile_commands.json, for compiler tooling support
|
||||
cmd << " && :";
|
||||
}
|
||||
# else
|
||||
(void)context;
|
||||
# endif
|
||||
#endif
|
||||
return cmd.str();
|
||||
|
||||
@@ -65,11 +65,18 @@ public:
|
||||
cmStateEnums::IntermediateDirKind kind =
|
||||
cmStateEnums::IntermediateDirKind::ObjectFiles) const override;
|
||||
|
||||
enum class CommandLineContext
|
||||
{
|
||||
Build,
|
||||
CompileCommands
|
||||
};
|
||||
|
||||
std::string BuildCommandLine(
|
||||
std::vector<std::string> const& cmdLines, std::string const& outputConfig,
|
||||
std::string const& commandConfig,
|
||||
std::string const& customStep = std::string(),
|
||||
cmGeneratorTarget const* target = nullptr) const;
|
||||
cmGeneratorTarget const* target = nullptr,
|
||||
CommandLineContext context = CommandLineContext::Build) const;
|
||||
|
||||
void AppendTargetOutputs(cmGeneratorTarget* target, cmNinjaDeps& outputs,
|
||||
std::string const& config);
|
||||
|
||||
@@ -2682,7 +2682,8 @@ void cmNinjaTargetGenerator::ExportObjectCompileCommand(
|
||||
}
|
||||
|
||||
std::string cmdLine = this->GetLocalGenerator()->BuildCommandLine(
|
||||
compileCmds, outputConfig, outputConfig);
|
||||
compileCmds, outputConfig, outputConfig, {}, nullptr,
|
||||
cmLocalNinjaGenerator::CommandLineContext::CompileCommands);
|
||||
|
||||
this->GetGlobalGenerator()->AddCXXCompileCommand(cmdLine, sourceFileName,
|
||||
objectFileName);
|
||||
@@ -2755,7 +2756,8 @@ void cmNinjaTargetGenerator::ExportSwiftObjectCompileCommand(
|
||||
}
|
||||
|
||||
std::string commandLine = this->GetLocalGenerator()->BuildCommandLine(
|
||||
compileCmds, outputConfig, outputConfig);
|
||||
compileCmds, outputConfig, outputConfig, {}, nullptr,
|
||||
cmLocalNinjaGenerator::CommandLineContext::CompileCommands);
|
||||
|
||||
this->GetGlobalGenerator()->AddCXXCompileCommand(
|
||||
commandLine, sourceFilename, objectFilename);
|
||||
|
||||
@@ -342,3 +342,49 @@ if (ARGS_BUILD_MAKE_PROGRAM)
|
||||
add_error("No snippet files of role \"build\" were found in ${v1}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (ARGS_PROCESS_METRICS_QUERY)
|
||||
# The process-metrics "&& :" suffix belongs only in build-tool shell commands,
|
||||
# not exported compile commands.
|
||||
set(compilation_database "${RunCMake_TEST_BINARY_DIR}/compile_commands.json")
|
||||
if (EXISTS "${compilation_database}")
|
||||
file(READ "${compilation_database}" compile_commands)
|
||||
string(JSON command_count LENGTH "${compile_commands}")
|
||||
if (command_count GREATER 0)
|
||||
math(EXPR last_command "${command_count} - 1")
|
||||
foreach(i RANGE 0 ${last_command})
|
||||
string(JSON arguments_type ERROR_VARIABLE no_arguments
|
||||
TYPE "${compile_commands}" ${i} arguments)
|
||||
if (arguments_type STREQUAL "ARRAY")
|
||||
# FASTBuild exports an argument array rather than a command string.
|
||||
set(arguments)
|
||||
string(JSON argument_count LENGTH "${compile_commands}" ${i} arguments)
|
||||
if (argument_count GREATER 0)
|
||||
math(EXPR last_argument "${argument_count} - 1")
|
||||
foreach(j RANGE 0 ${last_argument})
|
||||
string(JSON argument GET "${compile_commands}" ${i} arguments ${j})
|
||||
list(APPEND arguments "${argument}")
|
||||
endforeach()
|
||||
endif()
|
||||
else()
|
||||
string(JSON command GET "${compile_commands}" ${i} command)
|
||||
separate_arguments(arguments NATIVE_COMMAND "${command}")
|
||||
endif()
|
||||
list(LENGTH arguments argument_count)
|
||||
if (argument_count EQUAL 0)
|
||||
add_error("Compile command ${i} has no arguments")
|
||||
elseif (argument_count GREATER_EQUAL 2)
|
||||
list(GET arguments -2 penultimate_argument)
|
||||
list(GET arguments -1 last_argument)
|
||||
if (penultimate_argument STREQUAL "&&" AND last_argument STREQUAL ":")
|
||||
add_error("Compile command contains process-metrics shell suffix: ${arguments}")
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
else()
|
||||
add_error("No commands in ${compilation_database}")
|
||||
endif()
|
||||
else()
|
||||
add_error("Missing ${compilation_database}")
|
||||
endif()
|
||||
endif()
|
||||
@@ -1,4 +1,5 @@
|
||||
set_property(GLOBAL PROPERTY INSTALL_PARALLEL ON)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
cmake_instrumentation(
|
||||
API_VERSION 1
|
||||
DATA_VERSION 1.2
|
||||
|
||||
Reference in new issue
Block a user