straightforward, it is not trivial. In addition to the documentation, IDE
vendors may also wish to refer to the CMake source code and test cases for a
better understanding of how to implement the format.
-:download:`This file </manual/presets/schema.json>` provides a machine-readable
-JSON schema for the ``CMakePresets.json`` format that IDE vendors may find
-useful for validation and providing editing assistance.
+:download:`This file <../../manual/presets/schema.json>` provides a
+machine-readable JSON schema for the ``CMakePresets.json`` format that IDE
+vendors may find useful for validation and providing editing assistance.
Configuring
===========
# itself, allowing us to support numerous different scattered toolkit layouts
execute_process(COMMAND ${_CUDA_NVCC_EXECUTABLE} "-v" "__cmake_determine_cuda"
OUTPUT_VARIABLE _CUDA_NVCC_OUT ERROR_VARIABLE _CUDA_NVCC_OUT)
- if(_CUDA_NVCC_OUT MATCHES "TOP=([^\r\n]*)")
+ if(_CUDA_NVCC_OUT MATCHES "\\#\\$ TOP=([^\r\n]*)")
get_filename_component(CMAKE_CUDA_COMPILER_TOOLKIT_ROOT "${CMAKE_MATCH_1}" ABSOLUTE)
else()
get_filename_component(CMAKE_CUDA_COMPILER_TOOLKIT_ROOT "${_CUDA_NVCC_EXECUTABLE}" DIRECTORY)
list(APPEND _CMAKE_TOOL_VARS AR RANLIB STRIP LINKER NM OBJDUMP OBJCOPY READELF DLLTOOL ADDR2LINE)
endif()
-foreach(_tool IN LISTS _CMAKE_TOOL_VARS)
- foreach(_name IN LISTS _CMAKE_${_tool}_NAMES)
+foreach(_CMAKE_TOOL IN LISTS _CMAKE_TOOL_VARS)
+ foreach(_CMAKE_TOOL_NAME IN LISTS _CMAKE_${_CMAKE_TOOL}_NAMES)
if(NOT _CMAKE_TOOLCHAIN_PREFIX STREQUAL "")
if(NOT _CMAKE_TOOLCHAIN_SUFFIX STREQUAL "")
- list(PREPEND _CMAKE_${_tool}_NAMES ${_name}${_CMAKE_TOOLCHAIN_SUFFIX})
+ list(PREPEND _CMAKE_${_CMAKE_TOOL}_NAMES ${_CMAKE_TOOL_NAME}${_CMAKE_TOOLCHAIN_SUFFIX})
endif()
- list(PREPEND _CMAKE_${_tool}_NAMES ${_CMAKE_TOOLCHAIN_PREFIX}${_name})
+ list(PREPEND _CMAKE_${_CMAKE_TOOL}_NAMES ${_CMAKE_TOOLCHAIN_PREFIX}${_CMAKE_TOOL_NAME})
endif()
if(NOT _CMAKE_TOOLCHAIN_SUFFIX STREQUAL "")
- list(PREPEND _CMAKE_${_tool}_NAMES ${_CMAKE_TOOLCHAIN_PREFIX}${_name}${_CMAKE_TOOLCHAIN_SUFFIX})
+ list(PREPEND _CMAKE_${_CMAKE_TOOL}_NAMES ${_CMAKE_TOOLCHAIN_PREFIX}${_CMAKE_TOOL_NAME}${_CMAKE_TOOLCHAIN_SUFFIX})
endif()
endforeach()
- find_program(CMAKE_${_tool} NAMES ${_CMAKE_${_tool}_NAMES} HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
+ find_program(CMAKE_${_CMAKE_TOOL} NAMES ${_CMAKE_${_CMAKE_TOOL}_NAMES} HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
endforeach()
if(NOT CMAKE_RANLIB)
endif()
# Mark any tool cache entries as advanced.
-foreach(_tool IN LISTS _CMAKE_TOOL_VARS)
- get_property(_CMAKE_TOOL_CACHED CACHE CMAKE_${_tool} PROPERTY TYPE)
+foreach(_CMAKE_TOOL IN LISTS _CMAKE_TOOL_VARS)
+ get_property(_CMAKE_TOOL_CACHED CACHE CMAKE_${_CMAKE_TOOL} PROPERTY TYPE)
if(_CMAKE_TOOL_CACHED)
- mark_as_advanced(CMAKE_${_tool})
+ mark_as_advanced(CMAKE_${_CMAKE_TOOL})
endif()
- unset(_CMAKE_${_tool}_NAMES)
+ unset(_CMAKE_${_CMAKE_TOOL}_NAMES)
endforeach()
unset(_CMAKE_TOOL_VARS)
unset(_CMAKE_TOOL_CACHED)
+unset(_CMAKE_TOOL_NAME)
+unset(_CMAKE_TOOL)
set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std=gnu++1z")
endif()
-if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8.0)
+if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 11.1)
+ set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "-std=c++20")
+ set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "-std=gnu++20")
+ set(CMAKE_CXX23_STANDARD_COMPILE_OPTION "-std=c++23")
+ set(CMAKE_CXX23_EXTENSION_COMPILE_OPTION "-std=gnu++23")
+elseif(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 8.0)
set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "-std=c++2a")
set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "-std=gnu++2a")
endif()
-__compiler_check_default_language_standard(CXX 3.4 98 6.0 14)
+__compiler_check_default_language_standard(CXX 3.4 98 6.0 14 11.1 17)
include(Compiler/PGI-C)
include(Compiler/NVHPC)
+
+# Needed so that we support `LANGUAGE` property correctly
+set(CMAKE_C_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c)
+
+# Required since as of NVHPC 21.03 the `-MD` flag implicitly
+# implies `-E` and therefore compilation and dependency generation
+# can't occur in the same invocation
+set(CMAKE_C_DEPENDS_EXTRA_COMMANDS "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -x c -M <SOURCE> -MT <OBJECT> -MD<DEP_FILE>")
+
__compiler_nvhpc(C)
include(Compiler/PGI-CXX)
include(Compiler/NVHPC)
+
+# Needed so that we support `LANGUAGE` property correctly
+set(CMAKE_CXX_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c++)
+
+# Required since as of NVHPC 21.03 the `-MD` flag implicitly
+# implies `-E` and therefore compilation and dependency generation
+# can't occur in the same invocation
+set(CMAKE_CXX_DEPENDS_EXTRA_COMMANDS "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -x c++ -M <SOURCE> -MT <OBJECT> -MD<DEP_FILE>")
+
__compiler_nvhpc(CXX)
function(get_hash_for_ref ref out_var err_var)
execute_process(
- COMMAND "@git_EXECUTABLE@" rev-parse "${ref}"
+ COMMAND "@git_EXECUTABLE@" rev-parse "${ref}^{commit}"
WORKING_DIRECTORY "@work_dir@"
RESULT_VARIABLE error_code
OUTPUT_VARIABLE ref_hash
get_property(git_progress TARGET ${name} PROPERTY _EP_GIT_PROGRESS)
get_property(git_config TARGET ${name} PROPERTY _EP_GIT_CONFIG)
- # Make checkouts quiet when checking out a git hash (this avoids the
- # very noisy detached head message)
- list(PREPEND git_config advice.detachedHead=false)
+ # If git supports it, make checkouts quiet when checking out a git hash.
+ # This avoids the very noisy detached head message.
+ if(GIT_VERSION_STRING VERSION_GREATER_EQUAL 1.7.7)
+ list(PREPEND git_config advice.detachedHead=false)
+ endif()
# For the download step, and the git clone operation, only the repository
# should be recorded in a configured RepositoryInfo file. If the repo
set(_Boost_TIMER_DEPENDENCIES chrono)
set(_Boost_WAVE_DEPENDENCIES filesystem serialization thread chrono date_time atomic)
set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
- if(Boost_VERSION_STRING VERSION_GREATER_EQUAL 1.76.0 AND NOT Boost_NO_WARN_NEW_VERSIONS)
+ if(Boost_VERSION_STRING VERSION_GREATER_EQUAL 1.77.0 AND NOT Boost_NO_WARN_NEW_VERSIONS)
message(WARNING "New Boost version may have incorrect or missing dependencies and imported targets")
endif()
endif()
# _Boost_COMPONENT_HEADERS. See the instructions at the top of
# _Boost_COMPONENT_DEPENDENCIES.
set(_Boost_KNOWN_VERSIONS ${Boost_ADDITIONAL_VERSIONS}
- "1.75.0" "1.75" "1.74.0" "1.74"
+ "1.76.0" "1.76" "1.75.0" "1.75" "1.74.0" "1.74"
"1.73.0" "1.73" "1.72.0" "1.72" "1.71.0" "1.71" "1.70.0" "1.70" "1.69.0" "1.69"
"1.68.0" "1.68" "1.67.0" "1.67" "1.66.0" "1.66" "1.65.1" "1.65.0" "1.65"
"1.64.0" "1.64" "1.63.0" "1.63" "1.62.0" "1.62" "1.61.0" "1.61" "1.60.0" "1.60"
# itself, allowing us to support numerous different scattered toolkit layouts
execute_process(COMMAND ${CUDA_TOOLKIT_ROOT_DIR_NVCC} "-v" "__cmake_determine_cuda"
OUTPUT_VARIABLE _CUDA_NVCC_OUT ERROR_VARIABLE _CUDA_NVCC_OUT)
- if(_CUDA_NVCC_OUT MATCHES "TOP=([^\r\n]*)")
+ if(_CUDA_NVCC_OUT MATCHES "\\#\\$ TOP=([^\r\n]*)")
get_filename_component(CUDA_TOOLKIT_ROOT_DIR "${CMAKE_MATCH_1}" ABSOLUTE CACHE)
else()
get_filename_component(CUDA_TOOLKIT_ROOT_DIR "${CUDA_TOOLKIT_ROOT_DIR_NVCC}" DIRECTORY)
# NVIDIA HPC SDK, and distro's splayed layouts
execute_process(COMMAND ${CUDAToolkit_NVCC_EXECUTABLE} "-v" "__cmake_determine_cuda"
OUTPUT_VARIABLE _CUDA_NVCC_OUT ERROR_VARIABLE _CUDA_NVCC_OUT)
- if(_CUDA_NVCC_OUT MATCHES "TOP=([^\r\n]*)")
+ if(_CUDA_NVCC_OUT MATCHES "\\#\\$ TOP=([^\r\n]*)")
get_filename_component(CUDAToolkit_BIN_DIR "${CMAKE_MATCH_1}/bin" ABSOLUTE)
else()
get_filename_component(CUDAToolkit_BIN_DIR "${CUDAToolkit_NVCC_EXECUTABLE}" DIRECTORY)
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
set(CMake_VERSION_MINOR 20)
-set(CMake_VERSION_PATCH 2)
+set(CMake_VERSION_PATCH 3)
#set(CMake_VERSION_RC 0)
set(CMake_VERSION_IS_DIRTY 0)
if(NOT CMake_VERSION_NO_GIT)
# If this source was exported by 'git archive', use its commit info.
- set(git_info [==[1ad4501ae9 CMake 3.20.2]==])
+ set(git_info [==[13d112ea03 CMake 3.20.3]==])
# Otherwise, try to identify the current development source version.
if(NOT git_info MATCHES "^([0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]?[0-9a-f]?)[0-9a-f]* "
template <typename FunctionType>
cmCommandLineArgument(std::string n, Values t, FunctionType&& func)
- : InvalidSyntaxMessage(cmStrCat("Invalid syntax used with ", n))
+ : InvalidSyntaxMessage(cmStrCat(" is invalid syntax for ", n))
, InvalidValueMessage(cmStrCat("Invalid value used with ", n))
, Name(std::move(n))
, Type(t)
template <typename FunctionType>
cmCommandLineArgument(std::string n, std::string failedMsg, Values t,
FunctionType&& func)
- : InvalidSyntaxMessage(cmStrCat("Invalid syntax used with ", n))
+ : InvalidSyntaxMessage(cmStrCat(" is invalid syntax for ", n))
, InvalidValueMessage(std::move(failedMsg))
, Name(std::move(n))
, Type(t)
// parse the string to get the value
auto possible_value = cm::string_view(input).substr(this->Name.size());
if (possible_value.empty()) {
- parseState = ParseMode::SyntaxError;
parseState = ParseMode::ValueError;
} else if (possible_value[0] == '=') {
possible_value.remove_prefix(1);
if (possible_value.empty()) {
parseState = ParseMode::ValueError;
- } else {
- parseState = this->StoreCall(std::string(possible_value),
- std::forward<CallState>(state)...)
- ? ParseMode::Valid
- : ParseMode::Invalid;
}
}
if (parseState == ParseMode::Valid) {
: ParseMode::Invalid;
index = (nextValueIndex - 1);
}
+ } else {
+ parseState = ParseMode::SyntaxError;
}
}
if (parseState == ParseMode::SyntaxError) {
- cmSystemTools::Error(this->InvalidSyntaxMessage);
+ cmSystemTools::Error(
+ cmStrCat("'", input, "'", this->InvalidSyntaxMessage));
} else if (parseState == ParseMode::ValueError) {
cmSystemTools::Error(this->InvalidValueMessage);
}
#include "cmSystemTools.h"
cmInstallSubdirectoryGenerator::cmInstallSubdirectoryGenerator(
- cmMakefile* makefile, std::string binaryDirectory, bool excludeFromAll,
+ cmMakefile* makefile, std::string binaryDirectory,
cmListFileBacktrace backtrace)
: cmInstallGenerator("", std::vector<std::string>(), "", MessageDefault,
- excludeFromAll, std::move(backtrace))
+ false, std::move(backtrace))
, Makefile(makefile)
, BinaryDirectory(std::move(binaryDirectory))
{
void cmInstallSubdirectoryGenerator::GenerateScript(std::ostream& os)
{
- if (!this->ExcludeFromAll) {
+ if (!this->Makefile->GetPropertyAsBool("EXCLUDE_FROM_ALL")) {
cmPolicies::PolicyStatus status =
this->LocalGenerator->GetPolicyStatus(cmPolicies::CMP0082);
switch (status) {
public:
cmInstallSubdirectoryGenerator(cmMakefile* makefile,
std::string binaryDirectory,
- bool excludeFromAll,
cmListFileBacktrace backtrace);
~cmInstallSubdirectoryGenerator() override;
std::vector<std::string> archs;
target->GetAppleArchs(config, archs);
if (!archs.empty() &&
- (lang == "C" || lang == "CXX" || lang == "OBJ" || lang == "OBJCXX" ||
+ (lang == "C" || lang == "CXX" || lang == "OBJC" || lang == "OBJCXX" ||
lang == "ASM")) {
for (std::string const& arch : archs) {
if (filterArch.empty() || filterArch == arch) {
}
std::string cmLocalNinjaGenerator::WriteCommandScript(
- std::vector<std::string> const& cmdLines, std::string const& customStep,
+ std::vector<std::string> const& cmdLines, std::string const& outputConfig,
+ std::string const& commandConfig, std::string const& customStep,
cmGeneratorTarget const* target) const
{
std::string scriptPath;
} else {
scriptPath = cmStrCat(this->GetCurrentBinaryDirectory(), "/CMakeFiles");
}
+ scriptPath += this->GetGlobalNinjaGenerator()->ConfigDirectory(outputConfig);
cmSystemTools::MakeDirectory(scriptPath);
scriptPath += '/';
scriptPath += customStep;
+ if (this->GlobalGenerator->IsMultiConfig()) {
+ scriptPath += cmStrCat('-', commandConfig);
+ }
#ifdef _WIN32
scriptPath += ".bat";
#else
}
std::string cmLocalNinjaGenerator::BuildCommandLine(
- std::vector<std::string> const& cmdLines, std::string const& customStep,
+ std::vector<std::string> const& cmdLines, std::string const& outputConfig,
+ std::string const& commandConfig, std::string const& customStep,
cmGeneratorTarget const* target) const
{
// If we have no commands but we need to build a command anyway, use noop.
cmdLinesTotal += cmd.length() + 6;
}
if (cmdLinesTotal > cmSystemTools::CalculateCommandLineLengthLimit() / 2) {
- std::string const scriptPath =
- this->WriteCommandScript(cmdLines, customStep, target);
+ std::string const scriptPath = this->WriteCommandScript(
+ cmdLines, outputConfig, commandConfig, customStep, target);
std::string cmd
#ifndef _WIN32
= "/bin/sh "
}
gg->WriteCustomCommandBuild(
- this->BuildCommandLine(cmdLines, customStep),
+ this->BuildCommandLine(cmdLines, ccg.GetOutputConfig(), fileConfig,
+ customStep),
this->ConstructComment(ccg), "Custom command for " + ninjaOutputs[0],
depfile, cc->GetJobPool(), cc->GetUsesTerminal(),
/*restat*/ !symbolic || !byproducts.empty(), ninjaOutputs, fileConfig,
}
std::string BuildCommandLine(
- std::vector<std::string> const& cmdLines,
+ 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;
std::string MakeCustomLauncher(cmCustomCommandGenerator const& ccg);
std::string WriteCommandScript(std::vector<std::string> const& cmdLines,
+ std::string const& outputConfig,
+ std::string const& commandConfig,
std::string const& customStep,
cmGeneratorTarget const* target) const;
}
this->AddInstallGenerator(cm::make_unique<cmInstallSubdirectoryGenerator>(
- subMf, binPath, excludeFromAll, this->GetBacktrace()));
+ subMf, binPath, this->GetBacktrace()));
}
const std::string& cmMakefile::GetCurrentSourceDirectory() const
// If there is no ranlib the command will be ":". Skip it.
cm::erase_if(linkCmds, cmNinjaRemoveNoOpCommands());
- rule.Command = this->GetLocalGenerator()->BuildCommandLine(linkCmds);
+ rule.Command =
+ this->GetLocalGenerator()->BuildCommandLine(linkCmds, config, config);
// Write the linker rule with response file if needed.
rule.Comment =
cmNinjaRule rule(this->LanguageLinkerCudaDeviceRule(config));
rule.Command = this->GetLocalGenerator()->BuildCommandLine(
{ cmStrCat(mf->GetRequiredDefinition("CMAKE_CUDA_DEVICE_LINKER"),
- " -arch=$ARCH $REGISTER -o=$out $in") });
+ " -arch=$ARCH $REGISTER -o=$out $in") },
+ config, config);
rule.Comment = "Rule for CUDA device linking.";
rule.Description = "Linking CUDA $out";
this->GetGlobalGenerator()->AddRule(rule);
compileCmd, vars);
rule.Name = this->LanguageLinkerCudaDeviceCompileRule(config);
- rule.Command = this->GetLocalGenerator()->BuildCommandLine({ compileCmd });
+ rule.Command = this->GetLocalGenerator()->BuildCommandLine({ compileCmd },
+ config, config);
rule.Comment = "Rule for compiling CUDA device stubs.";
rule.Description = "Compiling CUDA device stub $out";
this->GetGlobalGenerator()->AddRule(rule);
rule.Command = this->GetLocalGenerator()->BuildCommandLine(
{ cmStrCat(mf->GetRequiredDefinition("CMAKE_CUDA_FATBINARY"),
" -64 -cmdline=--compile-only -compress-all -link "
- "--embedded-fatbin=$out $PROFILES") });
+ "--embedded-fatbin=$out $PROFILES") },
+ config, config);
rule.Comment = "Rule for CUDA fatbinaries.";
rule.Description = "Creating fatbinary $out";
this->GetGlobalGenerator()->AddRule(rule);
linkCmds.insert(linkCmds.begin(), "$PRE_LINK");
linkCmds.emplace_back("$POST_BUILD");
- rule.Command = this->GetLocalGenerator()->BuildCommandLine(linkCmds);
+ rule.Command =
+ this->GetLocalGenerator()->BuildCommandLine(linkCmds, config, config);
// Write the linker rule with response file if needed.
rule.Comment =
std::vector<std::string> cmd;
cmd.push_back(cmakeCommand + " -E cmake_symlink_executable $in $out");
cmd.emplace_back("$POST_BUILD");
- rule.Command = this->GetLocalGenerator()->BuildCommandLine(cmd);
+ rule.Command =
+ this->GetLocalGenerator()->BuildCommandLine(cmd, config, config);
}
rule.Description = "Creating executable symlink $out";
rule.Comment = "Rule for creating executable symlink.";
cmd.push_back(cmakeCommand +
" -E cmake_symlink_library $in $SONAME $out");
cmd.emplace_back("$POST_BUILD");
- rule.Command = this->GetLocalGenerator()->BuildCommandLine(cmd);
+ rule.Command =
+ this->GetLocalGenerator()->BuildCommandLine(cmd, config, config);
}
rule.Description = "Creating library symlink $out";
rule.Comment = "Rule for creating library symlink.";
preLinkCmdLines.push_back("cd " + homeOutDir);
}
- vars["PRE_LINK"] = localGen.BuildCommandLine(preLinkCmdLines, "pre-link",
- this->GeneratorTarget);
- std::string postBuildCmdLine = localGen.BuildCommandLine(
- postBuildCmdLines, "post-build", this->GeneratorTarget);
+ vars["PRE_LINK"] = localGen.BuildCommandLine(
+ preLinkCmdLines, config, fileConfig, "pre-link", this->GeneratorTarget);
+ std::string postBuildCmdLine =
+ localGen.BuildCommandLine(postBuildCmdLines, config, fileConfig,
+ "post-build", this->GeneratorTarget);
cmNinjaVars symlinkVars;
bool const symlinkNeeded =
cmRulePlaceholderExpander::RuleVariables const& vars,
const std::string& responseFlag, const std::string& flags,
cmRulePlaceholderExpander* const rulePlaceholderExpander,
- cmLocalNinjaGenerator* generator, std::vector<std::string> scanCmds)
+ cmLocalNinjaGenerator* generator, std::vector<std::string> scanCmds,
+ const std::string& outputConfig)
{
cmNinjaRule rule(ruleName);
// Scanning always uses a depfile for preprocessor dependencies.
for (std::string& scanCmd : scanCmds) {
rulePlaceholderExpander->ExpandRuleVariables(generator, scanCmd, scanVars);
}
- rule.Command = generator->BuildCommandLine(scanCmds);
+ rule.Command =
+ generator->BuildCommandLine(scanCmds, outputConfig, outputConfig);
return rule;
}
auto scanRule = GetScanRule(
scanRuleName, vars, responseFlag, flags, rulePlaceholderExpander.get(),
- this->GetLocalGenerator(), std::move(scanCommands));
+ this->GetLocalGenerator(), std::move(scanCommands), config);
scanRule.Comment =
cmStrCat("Rule for generating ", lang, " dependencies.");
auto scanRule = GetScanRule(
scanRuleName, vars, "", flags, rulePlaceholderExpander.get(),
- this->GetLocalGenerator(), std::move(scanCommands));
+ this->GetLocalGenerator(), std::move(scanCommands), config);
// Write the rule for generating dependencies for the given language.
scanRule.Comment = cmStrCat("Rule for generating ", lang,
ddModmapArg, " --dd=$out @", rule.RspFile);
ddCmds.emplace_back(std::move(ccmd));
}
- rule.Command = this->GetLocalGenerator()->BuildCommandLine(ddCmds);
+ rule.Command =
+ this->GetLocalGenerator()->BuildCommandLine(ddCmds, config, config);
}
rule.Comment =
cmStrCat("Rule to generate ninja dyndep files for ", lang, '.');
vars);
}
- rule.Command = this->GetLocalGenerator()->BuildCommandLine(compileCmds);
+ rule.Command =
+ this->GetLocalGenerator()->BuildCommandLine(compileCmds, config, config);
// Write the rule for compiling file of the given language.
rule.Comment = cmStrCat("Rule for compiling ", lang, " files.");
this->ExportObjectCompileCommand(
language, sourceFileName, objectDir, objectFileName, objectFileDir,
- vars["FLAGS"], vars["DEFINES"], vars["INCLUDES"]);
+ vars["FLAGS"], vars["DEFINES"], vars["INCLUDES"], config);
objBuild.Outputs.push_back(objectFileName);
if (firstForConfig) {
std::string const& language, std::string const& sourceFileName,
std::string const& objectDir, std::string const& objectFileName,
std::string const& objectFileDir, std::string const& flags,
- std::string const& defines, std::string const& includes)
+ std::string const& defines, std::string const& includes,
+ std::string const& outputConfig)
{
if (!this->GeneratorTarget->GetPropertyAsBool("EXPORT_COMPILE_COMMANDS")) {
return;
compileObjectVars);
}
- std::string cmdLine =
- this->GetLocalGenerator()->BuildCommandLine(compileCmds);
+ std::string cmdLine = this->GetLocalGenerator()->BuildCommandLine(
+ compileCmds, outputConfig, outputConfig);
this->GetGlobalGenerator()->AddCXXCompileCommand(cmdLine, sourceFileName);
}
std::string const& language, std::string const& sourceFileName,
std::string const& objectDir, std::string const& objectFileName,
std::string const& objectFileDir, std::string const& flags,
- std::string const& defines, std::string const& includes);
+ std::string const& defines, std::string const& includes,
+ std::string const& outputConfig);
void AdditionalCleanFiles(const std::string& config);
gg->WriteBuild(this->GetCommonFileStream(), phonyBuild);
}
} else {
- std::string command =
- lg->BuildCommandLine(commands, "utility", this->GeneratorTarget);
+ std::string command = lg->BuildCommandLine(
+ commands, config, fileConfig, "utility", this->GeneratorTarget);
std::string desc;
cmProp echoStr = genTarget->GetProperty("EchoString");
if (echoStr) {
return false; \
} \
\
- if (!cmSystemTools::FileIsFullPath(res)) { \
+ if (!work_directory.empty() && !cmSystemTools::FileIsFullPath(res)) { \
res = cmStrCat(work_directory, '/', res); \
} \
} while (0)
}
for (auto const& rule : rules) {
+ std::string work_directory;
Json::Value const& workdir = rule["work-directory"];
- if (!workdir.isString()) {
+ if (workdir.isString()) {
+ PARSE_BLOB(workdir, work_directory);
+ } else if (!workdir.isNull()) {
cmSystemTools::Error(cmStrCat("-E cmake_ninja_dyndep failed to parse ",
arg_pp,
": work-directory is not a string"));
return false;
}
- std::string work_directory;
- PARSE_BLOB(workdir, work_directory);
Json::Value const& depends = rule["depends"];
if (depends.isArray()) {
Json::Value& rules = ddi["rules"] = Json::arrayValue;
Json::Value rule(Json::objectValue);
- rule["work-directory"] =
- EncodeFilename(cmSystemTools::GetCurrentWorkingDirectory());
Json::Value& inputs = rule["inputs"] = Json::arrayValue;
inputs.append(EncodeFilename(input));
for (; i < inputArgs.size() && !nativeOptionsPassed; ++i) {
std::string const& arg = inputArgs[i];
+ bool matched = false;
+ bool parsed = false;
for (auto const& m : arguments) {
- if (m.matches(arg) && m.parse(arg, i, inputArgs)) {
+ matched = m.matches(arg);
+ if (matched) {
+ parsed = m.parse(arg, i, inputArgs);
break;
}
}
+ if (!(matched && parsed)) {
+ dir.clear();
+ if (!matched) {
+ std::cerr << "Unknown argument " << arg << std::endl;
+ }
+ break;
+ }
}
if (nativeOptionsPassed) {
for (decltype(inputArgs.size()) i = 0; i < inputArgs.size(); ++i) {
std::string const& arg = inputArgs[i];
+ bool matched = false;
+ bool parsed = false;
for (auto const& m : arguments) {
- if (m.matches(arg) && m.parse(arg, i, inputArgs)) {
+ matched = m.matches(arg);
+ if (matched) {
+ parsed = m.parse(arg, i, inputArgs);
break;
}
}
+ if (!(matched && parsed)) {
+ dir.clear();
+ if (!matched) {
+ std::cerr << "Unknown argument " << arg << std::endl;
+ }
+ break;
+ }
}
}
${CMAKE_COMMAND} --build)
run_cmake_command(build-no-cache
${CMAKE_COMMAND} --build ${RunCMake_SOURCE_DIR})
+run_cmake_command(build-unknown-command-short
+ ${CMAKE_COMMAND} --build ${RunCMake_SOURCE_DIR} -invalid-command)
+run_cmake_command(build-unknown-command-long
+ ${CMAKE_COMMAND} --build ${RunCMake_SOURCE_DIR} --invalid-command)
+run_cmake_command(build-unknown-command-partial-match
+ ${CMAKE_COMMAND} --build ${RunCMake_SOURCE_DIR} --targetinvalid)
+run_cmake_command(build-invalid-target-syntax
+ ${CMAKE_COMMAND} --build ${RunCMake_SOURCE_DIR} --target=invalid)
run_cmake_command(build-no-generator
${CMAKE_COMMAND} --build ${RunCMake_SOURCE_DIR}/cache-no-generator)
run_cmake_command(build-bad-dir
${CMAKE_COMMAND} --install)
run_cmake_command(install-bad-dir
${CMAKE_COMMAND} --install dir-does-not-exist)
+run_cmake_command(install-unknown-command-short
+ ${CMAKE_COMMAND} --install ${RunCMake_SOURCE_DIR} -invalid-command)
+run_cmake_command(install-unknown-command-long
+ ${CMAKE_COMMAND} --install ${RunCMake_SOURCE_DIR} --invalid-command)
run_cmake_command(install-options-to-vars
${CMAKE_COMMAND} --install ${RunCMake_SOURCE_DIR}/dir-install-options-to-vars
--strip --prefix /var/test --config sample --component pack)
--- /dev/null
+^CMake Error: '--target=invalid' is invalid syntax for --target
+Usage: cmake --build \[<dir> \| --preset <preset>\] \[options\] \[-- \[native-options\]\]
--- /dev/null
+^Unknown argument --invalid-command
+Usage: cmake --build \[<dir> \| --preset <preset>\] \[options\] \[-- \[native-options\]\]
--- /dev/null
+^CMake Error: '--targetinvalid' is invalid syntax for --target
+Usage: cmake --build \[<dir> \| --preset <preset>\] \[options\] \[-- \[native-options\]\]
--- /dev/null
+^Unknown argument -invalid-command
+Usage: cmake --build \[<dir> \| --preset <preset>\] \[options\] \[-- \[native-options\]\]
--- /dev/null
+^Unknown argument --invalid-command
+Usage: cmake --install <dir> \[options\]
--- /dev/null
+^Unknown argument -invalid-command
+Usage: cmake --install <dir> \[options\]
file(GLOB entries ${srcRepo}/*)
file(REMOVE_RECURSE ${entries} ${binDir})
file(TOUCH ${srcRepo}/firstFile.txt)
-configure_file(${CMAKE_CURRENT_LIST_DIR}/FetchGitTags/CMakeLists.txt
+configure_file(${CMAKE_CURRENT_LIST_DIR}/FetchGitRefs/CMakeLists.txt
${srcDir}/CMakeLists.txt COPYONLY)
function(execGitCommand)
execGitCommand(tag -a -m "Adding tag" tag_of_interest)
execGitCommand(reset --hard HEAD~1)
-message(STATUS "Second configure-and-build")
+message(STATUS "Configure-and-build, update to tag")
configureAndBuild(tag_of_interest)
+
+# Do the same, but this time for a commit hash
+file(TOUCH ${srcRepo}/thirdFile.txt)
+execGitCommand(add thirdFile.txt)
+execGitCommand(commit -m "Third file")
+execGitCommand(tag -a -m "Adding another tag" check_for_hash)
+execGitCommand(reset --hard HEAD~1)
+execute_process(
+ WORKING_DIRECTORY ${srcRepo}
+ COMMAND ${GIT_EXECUTABLE} rev-parse check_for_hash
+ COMMAND_ERROR_IS_FATAL ANY
+ OUTPUT_VARIABLE commit_hash
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+)
+
+message(STATUS "Configure-and-build, update to commit hash ${commit_hash}")
+configureAndBuild(${commit_hash})
# Note that there appear to be differences in where git writes its output to
# on some platforms. It may go to stdout or stderr, so force it to be merged.
set(RunCMake_TEST_OUTPUT_MERGE TRUE)
- run_cmake(FetchGitTags)
+ run_cmake(FetchGitRefs)
set(RunCMake_TEST_OUTPUT_MERGE FALSE)
endif()
--- /dev/null
+
+Post-build Debug Release \.*$
ALL
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/gen.txt"
)
+
+add_executable(exe main.c)
+
+add_custom_command(
+ TARGET exe POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E echo "Post-build $<CONFIG> $<COMMAND_CONFIG:$<CONFIG>> ${very_long}"
+ )
run_cmake_build(PostBuild debug-in-release-graph Release Exe:Debug)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/LongCommandLine-build)
+set(RunCMake_TEST_OPTIONS "-DCMAKE_CROSS_CONFIGS=all")
run_cmake_configure(LongCommandLine)
+unset(RunCMake_TEST_OPTIONS)
run_cmake_build(LongCommandLine release Release custom)
+run_cmake_build(LongCommandLine release-config Release exe:Debug)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Framework-build)
set(RunCMake_TEST_OPTIONS "-DCMAKE_CROSS_CONFIGS=all")
install(CODE "message(STATUS \"exclude\")")
+set_directory_properties(PROPERTIES EXCLUDE_FROM_ALL TRUE)
add_subdirectory(CMP0082)
-add_subdirectory(CMP0082-ExcludeFromAll EXCLUDE_FROM_ALL)
+add_subdirectory(CMP0082-ExcludeFromAll)
install(CODE "message(STATUS \"top\")")
add_subdirectory(CMP0082)
-add_subdirectory(CMP0082-ExcludeFromAll EXCLUDE_FROM_ALL)
+add_subdirectory(CMP0082-ExcludeFromAll)
install(CODE "message(STATUS \"top\")")
add_subdirectory(CMP0082)
-add_subdirectory(CMP0082-ExcludeFromAll EXCLUDE_FROM_ALL)
+add_subdirectory(CMP0082-ExcludeFromAll)
install(CODE "message(STATUS \"top\")")
except Exception as e:
sys.stderr.write("ERROR: %s\n" % str(e))
man_show_urls = False
+man_make_section_directory = False
html_show_sourcelink = True
html_static_path = ['@conf_path@/static']