mirror of
https://gitlab.kitware.com/cmake/cmake.git
synced 2026-09-25 04:09:36 +03:00
@@ -6,6 +6,7 @@
|
||||
#include <cstring>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
@@ -63,6 +64,7 @@ bool cmCTestLaunch::ParseArguments(int argc, char const* const* argv)
|
||||
{
|
||||
DoingNone,
|
||||
DoingOutput,
|
||||
DoingOutputAsFileName,
|
||||
DoingSource,
|
||||
DoingLanguage,
|
||||
DoingTargetLabels,
|
||||
@@ -87,6 +89,8 @@ bool cmCTestLaunch::ParseArguments(int argc, char const* const* argv)
|
||||
doing = DoingCommandType;
|
||||
} else if (strcmp(arg, "--output") == 0) {
|
||||
doing = DoingOutput;
|
||||
} else if (strcmp(arg, "--output-as-file-name") == 0) {
|
||||
doing = DoingOutputAsFileName;
|
||||
} else if (strcmp(arg, "--source") == 0) {
|
||||
doing = DoingSource;
|
||||
} else if (strcmp(arg, "--language") == 0) {
|
||||
@@ -112,6 +116,19 @@ bool cmCTestLaunch::ParseArguments(int argc, char const* const* argv)
|
||||
} else if (doing == DoingOutput) {
|
||||
this->Reporter.OptionOutput = arg;
|
||||
doing = DoingNone;
|
||||
} else if (doing == DoingOutputAsFileName) {
|
||||
// Read all data from the file name
|
||||
cmsys::ifstream file(arg, std::ios::in);
|
||||
if (!file) {
|
||||
std::cerr << "failed to open file '" << arg << "' for reading ("
|
||||
<< cmSystemTools::GetLastSystemError() << "):\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
this->Reporter.OptionOutput =
|
||||
std::string(std::istreambuf_iterator<char>(file),
|
||||
std::istreambuf_iterator<char>());
|
||||
doing = DoingNone;
|
||||
} else if (doing == DoingSource) {
|
||||
this->Reporter.OptionSource = arg;
|
||||
doing = DoingNone;
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#include <cmext/algorithm>
|
||||
#include <cmext/string_view>
|
||||
|
||||
#include "cmsys/FStream.hxx"
|
||||
|
||||
#include "cmCryptoHash.h"
|
||||
#include "cmCustomCommand.h"
|
||||
#include "cmCustomCommandLines.h"
|
||||
@@ -520,3 +522,24 @@ cmCustomCommandGenerator::GetUtilities() const
|
||||
{
|
||||
return this->Utilities;
|
||||
}
|
||||
|
||||
std::string cmCustomCommandGenerator::StoreContentToFile(
|
||||
std::string const& content) const
|
||||
{
|
||||
cmCryptoHash hash(cmCryptoHash::AlgoSHA256);
|
||||
|
||||
std::string fileDir =
|
||||
cmStrCat(this->LG->GetBinaryDirectory(), "/CMakeFiles/c");
|
||||
if (!cmSystemTools::MakeDirectory(fileDir)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string fileName = cmStrCat(fileDir, "/", hash.HashString(content));
|
||||
|
||||
cmsys::ofstream file(fileName.c_str(), std::ios::out);
|
||||
if (!file) {
|
||||
return "";
|
||||
}
|
||||
file.write(content.data(), content.size());
|
||||
return fileName;
|
||||
}
|
||||
|
||||
@@ -72,4 +72,6 @@ public:
|
||||
|
||||
std::string const& GetOutputConfig() const { return this->OutputConfig; }
|
||||
std::string const& GetCommandConfig() const { return this->CommandConfig; }
|
||||
|
||||
std::string StoreContentToFile(std::string const& content) const;
|
||||
};
|
||||
|
||||
@@ -716,6 +716,10 @@ std::string cmFastbuildTargetGenerator::MakeCustomLauncher(
|
||||
}
|
||||
}
|
||||
vars.Output = output.c_str();
|
||||
|
||||
std::string filePathWithOutput = ccg.StoreContentToFile(output);
|
||||
vars.FilePathWithOutput = filePathWithOutput.c_str();
|
||||
|
||||
vars.Role = ccg.GetCC().GetRole().c_str();
|
||||
vars.CMTargetName = ccg.GetCC().GetTarget().c_str();
|
||||
vars.Config = ccg.GetOutputConfig().c_str();
|
||||
|
||||
@@ -913,6 +913,10 @@ std::string cmLocalNinjaGenerator::MakeCustomLauncher(
|
||||
}
|
||||
}
|
||||
vars.Output = output.c_str();
|
||||
|
||||
std::string filePathWithOutput = ccg.StoreContentToFile(output);
|
||||
vars.FilePathWithOutput = filePathWithOutput.c_str();
|
||||
|
||||
vars.Role = ccg.GetCC().GetRole().c_str();
|
||||
vars.CMTargetName = ccg.GetCC().GetTarget().c_str();
|
||||
vars.Config = ccg.GetOutputConfig().c_str();
|
||||
|
||||
@@ -1071,6 +1071,10 @@ void cmLocalUnixMakefileGenerator3::AppendCustomCommand(
|
||||
}
|
||||
}
|
||||
vars.Output = output.c_str();
|
||||
|
||||
std::string filePathWithOutput = ccg.StoreContentToFile(output);
|
||||
vars.FilePathWithOutput = filePathWithOutput.c_str();
|
||||
|
||||
vars.Role = ccg.GetCC().GetRole().c_str();
|
||||
vars.CMTargetName = ccg.GetCC().GetTarget().c_str();
|
||||
vars.Config = ccg.GetOutputConfig().c_str();
|
||||
|
||||
@@ -304,6 +304,11 @@ std::string cmRulePlaceholderExpander::ExpandVariable(
|
||||
return this->ReplaceValues->Output;
|
||||
}
|
||||
}
|
||||
if (this->ReplaceValues->FilePathWithOutput) {
|
||||
if (variable == "OUTPUT_STORE_TO_FILE") {
|
||||
return this->ReplaceValues->FilePathWithOutput;
|
||||
}
|
||||
}
|
||||
if (variable == "CMAKE_COMMAND") {
|
||||
return this->OutputConverter->ConvertToOutputFormat(
|
||||
cmSystemTools::GetCMakeCommand(), cmOutputConverter::SHELL);
|
||||
|
||||
@@ -56,6 +56,7 @@ public:
|
||||
char const* PreprocessedSource = nullptr;
|
||||
char const* DynDepFile = nullptr;
|
||||
char const* Output = nullptr;
|
||||
char const* FilePathWithOutput = nullptr;
|
||||
char const* Object = nullptr;
|
||||
char const* TargetSupportDir = nullptr;
|
||||
char const* ObjectDir = nullptr;
|
||||
|
||||
+3
-2
@@ -2882,8 +2882,9 @@ int cmake::ActualConfigure()
|
||||
"--output <TARGET> --config <CONFIG> --language <LANGUAGE> -- "));
|
||||
this->State->SetGlobalProperty(
|
||||
"RULE_LAUNCH_CUSTOM",
|
||||
cmStrCat(launcher, "--command-type custom", common_args,
|
||||
"--output \"<OUTPUT>\" --role <ROLE> -- "));
|
||||
cmStrCat(
|
||||
launcher, "--command-type custom", common_args,
|
||||
"--output-as-file-name \"<OUTPUT_STORE_TO_FILE>\" --role <ROLE> -- "));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -617,6 +617,16 @@ instrument(cmake-command-trace
|
||||
CHECK_SCRIPT check-trace-removed.cmake
|
||||
)
|
||||
|
||||
# FIXME(#27984): FASTBuild long output test failure
|
||||
# FIXME(#279846): Watcom WMake unsupported file names
|
||||
if(NOT RunCMake_GENERATOR MATCHES "FASTBuild|Watcom WMake")
|
||||
instrument(cmake-command-long-output
|
||||
BUILD
|
||||
CONFIGURE_ARGS "-DLONG_CUSTOM_COMMAND_OUTPUT=ON"
|
||||
CHECK_SCRIPT check-long-output.cmake
|
||||
)
|
||||
endif()
|
||||
|
||||
# Test capture output
|
||||
instrument(cmake-command-capture-output
|
||||
BUILD CAPTURE_OUTPUT_QUERY
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/json.cmake)
|
||||
|
||||
if(NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/Destination-Modules/check-done.txt")
|
||||
string(APPEND RunCMake_TEST_FAILED
|
||||
"long custom command with instrumentation did not run (Destination-Modules missing)\n")
|
||||
endif()
|
||||
|
||||
# Reconstruct expected outputs as in project/CMakeLists.txt
|
||||
file(GLOB_RECURSE input_files
|
||||
RELATIVE "${CMAKE_ROOT}"
|
||||
"${CMAKE_ROOT}/Modules/*")
|
||||
set(expected_outs)
|
||||
foreach(f IN LISTS input_files)
|
||||
list(APPEND expected_outs "Destination-${f}")
|
||||
endforeach()
|
||||
list(LENGTH expected_outs expected_count)
|
||||
list(SORT expected_outs)
|
||||
|
||||
# Find the custom snippet for the long-output command and verify its outputs
|
||||
file(GLOB snippets LIST_DIRECTORIES false "${v1}/data/custom-*")
|
||||
set(found_long_snippet 0)
|
||||
foreach(snippet IN LISTS snippets)
|
||||
read_json("${snippet}" contents)
|
||||
string(JSON outputs ERROR_VARIABLE noOutputs GET "${contents}" outputs)
|
||||
if(NOT outputs MATCHES "Destination-")
|
||||
continue()
|
||||
endif()
|
||||
set(found_long_snippet 1)
|
||||
|
||||
string(JSON outputs_len LENGTH "${contents}" outputs)
|
||||
if(NOT outputs_len EQUAL expected_count)
|
||||
json_error("${snippet}"
|
||||
"Expected ${expected_count} outputs, got ${outputs_len}")
|
||||
continue()
|
||||
endif()
|
||||
|
||||
set(actual_outs)
|
||||
math(EXPR last "${outputs_len} - 1")
|
||||
foreach(i RANGE ${last})
|
||||
string(JSON out GET "${contents}" outputs ${i})
|
||||
string(REPLACE "\\" "/" out "${out}")
|
||||
list(APPEND actual_outs "${out}")
|
||||
endforeach()
|
||||
list(SORT actual_outs)
|
||||
if(NOT expected_outs STREQUAL actual_outs)
|
||||
json_error("${snippet}"
|
||||
"outputs field does not match expected Destination-* list")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(NOT found_long_snippet)
|
||||
add_error("No custom snippet with Destination- outputs was found")
|
||||
endif()
|
||||
@@ -62,6 +62,26 @@ install(TARGETS main)
|
||||
set_target_properties(main PROPERTIES LABELS "label1;label2")
|
||||
set_target_properties(lib PROPERTIES LABELS "label3")
|
||||
|
||||
if(LONG_CUSTOM_COMMAND_OUTPUT)
|
||||
file(GLOB_RECURSE LONG_CUSTOM_FILES
|
||||
RELATIVE "${CMAKE_ROOT}"
|
||||
"${CMAKE_ROOT}/Modules/*")
|
||||
set(long_dst "${CMAKE_CURRENT_BINARY_DIR}/Destination-Modules")
|
||||
set(long_outs)
|
||||
foreach(f IN LISTS LONG_CUSTOM_FILES)
|
||||
# Generate outputs without spaces to correct expansion
|
||||
list(APPEND long_outs "Destination-${f}")
|
||||
endforeach()
|
||||
add_custom_command(
|
||||
OUTPUT ${long_outs}
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy_directory
|
||||
"${CMAKE_ROOT}/Modules" "${long_dst}"
|
||||
COMMAND "${CMAKE_COMMAND}" -E touch "${long_dst}/check-done.txt"
|
||||
COMMENT "Copying Modules to Destination-Modules"
|
||||
)
|
||||
add_custom_target(longCustomCommand ALL DEPENDS ${long_outs})
|
||||
endif()
|
||||
|
||||
if (FAIL)
|
||||
file(WRITE "${CMAKE_BINARY_DIR}/dummy.c"
|
||||
"#error \"something which will not compile\"\n"
|
||||
|
||||
Reference in New Issue
Block a user