diff options
Diffstat (limited to 'Source/cmake.cxx')
-rw-r--r-- | Source/cmake.cxx | 166 |
1 files changed, 131 insertions, 35 deletions
diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 4d03821..315bd20 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -28,6 +28,7 @@ #include "cm_sys_stat.h" +#include "cmCMakePath.h" #include "cmCMakePresetsFile.h" #include "cmCommandLineArgument.h" #include "cmCommands.h" @@ -156,7 +157,8 @@ static void cmWarnUnusedCliWarning(const std::string& variable, int /*unused*/, #endif cmake::cmake(Role role, cmState::Mode mode) - : FileTimeCache(cm::make_unique<cmFileTimeCache>()) + : CMakeWorkingDirectory(cmSystemTools::GetCurrentWorkingDirectory()) + , FileTimeCache(cm::make_unique<cmFileTimeCache>()) #ifndef CMAKE_BOOTSTRAP , VariableWatch(cm::make_unique<cmVariableWatch>()) #endif @@ -208,9 +210,9 @@ cmake::cmake(Role role, cmState::Mode mode) }; // The "c" extension MUST precede the "C" extension. - setupExts( - this->CLikeSourceFileExtensions, - { "c", "C", "c++", "cc", "cpp", "cxx", "cu", "mpp", "m", "M", "mm" }); + setupExts(this->CLikeSourceFileExtensions, + { "c", "C", "c++", "cc", "cpp", "cxx", "cu", "mpp", "m", "M", + "mm", "ixx", "cppm" }); setupExts(this->HeaderFileExtensions, { "h", "hh", "h++", "hm", "hpp", "hxx", "in", "txx" }); setupExts(this->CudaFileExtensions, { "cu" }); @@ -258,6 +260,13 @@ Json::Value cmake::ReportCapabilitiesJson() const gen["name"] = gi.name; gen["toolsetSupport"] = gi.supportsToolset; gen["platformSupport"] = gi.supportsPlatform; + if (!gi.supportedPlatforms.empty()) { + Json::Value supportedPlatforms = Json::arrayValue; + for (std::string const& platform : gi.supportedPlatforms) { + supportedPlatforms.append(platform); + } + gen["supportedPlatforms"] = std::move(supportedPlatforms); + } gen["extraGenerators"] = Json::arrayValue; generatorMap[gi.name] = gen; } else { @@ -484,7 +493,7 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args) auto ScriptLambda = [&](std::string const& path, cmake* state) -> bool { // Register fake project commands that hint misuse in script mode. GetProjectCommandsInScriptMode(state->GetState()); - // Documented behaviour of CMAKE{,_CURRENT}_{SOURCE,BINARY}_DIR is to be + // Documented behavior of CMAKE{,_CURRENT}_{SOURCE,BINARY}_DIR is to be // set to $PWD for -P mode. state->SetHomeDirectory(cmSystemTools::GetCurrentWorkingDirectory()); state->SetHomeOutputDirectory(cmSystemTools::GetCurrentWorkingDirectory()); @@ -493,26 +502,61 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args) return true; }; + auto PrefixLambda = [&](std::string const& path, cmake* state) -> bool { + const std::string var = "CMAKE_INSTALL_PREFIX"; + cmStateEnums::CacheEntryType type = cmStateEnums::PATH; + cmCMakePath absolutePath(path); + if (absolutePath.IsAbsolute()) { +#ifndef CMAKE_BOOTSTRAP + state->UnprocessedPresetVariables.erase(var); +#endif + state->ProcessCacheArg(var, path, type); + return true; + } + cmSystemTools::Error("Absolute paths are required for --install-prefix"); + return false; + }; + + auto ToolchainLambda = [&](std::string const& path, cmake* state) -> bool { + const std::string var = "CMAKE_TOOLCHAIN_FILE"; + cmStateEnums::CacheEntryType type = cmStateEnums::FILEPATH; +#ifndef CMAKE_BOOTSTRAP + state->UnprocessedPresetVariables.erase(var); +#endif + state->ProcessCacheArg(var, path, type); + return true; + }; + std::vector<CommandArgument> arguments = { CommandArgument{ "-D", "-D must be followed with VAR=VALUE.", - CommandArgument::Values::One, DefineLambda }, + CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, DefineLambda }, CommandArgument{ "-W", "-W must be followed with [no-]<name>.", - CommandArgument::Values::One, WarningLambda }, + CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, WarningLambda }, CommandArgument{ "-U", "-U must be followed with VAR.", - CommandArgument::Values::One, UnSetLambda }, - CommandArgument{ "-C", "-C must be followed by a file name.", CommandArgument::Values::One, - [&](std::string const& value, cmake* state) -> bool { - cmSystemTools::Stdout("loading initial cache file " + - value + "\n"); - // Resolve script path specified on command line - // relative to $PWD. - auto path = cmSystemTools::CollapseFullPath(value); - state->ReadListFile(args, path); - return true; - } }, + CommandArgument::RequiresSeparator::No, UnSetLambda }, + CommandArgument{ + "-C", "-C must be followed by a file name.", + CommandArgument::Values::One, CommandArgument::RequiresSeparator::No, + [&](std::string const& value, cmake* state) -> bool { + cmSystemTools::Stdout("loading initial cache file " + value + "\n"); + // Resolve script path specified on command line + // relative to $PWD. + auto path = cmSystemTools::CollapseFullPath(value); + state->ReadListFile(args, path); + return true; + } }, + CommandArgument{ "-P", "-P must be followed by a file name.", - CommandArgument::Values::One, ScriptLambda }, + CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, ScriptLambda }, + CommandArgument{ "--toolchain", "No file specified for --toolchain", + CommandArgument::Values::One, ToolchainLambda }, + CommandArgument{ "--install-prefix", + "No install directory specified for --install-prefix", + CommandArgument::Values::One, PrefixLambda }, CommandArgument{ "--find-package", CommandArgument::Values::Zero, [&](std::string const&, cmake*) -> bool { findPackageMode = true; @@ -649,7 +693,7 @@ bool cmake::FindPackage(const std::vector<std::string>& args) this->GlobalGenerator->CreateGenerationObjects(); const auto& lg = this->GlobalGenerator->LocalGenerators[0]; std::string includeFlags = - lg->GetIncludeFlags(includeDirs, nullptr, language); + lg->GetIncludeFlags(includeDirs, nullptr, language, std::string()); std::string definitions = mf->GetSafeDefinition("PACKAGE_DEFINITIONS"); printf("%s %s\n", includeFlags.c_str(), definitions.c_str()); @@ -790,31 +834,49 @@ void cmake::SetArgs(const std::vector<std::string>& args) std::vector<CommandArgument> arguments = { CommandArgument{ "-S", "No source directory specified for -S", - CommandArgument::Values::One, SourceArgLambda }, + CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, SourceArgLambda }, CommandArgument{ "-H", "No source directory specified for -H", - CommandArgument::Values::One, SourceArgLambda }, + CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, SourceArgLambda }, CommandArgument{ "-O", CommandArgument::Values::Zero, IgnoreAndTrueLambda }, CommandArgument{ "-B", "No build directory specified for -B", - CommandArgument::Values::One, BuildArgLambda }, + CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, BuildArgLambda }, CommandArgument{ "-P", "-P must be followed by a file name.", CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, [&](std::string const&, cmake*) -> bool { scriptMode = true; return true; } }, CommandArgument{ "-D", "-D must be followed with VAR=VALUE.", - CommandArgument::Values::One, IgnoreAndTrueLambda }, + CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, + IgnoreAndTrueLambda }, CommandArgument{ "-C", "-C must be followed by a file name.", - CommandArgument::Values::One, IgnoreAndTrueLambda }, - CommandArgument{ "-U", "-U must be followed with VAR.", - CommandArgument::Values::One, IgnoreAndTrueLambda }, + CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, + IgnoreAndTrueLambda }, + CommandArgument{ + "-U", "-U must be followed with VAR.", CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, IgnoreAndTrueLambda }, CommandArgument{ "-W", "-W must be followed with [no-]<name>.", - CommandArgument::Values::One, IgnoreAndTrueLambda }, + CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, + IgnoreAndTrueLambda }, CommandArgument{ "-A", "No platform specified for -A", - CommandArgument::Values::One, PlatformLambda }, + CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, PlatformLambda }, CommandArgument{ "-T", "No toolset specified for -T", - CommandArgument::Values::One, ToolsetLamda }, + CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, ToolsetLamda }, + CommandArgument{ "--toolchain", "No file specified for --toolchain", + CommandArgument::Values::One, IgnoreAndTrueLambda }, + CommandArgument{ "--install-prefix", + "No install directory specified for --install-prefix", + CommandArgument::Values::One, IgnoreAndTrueLambda }, CommandArgument{ "--check-build-system", CommandArgument::Values::Two, [](std::string const& value, cmake* state) -> bool { @@ -1034,6 +1096,7 @@ void cmake::SetArgs(const std::vector<std::string>& args) bool badGeneratorName = false; CommandArgument generatorCommand( "-G", "No generator specified for -G", CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, [&](std::string const& value, cmake* state) -> bool { bool valid = state->CreateAndSetGlobalGenerator(value, true); badGeneratorName = !valid; @@ -1194,11 +1257,17 @@ void cmake::SetArgs(const std::vector<std::string>& args) "\": Invalid macro expansion")); return; } + if (!expandedPreset->ConditionResult) { + cmSystemTools::Error(cmStrCat("Could not use disabled preset \"", + preset->second.Unexpanded.Name, "\"")); + return; + } - if (!this->State->IsCacheLoaded() && !haveBArg) { + if (!this->State->IsCacheLoaded() && !haveBArg && + !expandedPreset->BinaryDir.empty()) { this->SetHomeOutputDirectory(expandedPreset->BinaryDir); } - if (!this->GlobalGenerator) { + if (!this->GlobalGenerator && !expandedPreset->Generator.empty()) { if (!this->CreateAndSetGlobalGenerator(expandedPreset->Generator, false)) { return; @@ -1207,6 +1276,19 @@ void cmake::SetArgs(const std::vector<std::string>& args) this->UnprocessedPresetVariables = expandedPreset->CacheVariables; this->UnprocessedPresetEnvironment = expandedPreset->Environment; + if (!expandedPreset->InstallDir.empty() && + !this->State->GetInitializedCacheValue("CMAKE_INSTALL_PREFIX")) { + this->UnprocessedPresetVariables["CMAKE_INSTALL_PREFIX"] = { + "PATH", expandedPreset->InstallDir + }; + } + if (!expandedPreset->ToolchainFile.empty() && + !this->State->GetInitializedCacheValue("CMAKE_TOOLCHAIN_FILE")) { + this->UnprocessedPresetVariables["CMAKE_TOOLCHAIN_FILE"] = { + "FILEPATH", expandedPreset->ToolchainFile + }; + } + if (!expandedPreset->ArchitectureStrategy || expandedPreset->ArchitectureStrategy == cmCMakePresetsFile::ArchToolsetStrategy::Set) { @@ -3023,12 +3105,16 @@ static bool cmakeCheckStampFile(const std::string& stampName) cmsys::ofstream stamp(stampTemp.c_str()); stamp << "# CMake generation timestamp file for this directory.\n"; } - if (cmSystemTools::RenameFile(stampTemp, stampName)) { + std::string err; + if (cmSystemTools::RenameFile(stampTemp, stampName, + cmSystemTools::Replace::Yes, &err) == + cmSystemTools::RenameResult::Success) { // CMake does not need to re-run because the stamp file is up-to-date. return true; } cmSystemTools::RemoveFile(stampTemp); - cmSystemTools::Error("Cannot restore timestamp " + stampName); + cmSystemTools::Error( + cmStrCat("Cannot restore timestamp \"", stampName, "\": ", err)); return false; } @@ -3133,6 +3219,14 @@ int cmake::Build(int jobs, std::string dir, std::vector<std::string> targets, return 1; } + if (!expandedPreset->ConditionResult) { + cmSystemTools::Error(cmStrCat("Cannot use disabled build preset in ", + this->GetHomeDirectory(), ": \"", + presetName, '"')); + settingsFile.PrintBuildPresetList(); + return 1; + } + auto configurePresetPair = settingsFile.ConfigurePresets.find(expandedPreset->ConfigurePreset); if (configurePresetPair == settingsFile.ConfigurePresets.end()) { @@ -3159,7 +3253,9 @@ int cmake::Build(int jobs, std::string dir, std::vector<std::string> targets, return 1; } - dir = expandedConfigurePreset->BinaryDir; + if (!expandedConfigurePreset->BinaryDir.empty()) { + dir = expandedConfigurePreset->BinaryDir; + } this->UnprocessedPresetEnvironment = expandedPreset->Environment; this->ProcessPresetEnvironment(); |