From 9689155a0513dbd2e6e747cd81f337c714a71614 Mon Sep 17 00:00:00 2001 From: Martin Duffy Date: Thu, 6 Feb 2025 12:16:24 -0500 Subject: [PATCH] instrumentation: Add Config value to snippet data --- Help/manual/cmake-instrumentation.7.rst | 7 ++++++- Source/CTest/cmCTestLaunch.cxx | 9 ++++++++- Source/CTest/cmCTestLaunchReporter.h | 1 + Source/CTest/cmCTestRunTest.cxx | 3 ++- Source/cmInstrumentation.cxx | 10 +++++++++- Source/cmInstrumentation.h | 3 ++- Source/cmMakefileExecutableTargetGenerator.cxx | 1 + Source/cmMakefileLibraryTargetGenerator.cxx | 2 +- Source/cmMakefileTargetGenerator.cxx | 2 ++ Source/cmNinjaNormalTargetGenerator.cxx | 4 ++++ Source/cmNinjaTargetGenerator.cxx | 5 +++++ Source/cmRulePlaceholderExpander.cxx | 6 ++++++ Source/cmRulePlaceholderExpander.h | 1 + Source/cmake.cxx | 4 ++-- Tests/RunCMake/Instrumentation/RunCMakeTest.cmake | 5 ++++- Tests/RunCMake/Instrumentation/check-data-dir.cmake | 8 ++++++++ Tests/RunCMake/Instrumentation/verify-snippet.cmake | 3 +++ 17 files changed, 65 insertions(+), 9 deletions(-) diff --git a/Help/manual/cmake-instrumentation.7.rst b/Help/manual/cmake-instrumentation.7.rst index c3ebc7596f..ae607ce825 100644 --- a/Help/manual/cmake-instrumentation.7.rst +++ b/Help/manual/cmake-instrumentation.7.rst @@ -263,6 +263,10 @@ and contain the following data: ``testName`` The name of the test being executed. Only included when ``role`` is ``test``. + ``config`` + The type of build, such as ``Release`` or ``Debug``. Only included when + ``role`` is ``compile``, ``link`` or ``test``. + ``dynamicSystemInformation`` Specifies the dynamic information collected about the host machine CMake is being run from. Data is collected for every snippet file @@ -294,7 +298,8 @@ Example: "language" : "C++", "outputs" : [ "CMakeFiles/main.dir/main.cxx.o" ], "outputSizes" : [ 0 ], - "source" : "/main.cxx" + "source" : "/main.cxx", + "config" : "Debug", "dynamicSystemInformation" : { "afterCPULoadAverage" : 2.3500000000000001, diff --git a/Source/CTest/cmCTestLaunch.cxx b/Source/CTest/cmCTestLaunch.cxx index 593adfb2b7..2f25de7453 100644 --- a/Source/CTest/cmCTestLaunch.cxx +++ b/Source/CTest/cmCTestLaunch.cxx @@ -70,7 +70,8 @@ bool cmCTestLaunch::ParseArguments(int argc, char const* const* argv) DoingBuildDir, DoingCurrentBuildDir, DoingCount, - DoingFilterPrefix + DoingFilterPrefix, + DoingConfig }; Doing doing = DoingNone; int arg0 = 0; @@ -100,6 +101,8 @@ bool cmCTestLaunch::ParseArguments(int argc, char const* const* argv) doing = DoingCurrentBuildDir; } else if (strcmp(arg, "--filter-prefix") == 0) { doing = DoingFilterPrefix; + } else if (strcmp(arg, "--config") == 0) { + doing = DoingConfig; } else if (doing == DoingOutput) { this->Reporter.OptionOutput = arg; doing = DoingNone; @@ -136,6 +139,9 @@ bool cmCTestLaunch::ParseArguments(int argc, char const* const* argv) } else if (doing == DoingRole) { this->Reporter.OptionRole = arg; doing = DoingNone; + } else if (doing == DoingConfig) { + this->Reporter.OptionConfig = arg; + doing = DoingNone; } } @@ -267,6 +273,7 @@ int cmCTestLaunch::Run() options["language"] = this->Reporter.OptionLanguage; options["targetType"] = this->Reporter.OptionTargetType; options["role"] = this->Reporter.OptionRole; + options["config"] = this->Reporter.OptionConfig; std::map arrayOptions; arrayOptions["outputs"] = this->Reporter.OptionOutput; arrayOptions["targetLabels"] = this->Reporter.OptionTargetLabels; diff --git a/Source/CTest/cmCTestLaunchReporter.h b/Source/CTest/cmCTestLaunchReporter.h index 31cd9f2cb6..0b9a08a608 100644 --- a/Source/CTest/cmCTestLaunchReporter.h +++ b/Source/CTest/cmCTestLaunchReporter.h @@ -42,6 +42,7 @@ public: std::string OptionFilterPrefix; std::string OptionCommandType; std::string OptionRole; + std::string OptionConfig; // The real command line appearing after launcher arguments. std::string CWD; diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx index 98fd24a015..42dc0af96f 100644 --- a/Source/CTest/cmCTestRunTest.cxx +++ b/Source/CTest/cmCTestRunTest.cxx @@ -1020,7 +1020,8 @@ void cmCTestRunTest::FinalizeTest(bool started) this->Instrumentation.InstrumentTest( this->TestProperties->Name, this->ActualCommand, this->Arguments, this->TestProcess->GetExitValue(), this->TestProcess->GetStartTime(), - this->TestProcess->GetSystemStartTime()); + this->TestProcess->GetSystemStartTime(), + this->GetCTest()->GetConfigType()); } this->MultiTestHandler.FinishTestProcess(this->TestProcess->GetRunner(), started); diff --git a/Source/cmInstrumentation.cxx b/Source/cmInstrumentation.cxx index c3f4488a03..774437dcc0 100644 --- a/Source/cmInstrumentation.cxx +++ b/Source/cmInstrumentation.cxx @@ -312,7 +312,7 @@ int cmInstrumentation::InstrumentTest( std::string const& name, std::string const& command, std::vector const& args, int64_t result, std::chrono::steady_clock::time_point steadyStart, - std::chrono::system_clock::time_point systemStart) + std::chrono::system_clock::time_point systemStart, std::string config) { // Store command info Json::Value root(this->preTestStats); @@ -323,6 +323,7 @@ int cmInstrumentation::InstrumentTest( root["testName"] = name; root["binaryDir"] = this->binaryDir; root["result"] = static_cast(result); + root["config"] = config; // Post-Command this->InsertTimingData(root, steadyStart, systemStart); @@ -417,6 +418,13 @@ int cmInstrumentation::InstrumentCommand( } } } + + // Create empty config entry if config not found + if (!root.isMember("config") && + (command_type == "compile" || command_type == "link")) { + root["config"] = ""; + } + if (arrayOptions.has_value()) { for (auto const& item : arrayOptions.value()) { if (item.first == "targetLabels" && command_type != "link") { diff --git a/Source/cmInstrumentation.h b/Source/cmInstrumentation.h index d17e99c30d..3a2f9d9ec6 100644 --- a/Source/cmInstrumentation.h +++ b/Source/cmInstrumentation.h @@ -32,7 +32,8 @@ public: int InstrumentTest(std::string const& name, std::string const& command, std::vector const& args, int64_t result, std::chrono::steady_clock::time_point steadyStart, - std::chrono::system_clock::time_point systemStart); + std::chrono::system_clock::time_point systemStart, + std::string config); void GetPreTestStats(); void LoadQueries(); bool HasQuery() const; diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index 3b3bbe4f49..85b2cfd0c0 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -554,6 +554,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) cmOutputConverter::SHELL, useWatcomQuote); vars.Target = target.c_str(); vars.TargetPDB = targetOutPathPDB.c_str(); + vars.Config = this->GetConfigName().c_str(); // Setup the target version. std::string targetVersionMajor; diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index 905a232f84..9774d12877 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -809,8 +809,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules( vars.TargetSOName = targetOutSOName.c_str(); } vars.LinkFlags = linkFlags.c_str(); - vars.Manifests = manifests.c_str(); + vars.Config = this->GetConfigName().c_str(); // Compute the directory portion of the install_name setting. std::string install_name_dir; diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 0adffc6053..ed232c8e6d 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -952,6 +952,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles( vars.ObjectFileDir = objectFileDir.c_str(); vars.Flags = flags.c_str(); vars.ISPCHeader = ispcHeaderForShell.c_str(); + vars.Config = this->GetConfigName().c_str(); std::string definesString = cmStrCat("$(", lang, "_DEFINES)"); @@ -1700,6 +1701,7 @@ void cmMakefileTargetGenerator::WriteDeviceLinkRule( vars.Object = output.c_str(); vars.Fatbinary = fatbinaryOutput.c_str(); vars.RegisterFile = registerFile.c_str(); + vars.Config = this->GetConfigName().c_str(); std::string linkFlags; this->GetDeviceLinkFlags(linkFlags, "CUDA"); diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 3c1d7e1ab0..707e4373fb 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -342,6 +342,7 @@ void cmNinjaNormalTargetGenerator::WriteNvidiaDeviceLinkRule( vars.Flags = "$FLAGS"; vars.LinkFlags = "$LINK_FLAGS"; vars.Manifests = "$MANIFESTS"; + vars.Config = "$CONFIG"; vars.LanguageCompileFlags = "$LANGUAGE_COMPILE_FLAGS"; @@ -416,6 +417,7 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkRules( std::string flags = this->GetFlags("CUDA", config); vars.Flags = flags.c_str(); + vars.Config = "$CONFIG"; std::string compileCmd = this->GetMakefile()->GetRequiredDefinition( "CMAKE_CUDA_DEVICE_LINK_COMPILE"); @@ -557,6 +559,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile, vars.Flags = "$FLAGS"; vars.LinkFlags = "$LINK_FLAGS"; vars.Manifests = "$MANIFESTS"; + vars.Config = "$CONFIG"; std::string langFlags; if (targetType != cmStateEnums::EXECUTABLE) { @@ -1313,6 +1316,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement( vars["AIX_EXPORTS"] = this->GetAIXExports(config); vars["LINK_PATH"] = frameworkPath + linkPath; + vars["CONFIG"] = config; // Compute architecture specific link flags. Yes, these go into a different // variable for executables, probably due to a mistake made when duplicating diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 59ab999b80..99ab466a0f 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -630,6 +630,7 @@ cmNinjaRule GetScanRule( scanVars.DynDepFile = "$DYNDEP_INTERMEDIATE_FILE"; scanVars.DependencyFile = rule.DepFile.c_str(); scanVars.DependencyTarget = "$out"; + scanVars.Config = vars.Config; // Scanning needs the same preprocessor settings as direct compilation would. scanVars.Source = vars.Source; @@ -695,6 +696,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(std::string const& lang, vars.ObjectFileDir = "$OBJECT_FILE_DIR"; vars.CudaCompileMode = "$CUDA_COMPILE_MODE"; vars.ISPCHeader = "$ISPC_HEADER_FILE"; + vars.Config = "$CONFIG"; cmMakefile* mf = this->GetMakefile(); @@ -1440,6 +1442,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( this->ComputeFlagsForObject(source, language, config, objectFileName); vars["DEFINES"] = this->ComputeDefines(source, language, config); vars["INCLUDES"] = this->ComputeIncludes(source, language, config); + vars["CONFIG"] = config; auto compilerLauncher = this->GetCompilerLauncher(language, config); @@ -1793,6 +1796,7 @@ void cmNinjaTargetGenerator::WriteCxxModuleBmiBuildStatement( this->ComputeFlagsForObject(source, language, config, bmiFileName); vars["DEFINES"] = this->ComputeDefines(source, language, config); vars["INCLUDES"] = this->ComputeIncludes(source, language, config); + vars["CONFIG"] = config; if (this->GetMakefile()->GetSafeDefinition( cmStrCat("CMAKE_", language, "_DEPFILE_FORMAT")) != "msvc"_s) { @@ -2035,6 +2039,7 @@ void cmNinjaTargetGenerator::WriteSwiftObjectBuildStatement( this->GetFlags(language, config)); vars["DEFINES"] = this->GetDefines(language, config); vars["INCLUDES"] = this->GetIncludes(language, config); + vars["CONFIG"] = config; // target-level object filename std::string const targetObjectFilename = this->ConvertToNinjaPath(cmStrCat( diff --git a/Source/cmRulePlaceholderExpander.cxx b/Source/cmRulePlaceholderExpander.cxx index c21f5fe5f5..9c3c1edf41 100644 --- a/Source/cmRulePlaceholderExpander.cxx +++ b/Source/cmRulePlaceholderExpander.cxx @@ -283,6 +283,12 @@ std::string cmRulePlaceholderExpander::ExpandVariable( } return ""; } + if (variable == "CONFIG") { + if (this->ReplaceValues->Config) { + return this->ReplaceValues->Config; + } + return ""; + } auto compIt = this->Compilers.find(variable); diff --git a/Source/cmRulePlaceholderExpander.h b/Source/cmRulePlaceholderExpander.h index 46d4be91d6..df382dddec 100644 --- a/Source/cmRulePlaceholderExpander.h +++ b/Source/cmRulePlaceholderExpander.h @@ -75,6 +75,7 @@ public: char const* RegisterFile = nullptr; char const* Launcher = nullptr; char const* Role = nullptr; + char const* Config = nullptr; }; // Expand rule variables in CMake of the type found in language rules diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 20551679ac..62f0d18f23 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -2690,13 +2690,13 @@ int cmake::ActualConfigure() this->State->SetGlobalProperty( "RULE_LAUNCH_COMPILE", cmStrCat( - launcher, "--command-type compile", common_args, + launcher, "--command-type compile", common_args, "--config ", "--output --source --language -- ")); this->State->SetGlobalProperty( "RULE_LAUNCH_LINK", cmStrCat( launcher, "--command-type link", common_args, - "--output --target-type ", + "--output --target-type --config ", "--language --target-labels \"\" -- ")); this->State->SetGlobalProperty( "RULE_LAUNCH_CUSTOM", diff --git a/Tests/RunCMake/Instrumentation/RunCMakeTest.cmake b/Tests/RunCMake/Instrumentation/RunCMakeTest.cmake index c270b714cd..1e86d440bb 100644 --- a/Tests/RunCMake/Instrumentation/RunCMakeTest.cmake +++ b/Tests/RunCMake/Instrumentation/RunCMakeTest.cmake @@ -52,7 +52,10 @@ function(instrument test) list(APPEND ARGS_CONFIGURE_ARG "-Wno-dev") endif() set(RunCMake_TEST_SOURCE_DIR ${RunCMake_SOURCE_DIR}/project) - run_cmake_with_options(${test} ${ARGS_CONFIGURE_ARG}) + if(NOT RunCMake_GENERATOR_IS_MULTI_CONFIG) + set(maybe_CMAKE_BUILD_TYPE -DCMAKE_BUILD_TYPE=Debug) + endif() + run_cmake_with_options(${test} ${ARGS_CONFIGURE_ARG} ${maybe_CMAKE_BUILD_TYPE}) # Follow-up Commands if (ARGS_BUILD) diff --git a/Tests/RunCMake/Instrumentation/check-data-dir.cmake b/Tests/RunCMake/Instrumentation/check-data-dir.cmake index 0c93d7aece..f2e8235b18 100644 --- a/Tests/RunCMake/Instrumentation/check-data-dir.cmake +++ b/Tests/RunCMake/Instrumentation/check-data-dir.cmake @@ -99,6 +99,14 @@ foreach(snippet IN LISTS snippets) snippet_error("${snippet}" "Unexpected testName: ${testName}") endif() endif() + + # Verify that Config is Debug + if (filename MATCHES "^test|^compile|^link") + string(JSON config GET "${contents}" config) + if (NOT config STREQUAL "Debug") + snippet_error(${snippet} "Unexpected config: ${config}") + endif() + endif() endforeach() # Verify that listed snippets match expected roles diff --git a/Tests/RunCMake/Instrumentation/verify-snippet.cmake b/Tests/RunCMake/Instrumentation/verify-snippet.cmake index dfc6332eb7..d64f686868 100644 --- a/Tests/RunCMake/Instrumentation/verify-snippet.cmake +++ b/Tests/RunCMake/Instrumentation/verify-snippet.cmake @@ -37,18 +37,21 @@ function(snippet_has_fields snippet contents) has_key("${snippet}" "${contents}" outputSizes) has_key("${snippet}" "${contents}" targetType) has_key("${snippet}" "${contents}" targetLabels) + has_key("${snippet}" "${contents}" config) elseif (filename MATCHES "^compile-*") has_key("${snippet}" "${contents}" target) has_key("${snippet}" "${contents}" outputs) has_key("${snippet}" "${contents}" outputSizes) has_key("${snippet}" "${contents}" source) has_key("${snippet}" "${contents}" language) + has_key("${snippet}" "${contents}" config) elseif (filename MATCHES "^custom-*") has_key("${snippet}" "${contents}" target) has_key("${snippet}" "${contents}" outputs) has_key("${snippet}" "${contents}" outputSizes) elseif (filename MATCHES "^test-*") has_key("${snippet}" "${contents}" testName) + has_key("${snippet}" "${contents}" config) endif() if(ARGS_DYNAMIC_QUERY) has_key("${snippet}" "${contents}" dynamicSystemInformation)