summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/CMakeLists.txt1
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/CTest/cmCTestBuildAndTestHandler.cxx6
-rw-r--r--Source/CursesDialog/form/CMakeLists.txt2
-rw-r--r--Source/cmBuildOptions.h44
-rw-r--r--Source/cmCMakePresetsGraph.cxx3
-rw-r--r--Source/cmCMakePresetsGraph.h3
-rw-r--r--Source/cmCMakePresetsGraphReadJSONBuildPresets.cxx35
-rw-r--r--Source/cmFileAPIToolchains.cxx41
-rw-r--r--Source/cmFunctionBlocker.cxx2
-rw-r--r--Source/cmGeneratorTarget.cxx20
-rw-r--r--Source/cmGeneratorTarget.h3
-rw-r--r--Source/cmGlobalBorlandMakefileGenerator.cxx7
-rw-r--r--Source/cmGlobalBorlandMakefileGenerator.h3
-rw-r--r--Source/cmGlobalGenerator.cxx22
-rw-r--r--Source/cmGlobalGenerator.h8
-rw-r--r--Source/cmGlobalGhsMultiGenerator.cxx3
-rw-r--r--Source/cmGlobalGhsMultiGenerator.h4
-rw-r--r--Source/cmGlobalJOMMakefileGenerator.cxx7
-rw-r--r--Source/cmGlobalJOMMakefileGenerator.h3
-rw-r--r--Source/cmGlobalNMakeMakefileGenerator.cxx7
-rw-r--r--Source/cmGlobalNMakeMakefileGenerator.h3
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx31
-rw-r--r--Source/cmGlobalNinjaGenerator.h6
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.cxx4
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.h4
-rw-r--r--Source/cmGlobalVisualStudio10Generator.cxx107
-rw-r--r--Source/cmGlobalVisualStudio10Generator.h5
-rw-r--r--Source/cmGlobalVisualStudio11Generator.cxx2
-rw-r--r--Source/cmGlobalVisualStudio12Generator.cxx2
-rw-r--r--Source/cmGlobalVisualStudio14Generator.cxx2
-rw-r--r--Source/cmGlobalVisualStudio7Generator.cxx5
-rw-r--r--Source/cmGlobalVisualStudio7Generator.h3
-rw-r--r--Source/cmGlobalVisualStudio9Generator.cxx2
-rw-r--r--Source/cmGlobalVisualStudioGenerator.cxx32
-rw-r--r--Source/cmGlobalVisualStudioGenerator.h2
-rw-r--r--Source/cmGlobalVisualStudioVersionedGenerator.cxx114
-rw-r--r--Source/cmGlobalWatcomWMakeGenerator.cxx7
-rw-r--r--Source/cmGlobalWatcomWMakeGenerator.h4
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx2
-rw-r--r--Source/cmGlobalXCodeGenerator.h3
-rw-r--r--Source/cmListFileCache.cxx28
-rw-r--r--Source/cmListFileCache.h122
-rw-r--r--Source/cmLocalGenerator.cxx30
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx4
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx13
-rw-r--r--Source/cmMakefile.cxx2
-rw-r--r--Source/cmMakefileTargetGenerator.cxx17
-rw-r--r--Source/cmOutputConverter.cxx30
-rw-r--r--Source/cmStandardLevelResolver.cxx5
-rw-r--r--Source/cmStandardLexer.h4
-rw-r--r--Source/cmTimestamp.cxx60
-rw-r--r--Source/cmTimestamp.h8
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx58
-rw-r--r--Source/cmVisualStudio10TargetGenerator.h1
-rw-r--r--Source/cmVisualStudioGeneratorOptions.cxx33
-rw-r--r--Source/cm_utf8.c5
-rw-r--r--Source/cmake.cxx15
-rw-r--r--Source/cmake.h5
-rw-r--r--Source/cmakemain.cxx31
-rw-r--r--Source/kwsys/CMakeLists.txt1
-rw-r--r--Source/kwsys/Directory.cxx90
-rw-r--r--Source/kwsys/Directory.hxx.in21
-rw-r--r--Source/kwsys/Glob.cxx4
-rw-r--r--Source/kwsys/ProcessUNIX.c6
-rw-r--r--Source/kwsys/SystemTools.cxx21
-rw-r--r--Source/kwsys/SystemTools.hxx.in10
-rw-r--r--Source/kwsys/testSystemTools.cxx9
68 files changed, 843 insertions, 356 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index b31b8dc..ddcdd7e 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -155,6 +155,7 @@ set(SRCS
cmBinUtilsWindowsPELinker.h
cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.cxx
cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.h
+ cmBuildOptions.h
cmCacheManager.cxx
cmCacheManager.h
cmCLocaleEnvironmentScope.h
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index d4ad937..3b23899 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,7 +1,7 @@
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
set(CMake_VERSION_MINOR 22)
-set(CMake_VERSION_PATCH 20220121)
+set(CMake_VERSION_PATCH 20220131)
#set(CMake_VERSION_RC 0)
set(CMake_VERSION_IS_DIRTY 0)
diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx
index adfc8ef..e09b4dd 100644
--- a/Source/CTest/cmCTestBuildAndTestHandler.cxx
+++ b/Source/CTest/cmCTestBuildAndTestHandler.cxx
@@ -9,6 +9,7 @@
#include "cmsys/Process.h"
+#include "cmBuildOptions.h"
#include "cmCTest.h"
#include "cmCTestTestHandler.h"
#include "cmGlobalGenerator.h"
@@ -263,10 +264,13 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
if (!config) {
config = "Debug";
}
+
+ cmBuildOptions buildOptions(!this->BuildNoClean, false,
+ PackageResolveMode::Disable);
int retVal = cm.GetGlobalGenerator()->Build(
cmake::NO_BUILD_PARALLEL_LEVEL, this->SourceDir, this->BinaryDir,
this->BuildProject, { tar }, output, this->BuildMakeProgram, config,
- !this->BuildNoClean, false, false, remainingTime);
+ buildOptions, false, remainingTime);
out << output;
// if the build failed then return
if (retVal) {
diff --git a/Source/CursesDialog/form/CMakeLists.txt b/Source/CursesDialog/form/CMakeLists.txt
index 22a2e84..68d28c8 100644
--- a/Source/CursesDialog/form/CMakeLists.txt
+++ b/Source/CursesDialog/form/CMakeLists.txt
@@ -5,7 +5,7 @@ project(CMAKE_FORM)
# Disable warnings to avoid changing 3rd party code.
if(CMAKE_C_COMPILER_ID MATCHES
- "^(GNU|LCC|Clang|AppleClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM|NVHPC)$")
+ "^(GNU|LCC|Clang|AppleClang|IBMClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM|NVHPC)$")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w")
elseif(CMAKE_C_COMPILER_ID STREQUAL "PathScale")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -woffall")
diff --git a/Source/cmBuildOptions.h b/Source/cmBuildOptions.h
new file mode 100644
index 0000000..58baeef
--- /dev/null
+++ b/Source/cmBuildOptions.h
@@ -0,0 +1,44 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#pragma once
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+/** \brief Defines how to resolve packages **/
+enum class PackageResolveMode
+{
+ /** \brief Defines behavior based on cache variable (e.g.
+ CMAKE_VS_NUGET_PACKAGE_RESTORE). This is the default. **/
+ FromCacheVariable,
+
+ /** \brief Ignore behavior defined by cache variable and forces packages to
+ be resolved prior to build. **/
+ Force,
+
+ /** \brief Ignore behavior defined by cache variable and forces packages to
+ be resolved, but skip the actual build. **/
+ OnlyResolve,
+
+ /** \brief Ignore behavior defined by cache variable and dont resolve any
+ packages **/
+ Disable
+};
+
+struct cmBuildOptions
+{
+public:
+ cmBuildOptions() noexcept = default;
+ explicit cmBuildOptions(bool clean, bool fast,
+ PackageResolveMode resolveMode) noexcept
+ : Clean(clean)
+ , Fast(fast)
+ , ResolveMode(resolveMode)
+ {
+ }
+ explicit cmBuildOptions(const cmBuildOptions&) noexcept = default;
+ cmBuildOptions& operator=(const cmBuildOptions&) noexcept = default;
+
+ bool Clean = false;
+ bool Fast = false;
+ PackageResolveMode ResolveMode = PackageResolveMode::FromCacheVariable;
+};
diff --git a/Source/cmCMakePresetsGraph.cxx b/Source/cmCMakePresetsGraph.cxx
index 238aa68..79e8191 100644
--- a/Source/cmCMakePresetsGraph.cxx
+++ b/Source/cmCMakePresetsGraph.cxx
@@ -724,6 +724,9 @@ cmCMakePresetsGraph::BuildPreset::VisitPresetInherit(
InheritOptionalValue(preset.CleanFirst, parent.CleanFirst);
InheritOptionalValue(preset.Verbose, parent.Verbose);
InheritVector(preset.NativeToolOptions, parent.NativeToolOptions);
+ if (!preset.ResolvePackageReferences) {
+ preset.ResolvePackageReferences = parent.ResolvePackageReferences;
+ }
return ReadFileResult::READ_OK;
}
diff --git a/Source/cmCMakePresetsGraph.h b/Source/cmCMakePresetsGraph.h
index 8581809..d3a5cfc 100644
--- a/Source/cmCMakePresetsGraph.h
+++ b/Source/cmCMakePresetsGraph.h
@@ -14,6 +14,8 @@
#include <cm/optional>
+enum class PackageResolveMode;
+
class cmCMakePresetsGraph
{
public:
@@ -181,6 +183,7 @@ public:
cm::optional<bool> CleanFirst;
cm::optional<bool> Verbose;
std::vector<std::string> NativeToolOptions;
+ cm::optional<PackageResolveMode> ResolvePackageReferences;
ReadFileResult VisitPresetInherit(const Preset& parent) override;
ReadFileResult VisitPresetAfterInherit(int /* version */) override;
diff --git a/Source/cmCMakePresetsGraphReadJSONBuildPresets.cxx b/Source/cmCMakePresetsGraphReadJSONBuildPresets.cxx
index ef605d1..eefe2fe 100644
--- a/Source/cmCMakePresetsGraphReadJSONBuildPresets.cxx
+++ b/Source/cmCMakePresetsGraphReadJSONBuildPresets.cxx
@@ -12,6 +12,7 @@
#include <cm3p/json/value.h>
+#include "cmBuildOptions.h"
#include "cmCMakePresetsGraph.h"
#include "cmCMakePresetsGraphInternal.h"
#include "cmJSONHelpers.h"
@@ -20,6 +21,37 @@ namespace {
using ReadFileResult = cmCMakePresetsGraph::ReadFileResult;
using BuildPreset = cmCMakePresetsGraph::BuildPreset;
+ReadFileResult PackageResolveModeHelper(cm::optional<PackageResolveMode>& out,
+ const Json::Value* value)
+{
+ if (!value) {
+ out = cm::nullopt;
+ return ReadFileResult::READ_OK;
+ }
+
+ if (!value->isString()) {
+ return ReadFileResult::INVALID_PRESET;
+ }
+
+ if (value->asString() == "on") {
+ out = PackageResolveMode::Force;
+ } else if (value->asString() == "off") {
+ out = PackageResolveMode::Disable;
+ } else if (value->asString() == "only") {
+ out = PackageResolveMode::OnlyResolve;
+ } else {
+ return ReadFileResult::INVALID_PRESET;
+ }
+
+ return ReadFileResult::READ_OK;
+}
+
+std::function<ReadFileResult(BuildPreset&, const Json::Value*)> const
+ ResolvePackageReferencesHelper =
+ [](BuildPreset& out, const Json::Value* value) -> ReadFileResult {
+ return PackageResolveModeHelper(out.ResolvePackageReferences, value);
+};
+
auto const BuildPresetHelper =
cmJSONObjectHelper<BuildPreset, ReadFileResult>(
ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false)
@@ -59,7 +91,8 @@ auto const BuildPresetHelper =
.Bind("nativeToolOptions"_s, &BuildPreset::NativeToolOptions,
cmCMakePresetsGraphInternal::PresetVectorStringHelper, false)
.Bind("condition"_s, &BuildPreset::ConditionEvaluator,
- cmCMakePresetsGraphInternal::PresetConditionHelper, false);
+ cmCMakePresetsGraphInternal::PresetConditionHelper, false)
+ .Bind("resolvePackageReferences"_s, ResolvePackageReferencesHelper, false);
}
namespace cmCMakePresetsGraphInternal {
diff --git a/Source/cmFileAPIToolchains.cxx b/Source/cmFileAPIToolchains.cxx
index b3540c9..fe2972f 100644
--- a/Source/cmFileAPIToolchains.cxx
+++ b/Source/cmFileAPIToolchains.cxx
@@ -30,10 +30,6 @@ class Toolchains
cmFileAPI& FileAPI;
unsigned long Version;
- static const std::vector<ToolchainVariable> CompilerVariables;
- static const std::vector<ToolchainVariable> CompilerImplicitVariables;
- static const ToolchainVariable SourceFileExtensionsVariable;
-
Json::Value DumpToolchains();
Json::Value DumpToolchain(std::string const& lang);
Json::Value DumpToolchainVariables(
@@ -48,24 +44,6 @@ public:
Json::Value Dump();
};
-const std::vector<ToolchainVariable> Toolchains::CompilerVariables{
- { "path", "COMPILER", false },
- { "id", "COMPILER_ID", false },
- { "version", "COMPILER_VERSION", false },
- { "target", "COMPILER_TARGET", false },
-};
-
-const std::vector<ToolchainVariable> Toolchains::CompilerImplicitVariables{
- { "includeDirectories", "IMPLICIT_INCLUDE_DIRECTORIES", true },
- { "linkDirectories", "IMPLICIT_LINK_DIRECTORIES", true },
- { "linkFrameworkDirectories", "IMPLICIT_LINK_FRAMEWORK_DIRECTORIES", true },
- { "linkLibraries", "IMPLICIT_LINK_LIBRARIES", true },
-};
-
-const ToolchainVariable Toolchains::SourceFileExtensionsVariable{
- "sourceFileExtensions", "SOURCE_FILE_EXTENSIONS", true
-};
-
Toolchains::Toolchains(cmFileAPI& fileAPI, unsigned long version)
: FileAPI(fileAPI)
, Version(version)
@@ -94,6 +72,25 @@ Json::Value Toolchains::DumpToolchains()
Json::Value Toolchains::DumpToolchain(std::string const& lang)
{
+ static const std::vector<ToolchainVariable> CompilerVariables{
+ { "path", "COMPILER", false },
+ { "id", "COMPILER_ID", false },
+ { "version", "COMPILER_VERSION", false },
+ { "target", "COMPILER_TARGET", false },
+ };
+
+ static const std::vector<ToolchainVariable> CompilerImplicitVariables{
+ { "includeDirectories", "IMPLICIT_INCLUDE_DIRECTORIES", true },
+ { "linkDirectories", "IMPLICIT_LINK_DIRECTORIES", true },
+ { "linkFrameworkDirectories", "IMPLICIT_LINK_FRAMEWORK_DIRECTORIES",
+ true },
+ { "linkLibraries", "IMPLICIT_LINK_LIBRARIES", true },
+ };
+
+ static const ToolchainVariable SourceFileExtensionsVariable{
+ "sourceFileExtensions", "SOURCE_FILE_EXTENSIONS", true
+ };
+
const auto& mf =
this->FileAPI.GetCMakeInstance()->GetGlobalGenerator()->GetMakefiles()[0];
Json::Value toolchain = Json::objectValue;
diff --git a/Source/cmFunctionBlocker.cxx b/Source/cmFunctionBlocker.cxx
index d4666d7..40e692d 100644
--- a/Source/cmFunctionBlocker.cxx
+++ b/Source/cmFunctionBlocker.cxx
@@ -27,7 +27,7 @@ bool cmFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff,
if (!this->ArgumentsMatch(lff, mf)) {
cmListFileContext const& lfc = this->GetStartingContext();
cmListFileContext closingContext =
- cmListFileContext::FromCommandContext(lff, lfc.FilePath);
+ cmListFileContext::FromListFileFunction(lff, lfc.FilePath);
std::ostringstream e;
/* clang-format off */
e << "A logical block opening on the line\n"
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 8624362..c4f1a13 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -8262,6 +8262,26 @@ cmLinkItem cmGeneratorTarget::ResolveLinkItem(BT<std::string> const& name,
return cmLinkItem(resolved.Target, false, bt);
}
+bool cmGeneratorTarget::HasPackageReferences() const
+{
+ return this->IsInBuildSystem() &&
+ !this->GetProperty("VS_PACKAGE_REFERENCES")->empty();
+}
+
+std::vector<std::string> cmGeneratorTarget::GetPackageReferences() const
+{
+ std::vector<std::string> packageReferences;
+
+ if (this->IsInBuildSystem()) {
+ if (cmValue vsPackageReferences =
+ this->GetProperty("VS_PACKAGE_REFERENCES")) {
+ cmExpandList(*vsPackageReferences, packageReferences);
+ }
+ }
+
+ return packageReferences;
+}
+
std::string cmGeneratorTarget::GetPDBDirectory(const std::string& config) const
{
if (OutputInfo const* info = this->GetOutputInfo(config)) {
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 0dbc940..45639c0 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -424,6 +424,9 @@ public:
cmLinkItem ResolveLinkItem(BT<std::string> const& name,
cmLocalGenerator const* lg) const;
+ bool HasPackageReferences() const;
+ std::vector<std::string> GetPackageReferences() const;
+
// Compute the set of languages compiled by the target. This is
// computed every time it is called because the languages can change
// when source file properties are changed and we do not have enough
diff --git a/Source/cmGlobalBorlandMakefileGenerator.cxx b/Source/cmGlobalBorlandMakefileGenerator.cxx
index 5503619..776ee40 100644
--- a/Source/cmGlobalBorlandMakefileGenerator.cxx
+++ b/Source/cmGlobalBorlandMakefileGenerator.cxx
@@ -71,12 +71,13 @@ std::vector<cmGlobalGenerator::GeneratedMakeCommand>
cmGlobalBorlandMakefileGenerator::GenerateBuildCommand(
const std::string& makeProgram, const std::string& projectName,
const std::string& projectDir, std::vector<std::string> const& targetNames,
- const std::string& config, bool fast, int /*jobs*/, bool verbose,
+ const std::string& config, int /*jobs*/, bool verbose,
+ const cmBuildOptions& buildOptions,
std::vector<std::string> const& makeOptions)
{
return this->cmGlobalUnixMakefileGenerator3::GenerateBuildCommand(
- makeProgram, projectName, projectDir, targetNames, config, fast,
- cmake::NO_BUILD_PARALLEL_LEVEL, verbose, makeOptions);
+ makeProgram, projectName, projectDir, targetNames, config,
+ cmake::NO_BUILD_PARALLEL_LEVEL, verbose, buildOptions, makeOptions);
}
void cmGlobalBorlandMakefileGenerator::PrintBuildCommandAdvice(
diff --git a/Source/cmGlobalBorlandMakefileGenerator.h b/Source/cmGlobalBorlandMakefileGenerator.h
index 646dfff..a280b81 100644
--- a/Source/cmGlobalBorlandMakefileGenerator.h
+++ b/Source/cmGlobalBorlandMakefileGenerator.h
@@ -59,7 +59,8 @@ protected:
std::vector<GeneratedMakeCommand> GenerateBuildCommand(
const std::string& makeProgram, const std::string& projectName,
const std::string& projectDir, std::vector<std::string> const& targetNames,
- const std::string& config, bool fast, int jobs, bool verbose,
+ const std::string& config, int jobs, bool verbose,
+ const cmBuildOptions& buildOptions = cmBuildOptions(),
std::vector<std::string> const& makeOptions =
std::vector<std::string>()) override;
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 6433681..156ecce 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -1994,16 +1994,19 @@ int cmGlobalGenerator::TryCompile(int jobs, const std::string& srcdir,
}
std::string config =
mf->GetSafeDefinition("CMAKE_TRY_COMPILE_CONFIGURATION");
+ cmBuildOptions defaultBuildOptions(false, fast, PackageResolveMode::Disable);
+
return this->Build(jobs, srcdir, bindir, projectName, newTarget, output, "",
- config, false, fast, false, this->TryCompileTimeout);
+ config, defaultBuildOptions, false,
+ this->TryCompileTimeout);
}
std::vector<cmGlobalGenerator::GeneratedMakeCommand>
cmGlobalGenerator::GenerateBuildCommand(
const std::string& /*unused*/, const std::string& /*unused*/,
const std::string& /*unused*/, std::vector<std::string> const& /*unused*/,
- const std::string& /*unused*/, bool /*unused*/, int /*unused*/,
- bool /*unused*/, std::vector<std::string> const& /*unused*/)
+ const std::string& /*unused*/, int /*unused*/, bool /*unused*/,
+ const cmBuildOptions& /*unused*/, std::vector<std::string> const& /*unused*/)
{
GeneratedMakeCommand makeCommand;
makeCommand.Add("cmGlobalGenerator::GenerateBuildCommand not implemented");
@@ -2021,7 +2024,7 @@ int cmGlobalGenerator::Build(
int jobs, const std::string& /*unused*/, const std::string& bindir,
const std::string& projectName, const std::vector<std::string>& targets,
std::string& output, const std::string& makeCommandCSTR,
- const std::string& config, bool clean, bool fast, bool verbose,
+ const std::string& config, const cmBuildOptions& buildOptions, bool verbose,
cmDuration timeout, cmSystemTools::OutputOption outputflag,
std::vector<std::string> const& nativeOptions)
{
@@ -2053,9 +2056,9 @@ int cmGlobalGenerator::Build(
std::string outputBuffer;
std::string* outputPtr = &outputBuffer;
- std::vector<GeneratedMakeCommand> makeCommand =
- this->GenerateBuildCommand(makeCommandCSTR, projectName, bindir, targets,
- realConfig, fast, jobs, verbose, nativeOptions);
+ std::vector<GeneratedMakeCommand> makeCommand = this->GenerateBuildCommand(
+ makeCommandCSTR, projectName, bindir, targets, realConfig, jobs, verbose,
+ buildOptions, nativeOptions);
// Workaround to convince some commands to produce output.
if (outputflag == cmSystemTools::OUTPUT_PASSTHROUGH &&
@@ -2064,10 +2067,11 @@ int cmGlobalGenerator::Build(
}
// should we do a clean first?
- if (clean) {
+ if (buildOptions.Clean) {
std::vector<GeneratedMakeCommand> cleanCommand =
this->GenerateBuildCommand(makeCommandCSTR, projectName, bindir,
- { "clean" }, realConfig, fast, jobs, verbose);
+ { "clean" }, realConfig, jobs, verbose,
+ buildOptions);
output += "\nRun Clean Command:";
output += cleanCommand.front().Printable();
output += "\n";
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index 2406798..a43d4a6 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -20,6 +20,7 @@
#include "cm_codecvt.hxx"
+#include "cmBuildOptions.h"
#include "cmCustomCommandLines.h"
#include "cmDuration.h"
#include "cmExportSet.h"
@@ -229,8 +230,8 @@ public:
int jobs, const std::string& srcdir, const std::string& bindir,
const std::string& projectName,
std::vector<std::string> const& targetNames, std::string& output,
- const std::string& makeProgram, const std::string& config, bool clean,
- bool fast, bool verbose, cmDuration timeout,
+ const std::string& makeProgram, const std::string& config,
+ const cmBuildOptions& buildOptions, bool verbose, cmDuration timeout,
cmSystemTools::OutputOption outputflag = cmSystemTools::OUTPUT_NONE,
std::vector<std::string> const& nativeOptions =
std::vector<std::string>());
@@ -248,7 +249,8 @@ public:
virtual std::vector<GeneratedMakeCommand> GenerateBuildCommand(
const std::string& makeProgram, const std::string& projectName,
const std::string& projectDir, std::vector<std::string> const& targetNames,
- const std::string& config, bool fast, int jobs, bool verbose,
+ const std::string& config, int jobs, bool verbose,
+ const cmBuildOptions& buildOptions = cmBuildOptions(),
std::vector<std::string> const& makeOptions = std::vector<std::string>());
virtual void PrintBuildCommandAdvice(std::ostream& os, int jobs) const;
diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx
index bf537b7..5e51dd2 100644
--- a/Source/cmGlobalGhsMultiGenerator.cxx
+++ b/Source/cmGlobalGhsMultiGenerator.cxx
@@ -510,7 +510,8 @@ std::vector<cmGlobalGenerator::GeneratedMakeCommand>
cmGlobalGhsMultiGenerator::GenerateBuildCommand(
const std::string& makeProgram, const std::string& projectName,
const std::string& projectDir, std::vector<std::string> const& targetNames,
- const std::string& /*config*/, bool /*fast*/, int jobs, bool /*verbose*/,
+ const std::string& /*config*/, int jobs, bool /*verbose*/,
+ const cmBuildOptions& /*buildOptions*/,
std::vector<std::string> const& makeOptions)
{
GeneratedMakeCommand makeCommand = {};
diff --git a/Source/cmGlobalGhsMultiGenerator.h b/Source/cmGlobalGhsMultiGenerator.h
index 9076e0e..26ea3c7 100644
--- a/Source/cmGlobalGhsMultiGenerator.h
+++ b/Source/cmGlobalGhsMultiGenerator.h
@@ -9,6 +9,7 @@
#include <utility>
#include <vector>
+#include "cmBuildOptions.h"
#include "cmGlobalGenerator.h"
#include "cmGlobalGeneratorFactory.h"
#include "cmTargetDepend.h"
@@ -87,7 +88,8 @@ protected:
std::vector<GeneratedMakeCommand> GenerateBuildCommand(
const std::string& makeProgram, const std::string& projectName,
const std::string& projectDir, std::vector<std::string> const& targetNames,
- const std::string& config, bool fast, int jobs, bool verbose,
+ const std::string& config, int jobs, bool verbose,
+ const cmBuildOptions& buildOptions = cmBuildOptions(),
std::vector<std::string> const& makeOptions =
std::vector<std::string>()) override;
diff --git a/Source/cmGlobalJOMMakefileGenerator.cxx b/Source/cmGlobalJOMMakefileGenerator.cxx
index 1b406a6..1a625cc 100644
--- a/Source/cmGlobalJOMMakefileGenerator.cxx
+++ b/Source/cmGlobalJOMMakefileGenerator.cxx
@@ -63,7 +63,8 @@ std::vector<cmGlobalGenerator::GeneratedMakeCommand>
cmGlobalJOMMakefileGenerator::GenerateBuildCommand(
const std::string& makeProgram, const std::string& projectName,
const std::string& projectDir, std::vector<std::string> const& targetNames,
- const std::string& config, bool fast, int jobs, bool verbose,
+ const std::string& config, int jobs, bool verbose,
+ const cmBuildOptions& buildOptions,
std::vector<std::string> const& makeOptions)
{
std::vector<std::string> jomMakeOptions;
@@ -81,6 +82,6 @@ cmGlobalJOMMakefileGenerator::GenerateBuildCommand(
}
return cmGlobalUnixMakefileGenerator3::GenerateBuildCommand(
- makeProgram, projectName, projectDir, targetNames, config, fast, jobs,
- verbose, jomMakeOptions);
+ makeProgram, projectName, projectDir, targetNames, config, jobs, verbose,
+ buildOptions, jomMakeOptions);
}
diff --git a/Source/cmGlobalJOMMakefileGenerator.h b/Source/cmGlobalJOMMakefileGenerator.h
index 8229745..332d1cf 100644
--- a/Source/cmGlobalJOMMakefileGenerator.h
+++ b/Source/cmGlobalJOMMakefileGenerator.h
@@ -52,7 +52,8 @@ protected:
std::vector<GeneratedMakeCommand> GenerateBuildCommand(
const std::string& makeProgram, const std::string& projectName,
const std::string& projectDir, std::vector<std::string> const& targetNames,
- const std::string& config, bool fast, int jobs, bool verbose,
+ const std::string& config, int jobs, bool verbose,
+ const cmBuildOptions& buildOptions = cmBuildOptions(),
std::vector<std::string> const& makeOptions =
std::vector<std::string>()) override;
diff --git a/Source/cmGlobalNMakeMakefileGenerator.cxx b/Source/cmGlobalNMakeMakefileGenerator.cxx
index 9f3d30e..55748cf 100644
--- a/Source/cmGlobalNMakeMakefileGenerator.cxx
+++ b/Source/cmGlobalNMakeMakefileGenerator.cxx
@@ -106,7 +106,8 @@ std::vector<cmGlobalGenerator::GeneratedMakeCommand>
cmGlobalNMakeMakefileGenerator::GenerateBuildCommand(
const std::string& makeProgram, const std::string& projectName,
const std::string& projectDir, std::vector<std::string> const& targetNames,
- const std::string& config, bool fast, int /*jobs*/, bool verbose,
+ const std::string& config, int /*jobs*/, bool verbose,
+ const cmBuildOptions& buildOptions,
std::vector<std::string> const& makeOptions)
{
std::vector<std::string> nmakeMakeOptions;
@@ -117,8 +118,8 @@ cmGlobalNMakeMakefileGenerator::GenerateBuildCommand(
cm::append(nmakeMakeOptions, makeOptions);
return this->cmGlobalUnixMakefileGenerator3::GenerateBuildCommand(
- makeProgram, projectName, projectDir, targetNames, config, fast,
- cmake::NO_BUILD_PARALLEL_LEVEL, verbose, nmakeMakeOptions);
+ makeProgram, projectName, projectDir, targetNames, config,
+ cmake::NO_BUILD_PARALLEL_LEVEL, verbose, buildOptions, nmakeMakeOptions);
}
void cmGlobalNMakeMakefileGenerator::PrintBuildCommandAdvice(std::ostream& os,
diff --git a/Source/cmGlobalNMakeMakefileGenerator.h b/Source/cmGlobalNMakeMakefileGenerator.h
index ca5b8d6..b3574eb 100644
--- a/Source/cmGlobalNMakeMakefileGenerator.h
+++ b/Source/cmGlobalNMakeMakefileGenerator.h
@@ -58,7 +58,8 @@ protected:
std::vector<GeneratedMakeCommand> GenerateBuildCommand(
const std::string& makeProgram, const std::string& projectName,
const std::string& projectDir, std::vector<std::string> const& targetNames,
- const std::string& config, bool fast, int jobs, bool verbose,
+ const std::string& config, int jobs, bool verbose,
+ const cmBuildOptions& buildOptions = cmBuildOptions(),
std::vector<std::string> const& makeOptions =
std::vector<std::string>()) override;
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 19c4ee3..4245037 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -166,14 +166,18 @@ std::string cmGlobalNinjaGenerator::EncodeRuleName(std::string const& name)
std::string cmGlobalNinjaGenerator::EncodeLiteral(const std::string& lit)
{
std::string result = lit;
- cmSystemTools::ReplaceString(result, "$", "$$");
- cmSystemTools::ReplaceString(result, "\n", "$\n");
+ EncodeLiteralInplace(result);
+ return result;
+}
+
+void cmGlobalNinjaGenerator::EncodeLiteralInplace(std::string& lit)
+{
+ cmSystemTools::ReplaceString(lit, "$", "$$");
+ cmSystemTools::ReplaceString(lit, "\n", "$\n");
if (this->IsMultiConfig()) {
- cmSystemTools::ReplaceString(result,
- cmStrCat('$', this->GetCMakeCFGIntDir()),
+ cmSystemTools::ReplaceString(lit, cmStrCat('$', this->GetCMakeCFGIntDir()),
this->GetCMakeCFGIntDir());
}
- return result;
}
std::string cmGlobalNinjaGenerator::EncodePath(const std::string& path)
@@ -185,7 +189,7 @@ std::string cmGlobalNinjaGenerator::EncodePath(const std::string& path)
else
std::replace(result.begin(), result.end(), '/', '\\');
#endif
- result = this->EncodeLiteral(result);
+ this->EncodeLiteralInplace(result);
cmSystemTools::ReplaceString(result, " ", "$ ");
cmSystemTools::ReplaceString(result, ":", "$:");
return result;
@@ -955,7 +959,7 @@ cmGlobalNinjaGenerator::GenerateBuildCommand(
const std::string& makeProgram, const std::string& /*projectName*/,
const std::string& /*projectDir*/,
std::vector<std::string> const& targetNames, const std::string& config,
- bool /*fast*/, int jobs, bool verbose,
+ int jobs, bool verbose, const cmBuildOptions& /*buildOptions*/,
std::vector<std::string> const& makeOptions)
{
GeneratedMakeCommand makeCommand;
@@ -1021,6 +1025,19 @@ bool cmGlobalNinjaGenerator::OpenBuildFileStreams()
return false;
}
+ // New buffer size 8 MiB
+ constexpr auto buildFileStreamBufferSize = 8 * 1024 * 1024;
+
+ // Ensure the buffer is allocated
+ if (!this->BuildFileStreamBuffer) {
+ this->BuildFileStreamBuffer =
+ cm::make_unique<char[]>(buildFileStreamBufferSize);
+ }
+
+ // Enlarge the internal buffer of the `BuildFileStream`
+ this->BuildFileStream->rdbuf()->pubsetbuf(this->BuildFileStreamBuffer.get(),
+ buildFileStreamBufferSize);
+
// Write a comment about this file.
*this->BuildFileStream
<< "# This file contains all the build statements describing the\n"
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index 84fc06c..aa2df4d 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -18,6 +18,7 @@
#include "cm_codecvt.hxx"
+#include "cmBuildOptions.h"
#include "cmGeneratedFileStream.h"
#include "cmGlobalCommonGenerator.h"
#include "cmGlobalGeneratorFactory.h"
@@ -77,6 +78,7 @@ public:
static std::string EncodeRuleName(std::string const& name);
std::string EncodeLiteral(const std::string& lit);
+ void EncodeLiteralInplace(std::string& lit);
std::string EncodePath(const std::string& path);
std::unique_ptr<cmLinkLineComputer> CreateLinkLineComputer(
@@ -199,7 +201,8 @@ public:
std::vector<GeneratedMakeCommand> GenerateBuildCommand(
const std::string& makeProgram, const std::string& projectName,
const std::string& projectDir, std::vector<std::string> const& targetNames,
- const std::string& config, bool fast, int jobs, bool verbose,
+ const std::string& config, int jobs, bool verbose,
+ const cmBuildOptions& buildOptions = cmBuildOptions(),
std::vector<std::string> const& makeOptions =
std::vector<std::string>()) override;
@@ -526,6 +529,7 @@ private:
/// The file containing the build statement. (the relationship of the
/// compilation DAG).
std::unique_ptr<cmGeneratedFileStream> BuildFileStream;
+ std::unique_ptr<char[]> BuildFileStreamBuffer;
/// The file containing the rule statements. (The action attached to each
/// edge of the compilation DAG).
std::unique_ptr<cmGeneratedFileStream> RulesFileStream;
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index 0556540..ab9ca50 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -518,7 +518,7 @@ cmGlobalUnixMakefileGenerator3::GenerateBuildCommand(
const std::string& makeProgram, const std::string& /*projectName*/,
const std::string& /*projectDir*/,
std::vector<std::string> const& targetNames, const std::string& /*config*/,
- bool fast, int jobs, bool verbose,
+ int jobs, bool verbose, const cmBuildOptions& buildOptions,
std::vector<std::string> const& makeOptions)
{
GeneratedMakeCommand makeCommand;
@@ -548,7 +548,7 @@ cmGlobalUnixMakefileGenerator3::GenerateBuildCommand(
makeCommand.Add(makeOptions.begin(), makeOptions.end());
for (auto tname : targetNames) {
if (!tname.empty()) {
- if (fast) {
+ if (buildOptions.Fast) {
tname += "/fast";
}
cmSystemTools::ConvertToOutputSlashes(tname);
diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h
index 94ee476..5157826 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.h
+++ b/Source/cmGlobalUnixMakefileGenerator3.h
@@ -12,6 +12,7 @@
#include <string>
#include <vector>
+#include "cmBuildOptions.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalCommonGenerator.h"
#include "cmGlobalGeneratorFactory.h"
@@ -163,7 +164,8 @@ public:
std::vector<GeneratedMakeCommand> GenerateBuildCommand(
const std::string& makeProgram, const std::string& projectName,
const std::string& projectDir, std::vector<std::string> const& targetNames,
- const std::string& config, bool fast, int jobs, bool verbose,
+ const std::string& config, int jobs, bool verbose,
+ const cmBuildOptions& buildOptions = cmBuildOptions(),
std::vector<std::string> const& makeOptions =
std::vector<std::string>()) override;
diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx
index d7bc05d..a52c831 100644
--- a/Source/cmGlobalVisualStudio10Generator.cxx
+++ b/Source/cmGlobalVisualStudio10Generator.cxx
@@ -170,7 +170,7 @@ cmGlobalVisualStudio10Generator::cmGlobalVisualStudio10Generator(
this->DefaultNasmFlagTableName = "v10";
this->DefaultRCFlagTableName = "v10";
- this->Version = VS10;
+ this->Version = VSVersion::VS10;
this->PlatformToolsetNeedsDebugEnum = false;
}
@@ -277,8 +277,8 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset(
}
this->SupportsUnityBuilds =
- this->Version >= cmGlobalVisualStudioGenerator::VS16 ||
- (this->Version == cmGlobalVisualStudioGenerator::VS15 &&
+ this->Version >= cmGlobalVisualStudioGenerator::VSVersion::VS16 ||
+ (this->Version == cmGlobalVisualStudioGenerator::VSVersion::VS15 &&
cmSystemTools::PathExists(this->VCTargetsPath +
"/Microsoft.Cpp.Unity.targets"));
@@ -591,7 +591,7 @@ bool cmGlobalVisualStudio10Generator::InitializeWindowsCE(cmMakefile* mf)
this->DefaultPlatformToolset = this->SelectWindowsCEToolset();
- if (this->GetVersion() == cmGlobalVisualStudioGenerator::VS12) {
+ if (this->GetVersion() == cmGlobalVisualStudioGenerator::VSVersion::VS12) {
// VS 12 .NET CF defaults to .NET framework 3.9 for Windows CE.
this->DefaultTargetFrameworkVersion = "v3.9";
this->DefaultTargetFrameworkIdentifier = "WindowsEmbeddedCompact";
@@ -724,6 +724,10 @@ void cmGlobalVisualStudio10Generator::Generate()
/* clang-format on */
lg->IssueMessage(MessageType::WARNING, e.str());
}
+ if (cmValue cached = this->CMakeInstance->GetState()->GetCacheEntryValue(
+ "CMAKE_VS_NUGET_PACKAGE_RESTORE")) {
+ this->CMakeInstance->MarkCliAsUsed("CMAKE_VS_NUGET_PACKAGE_RESTORE");
+ }
}
void cmGlobalVisualStudio10Generator::EnableLanguage(
@@ -1099,7 +1103,8 @@ std::vector<cmGlobalGenerator::GeneratedMakeCommand>
cmGlobalVisualStudio10Generator::GenerateBuildCommand(
const std::string& makeProgram, const std::string& projectName,
const std::string& projectDir, std::vector<std::string> const& targetNames,
- const std::string& config, bool fast, int jobs, bool verbose,
+ const std::string& config, int jobs, bool verbose,
+ const cmBuildOptions& buildOptions,
std::vector<std::string> const& makeOptions)
{
std::vector<GeneratedMakeCommand> makeCommands;
@@ -1145,8 +1150,8 @@ cmGlobalVisualStudio10Generator::GenerateBuildCommand(
if (useDevEnv) {
// Use devenv to build solutions containing Intel Fortran projects.
return cmGlobalVisualStudio7Generator::GenerateBuildCommand(
- makeProgram, projectName, projectDir, targetNames, config, fast, jobs,
- verbose, makeOptions);
+ makeProgram, projectName, projectDir, targetNames, config, jobs, verbose,
+ buildOptions, makeOptions);
}
std::vector<std::string> realTargetNames = targetNames;
@@ -1178,8 +1183,66 @@ cmGlobalVisualStudio10Generator::GenerateBuildCommand(
cmSystemTools::ConvertToUnixSlashes(targetProject);
}
}
- makeCommand.Add(std::move(targetProject));
+ makeCommand.Add(targetProject);
+
+ // Check if we do need a restore at all (i.e. if there are package
+ // references and restore has not been disabled by a command line option.
+ PackageResolveMode restoreMode = buildOptions.ResolveMode;
+ bool requiresRestore = true;
+
+ if (restoreMode == PackageResolveMode::Disable) {
+ requiresRestore = false;
+ } else if (cmValue cached =
+ this->CMakeInstance->GetState()->GetCacheEntryValue(
+ tname + "_REQUIRES_VS_PACKAGE_RESTORE")) {
+ requiresRestore = cached.IsOn();
+ } else {
+ // There are no package references defined.
+ requiresRestore = false;
+ }
+
+ // If a restore is required, evaluate the restore mode.
+ if (requiresRestore) {
+ if (restoreMode == PackageResolveMode::OnlyResolve) {
+ // Only invoke the restore target on the project.
+ makeCommand.Add("/t:Restore");
+ } else {
+ // Invoke restore target, unless it has been explicitly disabled.
+ bool restorePackages = true;
+
+ if (this->Version < VSVersion::VS15) {
+ // Package restore is only supported starting from Visual Studio
+ // 2017. Package restore must be executed manually using NuGet
+ // shell for older versions.
+ this->CMakeInstance->IssueMessage(
+ MessageType::WARNING,
+ "Restoring package references is only supported for Visual "
+ "Studio 2017 and later. You have to manually restore the "
+ "packages using NuGet before building the project.");
+ restorePackages = false;
+ } else if (restoreMode == PackageResolveMode::FromCacheVariable) {
+ // Decide if a restore is performed, based on a cache variable.
+ if (cmValue cached =
+ this->CMakeInstance->GetState()->GetCacheEntryValue(
+ "CMAKE_VS_NUGET_PACKAGE_RESTORE"))
+ restorePackages = cached.IsOn();
+ }
+
+ if (restorePackages) {
+ if (this->IsMsBuildRestoreSupported()) {
+ makeCommand.Add("/restore");
+ } else {
+ GeneratedMakeCommand restoreCommand;
+ restoreCommand.Add(makeProgramSelected);
+ restoreCommand.Add(targetProject);
+ restoreCommand.Add("/t:Restore");
+ makeCommands.emplace_back(restoreCommand);
+ }
+ }
+ }
+ }
}
+
std::string configArg = "/p:Configuration=";
if (!config.empty()) {
configArg += config;
@@ -1284,23 +1347,23 @@ std::string cmGlobalVisualStudio10Generator::Encoding()
const char* cmGlobalVisualStudio10Generator::GetToolsVersion() const
{
switch (this->Version) {
- case cmGlobalVisualStudioGenerator::VS9:
- case cmGlobalVisualStudioGenerator::VS10:
- case cmGlobalVisualStudioGenerator::VS11:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS9:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS10:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS11:
return "4.0";
// in Visual Studio 2013 they detached the MSBuild tools version
// from the .Net Framework version and instead made it have it's own
// version number
- case cmGlobalVisualStudioGenerator::VS12:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS12:
return "12.0";
- case cmGlobalVisualStudioGenerator::VS14:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS14:
return "14.0";
- case cmGlobalVisualStudioGenerator::VS15:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS15:
return "15.0";
- case cmGlobalVisualStudioGenerator::VS16:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS16:
return "16.0";
- case cmGlobalVisualStudioGenerator::VS17:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS17:
return "17.0";
}
return "";
@@ -1559,6 +1622,18 @@ cmIDEFlagTable const* cmGlobalVisualStudio10Generator::GetNasmFlagTable() const
return LoadFlagTable(std::string(), this->DefaultNasmFlagTableName, "NASM");
}
+bool cmGlobalVisualStudio10Generator::IsMsBuildRestoreSupported() const
+{
+ if (this->Version >= VSVersion::VS16) {
+ return true;
+ }
+
+ static std::string const vsVer15_7_5 = "15.7.27703.2042";
+ cm::optional<std::string> vsVer = this->GetVSInstanceVersion();
+ return (vsVer &&
+ cmSystemTools::VersionCompareGreaterEq(*vsVer, vsVer15_7_5));
+}
+
std::string cmGlobalVisualStudio10Generator::GetClFlagTableName() const
{
std::string const& toolset = this->GetPlatformToolsetString();
diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h
index c8fd149..4977a84 100644
--- a/Source/cmGlobalVisualStudio10Generator.h
+++ b/Source/cmGlobalVisualStudio10Generator.h
@@ -43,7 +43,8 @@ public:
std::vector<GeneratedMakeCommand> GenerateBuildCommand(
const std::string& makeProgram, const std::string& projectName,
const std::string& projectDir, std::vector<std::string> const& targetNames,
- const std::string& config, bool fast, int jobs, bool verbose,
+ const std::string& config, int jobs, bool verbose,
+ const cmBuildOptions& buildOptions = cmBuildOptions(),
std::vector<std::string> const& makeOptions =
std::vector<std::string>()) override;
@@ -172,6 +173,8 @@ public:
cmIDEFlagTable const* GetMasmFlagTable() const;
cmIDEFlagTable const* GetNasmFlagTable() const;
+ bool IsMsBuildRestoreSupported() const;
+
protected:
cmGlobalVisualStudio10Generator(cmake* cm, const std::string& name,
std::string const& platformInGeneratorName);
diff --git a/Source/cmGlobalVisualStudio11Generator.cxx b/Source/cmGlobalVisualStudio11Generator.cxx
index 6126cb4..10dc258 100644
--- a/Source/cmGlobalVisualStudio11Generator.cxx
+++ b/Source/cmGlobalVisualStudio11Generator.cxx
@@ -148,7 +148,7 @@ cmGlobalVisualStudio11Generator::cmGlobalVisualStudio11Generator(
this->DefaultLinkFlagTableName = "v11";
this->DefaultMasmFlagTableName = "v11";
this->DefaultRCFlagTableName = "v11";
- this->Version = VS11;
+ this->Version = VSVersion::VS11;
}
bool cmGlobalVisualStudio11Generator::MatchesGeneratorName(
diff --git a/Source/cmGlobalVisualStudio12Generator.cxx b/Source/cmGlobalVisualStudio12Generator.cxx
index d8c1b43..12ffa5b 100644
--- a/Source/cmGlobalVisualStudio12Generator.cxx
+++ b/Source/cmGlobalVisualStudio12Generator.cxx
@@ -122,7 +122,7 @@ cmGlobalVisualStudio12Generator::cmGlobalVisualStudio12Generator(
this->DefaultLinkFlagTableName = "v12";
this->DefaultMasmFlagTableName = "v12";
this->DefaultRCFlagTableName = "v12";
- this->Version = VS12;
+ this->Version = VSVersion::VS12;
}
bool cmGlobalVisualStudio12Generator::MatchesGeneratorName(
diff --git a/Source/cmGlobalVisualStudio14Generator.cxx b/Source/cmGlobalVisualStudio14Generator.cxx
index 014668f..9f94cca 100644
--- a/Source/cmGlobalVisualStudio14Generator.cxx
+++ b/Source/cmGlobalVisualStudio14Generator.cxx
@@ -125,7 +125,7 @@ cmGlobalVisualStudio14Generator::cmGlobalVisualStudio14Generator(
this->DefaultLinkFlagTableName = "v140";
this->DefaultMasmFlagTableName = "v14";
this->DefaultRCFlagTableName = "v14";
- this->Version = VS14;
+ this->Version = VSVersion::VS14;
}
bool cmGlobalVisualStudio14Generator::MatchesGeneratorName(
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
index c72b109..134937e 100644
--- a/Source/cmGlobalVisualStudio7Generator.cxx
+++ b/Source/cmGlobalVisualStudio7Generator.cxx
@@ -212,7 +212,7 @@ cmGlobalVisualStudio7Generator::GenerateBuildCommand(
const std::string& makeProgram, const std::string& projectName,
const std::string& /*projectDir*/,
std::vector<std::string> const& targetNames, const std::string& config,
- bool /*fast*/, int /*jobs*/, bool /*verbose*/,
+ int /*jobs*/, bool /*verbose*/, const cmBuildOptions& /*buildOptions*/,
std::vector<std::string> const& makeOptions)
{
// Select the caller- or user-preferred make program, else devenv.
@@ -304,7 +304,8 @@ void cmGlobalVisualStudio7Generator::Generate()
GetSLNFile(this->LocalGenerators[0].get()));
}
- if (this->Version == VS10 && !this->CMakeInstance->GetIsInTryCompile()) {
+ if (this->Version == VSVersion::VS10 &&
+ !this->CMakeInstance->GetIsInTryCompile()) {
std::string cmakeWarnVS10;
if (cmValue cached = this->CMakeInstance->GetState()->GetCacheEntryValue(
"CMAKE_WARN_VS10")) {
diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h
index d1fb804..33f1063 100644
--- a/Source/cmGlobalVisualStudio7Generator.h
+++ b/Source/cmGlobalVisualStudio7Generator.h
@@ -69,7 +69,8 @@ public:
std::vector<GeneratedMakeCommand> GenerateBuildCommand(
const std::string& makeProgram, const std::string& projectName,
const std::string& projectDir, std::vector<std::string> const& targetNames,
- const std::string& config, bool fast, int jobs, bool verbose,
+ const std::string& config, int jobs, bool verbose,
+ const cmBuildOptions& buildOptions = cmBuildOptions(),
std::vector<std::string> const& makeOptions =
std::vector<std::string>()) override;
diff --git a/Source/cmGlobalVisualStudio9Generator.cxx b/Source/cmGlobalVisualStudio9Generator.cxx
index 5f867f5..e03e665 100644
--- a/Source/cmGlobalVisualStudio9Generator.cxx
+++ b/Source/cmGlobalVisualStudio9Generator.cxx
@@ -124,7 +124,7 @@ cmGlobalVisualStudio9Generator::cmGlobalVisualStudio9Generator(
std::string const& platformInGeneratorName)
: cmGlobalVisualStudio8Generator(cm, name, platformInGeneratorName)
{
- this->Version = VS9;
+ this->Version = VSVersion::VS9;
std::string vc9Express;
this->ExpressEdition = cmSystemTools::ReadRegistryValue(
"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\9.0\\Setup\\VC;"
diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx
index 948fa53..141b5eb 100644
--- a/Source/cmGlobalVisualStudioGenerator.cxx
+++ b/Source/cmGlobalVisualStudioGenerator.cxx
@@ -97,21 +97,21 @@ std::string const& cmGlobalVisualStudioGenerator::GetPlatformName() const
const char* cmGlobalVisualStudioGenerator::GetIDEVersion() const
{
switch (this->Version) {
- case cmGlobalVisualStudioGenerator::VS9:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS9:
return "9.0";
- case cmGlobalVisualStudioGenerator::VS10:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS10:
return "10.0";
- case cmGlobalVisualStudioGenerator::VS11:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS11:
return "11.0";
- case cmGlobalVisualStudioGenerator::VS12:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS12:
return "12.0";
- case cmGlobalVisualStudioGenerator::VS14:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS14:
return "14.0";
- case cmGlobalVisualStudioGenerator::VS15:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS15:
return "15.0";
- case cmGlobalVisualStudioGenerator::VS16:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS16:
return "16.0";
- case cmGlobalVisualStudioGenerator::VS17:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS17:
return "17.0";
}
return "";
@@ -124,11 +124,11 @@ void cmGlobalVisualStudioGenerator::WriteSLNHeader(std::ostream& fout)
fout << '\n';
switch (this->Version) {
- case cmGlobalVisualStudioGenerator::VS9:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS9:
fout << "Microsoft Visual Studio Solution File, Format Version 10.00\n";
fout << "# Visual Studio 2008\n";
break;
- case cmGlobalVisualStudioGenerator::VS10:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS10:
fout << "Microsoft Visual Studio Solution File, Format Version 11.00\n";
if (this->ExpressEdition) {
fout << "# Visual C++ Express 2010\n";
@@ -136,7 +136,7 @@ void cmGlobalVisualStudioGenerator::WriteSLNHeader(std::ostream& fout)
fout << "# Visual Studio 2010\n";
}
break;
- case cmGlobalVisualStudioGenerator::VS11:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS11:
fout << "Microsoft Visual Studio Solution File, Format Version 12.00\n";
if (this->ExpressEdition) {
fout << "# Visual Studio Express 2012 for Windows Desktop\n";
@@ -144,7 +144,7 @@ void cmGlobalVisualStudioGenerator::WriteSLNHeader(std::ostream& fout)
fout << "# Visual Studio 2012\n";
}
break;
- case cmGlobalVisualStudioGenerator::VS12:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS12:
fout << "Microsoft Visual Studio Solution File, Format Version 12.00\n";
if (this->ExpressEdition) {
fout << "# Visual Studio Express 2013 for Windows Desktop\n";
@@ -152,7 +152,7 @@ void cmGlobalVisualStudioGenerator::WriteSLNHeader(std::ostream& fout)
fout << "# Visual Studio 2013\n";
}
break;
- case cmGlobalVisualStudioGenerator::VS14:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS14:
// Visual Studio 14 writes .sln format 12.00
fout << "Microsoft Visual Studio Solution File, Format Version 12.00\n";
if (this->ExpressEdition) {
@@ -161,7 +161,7 @@ void cmGlobalVisualStudioGenerator::WriteSLNHeader(std::ostream& fout)
fout << "# Visual Studio 14\n";
}
break;
- case cmGlobalVisualStudioGenerator::VS15:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS15:
// Visual Studio 15 writes .sln format 12.00
fout << "Microsoft Visual Studio Solution File, Format Version 12.00\n";
if (this->ExpressEdition) {
@@ -170,7 +170,7 @@ void cmGlobalVisualStudioGenerator::WriteSLNHeader(std::ostream& fout)
fout << "# Visual Studio 15\n";
}
break;
- case cmGlobalVisualStudioGenerator::VS16:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS16:
// Visual Studio 16 writes .sln format 12.00
fout << "Microsoft Visual Studio Solution File, Format Version 12.00\n";
if (this->ExpressEdition) {
@@ -179,7 +179,7 @@ void cmGlobalVisualStudioGenerator::WriteSLNHeader(std::ostream& fout)
fout << "# Visual Studio Version 16\n";
}
break;
- case cmGlobalVisualStudioGenerator::VS17:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS17:
// Visual Studio 17 writes .sln format 12.00
fout << "Microsoft Visual Studio Solution File, Format Version 12.00\n";
if (this->ExpressEdition) {
diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h
index 1eff135..cb1b14b 100644
--- a/Source/cmGlobalVisualStudioGenerator.h
+++ b/Source/cmGlobalVisualStudioGenerator.h
@@ -32,7 +32,7 @@ class cmGlobalVisualStudioGenerator : public cmGlobalGenerator
{
public:
/** Known versions of Visual Studio. */
- enum VSVersion
+ enum class VSVersion : uint16_t
{
VS9 = 90,
VS10 = 100,
diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.cxx b/Source/cmGlobalVisualStudioVersionedGenerator.cxx
index ef8fee1..bc38335 100644
--- a/Source/cmGlobalVisualStudioVersionedGenerator.cxx
+++ b/Source/cmGlobalVisualStudioVersionedGenerator.cxx
@@ -75,21 +75,21 @@ static unsigned int VSVersionToMajor(
cmGlobalVisualStudioGenerator::VSVersion v)
{
switch (v) {
- case cmGlobalVisualStudioGenerator::VS9:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS9:
return 9;
- case cmGlobalVisualStudioGenerator::VS10:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS10:
return 10;
- case cmGlobalVisualStudioGenerator::VS11:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS11:
return 11;
- case cmGlobalVisualStudioGenerator::VS12:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS12:
return 12;
- case cmGlobalVisualStudioGenerator::VS14:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS14:
return 14;
- case cmGlobalVisualStudioGenerator::VS15:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS15:
return 15;
- case cmGlobalVisualStudioGenerator::VS16:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS16:
return 16;
- case cmGlobalVisualStudioGenerator::VS17:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS17:
return 17;
}
return 0;
@@ -99,21 +99,21 @@ static const char* VSVersionToToolset(
cmGlobalVisualStudioGenerator::VSVersion v)
{
switch (v) {
- case cmGlobalVisualStudioGenerator::VS9:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS9:
return "v90";
- case cmGlobalVisualStudioGenerator::VS10:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS10:
return "v100";
- case cmGlobalVisualStudioGenerator::VS11:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS11:
return "v110";
- case cmGlobalVisualStudioGenerator::VS12:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS12:
return "v120";
- case cmGlobalVisualStudioGenerator::VS14:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS14:
return "v140";
- case cmGlobalVisualStudioGenerator::VS15:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS15:
return "v141";
- case cmGlobalVisualStudioGenerator::VS16:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS16:
return "v142";
- case cmGlobalVisualStudioGenerator::VS17:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS17:
return "v143";
}
return "";
@@ -123,21 +123,21 @@ static std::string VSVersionToMajorString(
cmGlobalVisualStudioGenerator::VSVersion v)
{
switch (v) {
- case cmGlobalVisualStudioGenerator::VS9:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS9:
return "9";
- case cmGlobalVisualStudioGenerator::VS10:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS10:
return "10";
- case cmGlobalVisualStudioGenerator::VS11:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS11:
return "11";
- case cmGlobalVisualStudioGenerator::VS12:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS12:
return "12";
- case cmGlobalVisualStudioGenerator::VS14:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS14:
return "14";
- case cmGlobalVisualStudioGenerator::VS15:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS15:
return "15";
- case cmGlobalVisualStudioGenerator::VS16:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS16:
return "16";
- case cmGlobalVisualStudioGenerator::VS17:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS17:
return "17";
}
return "";
@@ -147,16 +147,16 @@ static const char* VSVersionToAndroidToolset(
cmGlobalVisualStudioGenerator::VSVersion v)
{
switch (v) {
- case cmGlobalVisualStudioGenerator::VS9:
- case cmGlobalVisualStudioGenerator::VS10:
- case cmGlobalVisualStudioGenerator::VS11:
- case cmGlobalVisualStudioGenerator::VS12:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS9:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS10:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS11:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS12:
return "";
- case cmGlobalVisualStudioGenerator::VS14:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS14:
return "Clang_3_8";
- case cmGlobalVisualStudioGenerator::VS15:
- case cmGlobalVisualStudioGenerator::VS16:
- case cmGlobalVisualStudioGenerator::VS17:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS15:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS16:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS17:
return "Clang_5_0";
}
return "";
@@ -194,7 +194,7 @@ public:
if (!*p) {
return std::unique_ptr<cmGlobalGenerator>(
new cmGlobalVisualStudioVersionedGenerator(
- cmGlobalVisualStudioGenerator::VS15, cm, genName, ""));
+ cmGlobalVisualStudioGenerator::VSVersion::VS15, cm, genName, ""));
}
if (!allowArch || *p++ != ' ') {
return std::unique_ptr<cmGlobalGenerator>();
@@ -202,12 +202,12 @@ public:
if (strcmp(p, "Win64") == 0) {
return std::unique_ptr<cmGlobalGenerator>(
new cmGlobalVisualStudioVersionedGenerator(
- cmGlobalVisualStudioGenerator::VS15, cm, genName, "x64"));
+ cmGlobalVisualStudioGenerator::VSVersion::VS15, cm, genName, "x64"));
}
if (strcmp(p, "ARM") == 0) {
return std::unique_ptr<cmGlobalGenerator>(
new cmGlobalVisualStudioVersionedGenerator(
- cmGlobalVisualStudioGenerator::VS15, cm, genName, "ARM"));
+ cmGlobalVisualStudioGenerator::VSVersion::VS15, cm, genName, "ARM"));
}
return std::unique_ptr<cmGlobalGenerator>();
}
@@ -303,7 +303,7 @@ public:
if (!*p) {
return std::unique_ptr<cmGlobalGenerator>(
new cmGlobalVisualStudioVersionedGenerator(
- cmGlobalVisualStudioGenerator::VS16, cm, genName, ""));
+ cmGlobalVisualStudioGenerator::VSVersion::VS16, cm, genName, ""));
}
return std::unique_ptr<cmGlobalGenerator>();
}
@@ -368,7 +368,7 @@ public:
if (!*p) {
return std::unique_ptr<cmGlobalGenerator>(
new cmGlobalVisualStudioVersionedGenerator(
- cmGlobalVisualStudioGenerator::VS17, cm, genName, ""));
+ cmGlobalVisualStudioGenerator::VSVersion::VS17, cm, genName, ""));
}
return std::unique_ptr<cmGlobalGenerator>();
}
@@ -431,11 +431,11 @@ cmGlobalVisualStudioVersionedGenerator::cmGlobalVisualStudioVersionedGenerator(
this->DefaultCLFlagTableName = VSVersionToToolset(this->Version);
this->DefaultCSharpFlagTableName = VSVersionToToolset(this->Version);
this->DefaultLinkFlagTableName = VSVersionToToolset(this->Version);
- if (this->Version >= cmGlobalVisualStudioGenerator::VS16) {
+ if (this->Version >= cmGlobalVisualStudioGenerator::VSVersion::VS16) {
this->DefaultPlatformName = VSHostPlatformName();
this->DefaultPlatformToolsetHostArchitecture = VSHostArchitecture();
}
- if (this->Version >= cmGlobalVisualStudioGenerator::VS17) {
+ if (this->Version >= cmGlobalVisualStudioGenerator::VSVersion::VS17) {
// FIXME: Search for an existing framework? Under '%ProgramFiles(x86)%',
// see 'Reference Assemblies\Microsoft\Framework\.NETFramework'.
// Use a version installed by VS 2022 without a separate component.
@@ -448,23 +448,23 @@ bool cmGlobalVisualStudioVersionedGenerator::MatchesGeneratorName(
{
std::string genName;
switch (this->Version) {
- case cmGlobalVisualStudioGenerator::VS9:
- case cmGlobalVisualStudioGenerator::VS10:
- case cmGlobalVisualStudioGenerator::VS11:
- case cmGlobalVisualStudioGenerator::VS12:
- case cmGlobalVisualStudioGenerator::VS14:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS9:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS10:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS11:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS12:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS14:
break;
- case cmGlobalVisualStudioGenerator::VS15:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS15:
if (cmVS15GenName(name, genName)) {
return genName == this->GetName();
}
break;
- case cmGlobalVisualStudioGenerator::VS16:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS16:
if (cmVS16GenName(name, genName)) {
return genName == this->GetName();
}
break;
- case cmGlobalVisualStudioGenerator::VS17:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS17:
if (cmVS17GenName(name, genName)) {
return genName == this->GetName();
}
@@ -691,16 +691,16 @@ cmGlobalVisualStudioVersionedGenerator::GetAndroidApplicationTypeRevision()
const
{
switch (this->Version) {
- case cmGlobalVisualStudioGenerator::VS9:
- case cmGlobalVisualStudioGenerator::VS10:
- case cmGlobalVisualStudioGenerator::VS11:
- case cmGlobalVisualStudioGenerator::VS12:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS9:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS10:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS11:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS12:
return "";
- case cmGlobalVisualStudioGenerator::VS14:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS14:
return "2.0";
- case cmGlobalVisualStudioGenerator::VS15:
- case cmGlobalVisualStudioGenerator::VS16:
- case cmGlobalVisualStudioGenerator::VS17:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS15:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS16:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS17:
return "3.0";
}
return "";
@@ -806,7 +806,7 @@ bool cmGlobalVisualStudioVersionedGenerator::InitializeWindows(cmMakefile* mf)
// the target Windows version.
if (this->IsWin81SDKInstalled()) {
// VS 2019 does not default to 8.1 so specify it explicitly when needed.
- if (this->Version >= cmGlobalVisualStudioGenerator::VS16 &&
+ if (this->Version >= cmGlobalVisualStudioGenerator::VSVersion::VS16 &&
!cmSystemTools::VersionCompareGreater(this->SystemVersion, "8.1")) {
this->SetWindowsTargetPlatformVersion("8.1", mf);
return true;
@@ -894,7 +894,7 @@ std::string cmGlobalVisualStudioVersionedGenerator::FindMSBuildCommand()
// Ask Visual Studio Installer tool.
std::string vs;
if (vsSetupAPIHelper.GetVSInstanceInfo(vs)) {
- if (this->Version >= cmGlobalVisualStudioGenerator::VS17) {
+ if (this->Version >= cmGlobalVisualStudioGenerator::VSVersion::VS17) {
msbuild = vs + "/MSBuild/Current/Bin/amd64/MSBuild.exe";
if (cmSystemTools::FileExists(msbuild)) {
return msbuild;
diff --git a/Source/cmGlobalWatcomWMakeGenerator.cxx b/Source/cmGlobalWatcomWMakeGenerator.cxx
index 3e2d92d..fb2a8b6 100644
--- a/Source/cmGlobalWatcomWMakeGenerator.cxx
+++ b/Source/cmGlobalWatcomWMakeGenerator.cxx
@@ -65,12 +65,13 @@ std::vector<cmGlobalGenerator::GeneratedMakeCommand>
cmGlobalWatcomWMakeGenerator::GenerateBuildCommand(
const std::string& makeProgram, const std::string& projectName,
const std::string& projectDir, std::vector<std::string> const& targetNames,
- const std::string& config, bool fast, int /*jobs*/, bool verbose,
+ const std::string& config, int /*jobs*/, bool verbose,
+ const cmBuildOptions& buildOptions,
std::vector<std::string> const& makeOptions)
{
return this->cmGlobalUnixMakefileGenerator3::GenerateBuildCommand(
- makeProgram, projectName, projectDir, targetNames, config, fast,
- cmake::NO_BUILD_PARALLEL_LEVEL, verbose, makeOptions);
+ makeProgram, projectName, projectDir, targetNames, config,
+ cmake::NO_BUILD_PARALLEL_LEVEL, verbose, buildOptions, makeOptions);
}
void cmGlobalWatcomWMakeGenerator::PrintBuildCommandAdvice(std::ostream& os,
diff --git a/Source/cmGlobalWatcomWMakeGenerator.h b/Source/cmGlobalWatcomWMakeGenerator.h
index da39d3f..eb93934 100644
--- a/Source/cmGlobalWatcomWMakeGenerator.h
+++ b/Source/cmGlobalWatcomWMakeGenerator.h
@@ -9,6 +9,7 @@
#include <string>
#include <vector>
+#include "cmBuildOptions.h"
#include "cmGlobalGeneratorFactory.h"
#include "cmGlobalUnixMakefileGenerator3.h"
@@ -57,7 +58,8 @@ protected:
std::vector<GeneratedMakeCommand> GenerateBuildCommand(
const std::string& makeProgram, const std::string& projectName,
const std::string& projectDir, std::vector<std::string> const& targetNames,
- const std::string& config, bool fast, int jobs, bool verbose,
+ const std::string& config, int jobs, bool verbose,
+ const cmBuildOptions& buildOptions = cmBuildOptions(),
std::vector<std::string> const& makeOptions =
std::vector<std::string>()) override;
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index bc2a6f7..203addd 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -478,7 +478,7 @@ cmGlobalXCodeGenerator::GenerateBuildCommand(
const std::string& makeProgram, const std::string& projectName,
const std::string& /*projectDir*/,
std::vector<std::string> const& targetNames, const std::string& config,
- bool /*fast*/, int jobs, bool /*verbose*/,
+ int jobs, bool /*verbose*/, const cmBuildOptions& /*buildOptions*/,
std::vector<std::string> const& makeOptions)
{
GeneratedMakeCommand makeCommand;
diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h
index 5917db3..ff6ffe8 100644
--- a/Source/cmGlobalXCodeGenerator.h
+++ b/Source/cmGlobalXCodeGenerator.h
@@ -80,7 +80,8 @@ public:
std::vector<GeneratedMakeCommand> GenerateBuildCommand(
const std::string& makeProgram, const std::string& projectName,
const std::string& projectDir, std::vector<std::string> const& targetNames,
- const std::string& config, bool fast, int jobs, bool verbose,
+ const std::string& config, int jobs, bool verbose,
+ const cmBuildOptions& buildOptions = cmBuildOptions(),
std::vector<std::string> const& makeOptions =
std::vector<std::string>()) override;
diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx
index 9f8a18f..3da266d 100644
--- a/Source/cmListFileCache.cxx
+++ b/Source/cmListFileCache.cxx
@@ -369,68 +369,68 @@ cm::optional<cmListFileContext> cmListFileParser::CheckNesting() const
if (name == "if") {
stack.push_back({
NestingStateEnum::If,
- cmListFileContext::FromCommandContext(func, this->FileName),
+ cmListFileContext::FromListFileFunction(func, this->FileName),
});
} else if (name == "elseif") {
if (!TopIs(stack, NestingStateEnum::If)) {
- return cmListFileContext::FromCommandContext(func, this->FileName);
+ return cmListFileContext::FromListFileFunction(func, this->FileName);
}
stack.back() = {
NestingStateEnum::If,
- cmListFileContext::FromCommandContext(func, this->FileName),
+ cmListFileContext::FromListFileFunction(func, this->FileName),
};
} else if (name == "else") {
if (!TopIs(stack, NestingStateEnum::If)) {
- return cmListFileContext::FromCommandContext(func, this->FileName);
+ return cmListFileContext::FromListFileFunction(func, this->FileName);
}
stack.back() = {
NestingStateEnum::Else,
- cmListFileContext::FromCommandContext(func, this->FileName),
+ cmListFileContext::FromListFileFunction(func, this->FileName),
};
} else if (name == "endif") {
if (!TopIs(stack, NestingStateEnum::If) &&
!TopIs(stack, NestingStateEnum::Else)) {
- return cmListFileContext::FromCommandContext(func, this->FileName);
+ return cmListFileContext::FromListFileFunction(func, this->FileName);
}
stack.pop_back();
} else if (name == "while") {
stack.push_back({
NestingStateEnum::While,
- cmListFileContext::FromCommandContext(func, this->FileName),
+ cmListFileContext::FromListFileFunction(func, this->FileName),
});
} else if (name == "endwhile") {
if (!TopIs(stack, NestingStateEnum::While)) {
- return cmListFileContext::FromCommandContext(func, this->FileName);
+ return cmListFileContext::FromListFileFunction(func, this->FileName);
}
stack.pop_back();
} else if (name == "foreach") {
stack.push_back({
NestingStateEnum::Foreach,
- cmListFileContext::FromCommandContext(func, this->FileName),
+ cmListFileContext::FromListFileFunction(func, this->FileName),
});
} else if (name == "endforeach") {
if (!TopIs(stack, NestingStateEnum::Foreach)) {
- return cmListFileContext::FromCommandContext(func, this->FileName);
+ return cmListFileContext::FromListFileFunction(func, this->FileName);
}
stack.pop_back();
} else if (name == "function") {
stack.push_back({
NestingStateEnum::Function,
- cmListFileContext::FromCommandContext(func, this->FileName),
+ cmListFileContext::FromListFileFunction(func, this->FileName),
});
} else if (name == "endfunction") {
if (!TopIs(stack, NestingStateEnum::Function)) {
- return cmListFileContext::FromCommandContext(func, this->FileName);
+ return cmListFileContext::FromListFileFunction(func, this->FileName);
}
stack.pop_back();
} else if (name == "macro") {
stack.push_back({
NestingStateEnum::Macro,
- cmListFileContext::FromCommandContext(func, this->FileName),
+ cmListFileContext::FromListFileFunction(func, this->FileName),
});
} else if (name == "endmacro") {
if (!TopIs(stack, NestingStateEnum::Macro)) {
- return cmListFileContext::FromCommandContext(func, this->FileName);
+ return cmListFileContext::FromListFileFunction(func, this->FileName);
}
stack.pop_back();
}
diff --git a/Source/cmListFileCache.h b/Source/cmListFileCache.h
index 4a52876..5d45027 100644
--- a/Source/cmListFileCache.h
+++ b/Source/cmListFileCache.h
@@ -23,28 +23,6 @@
class cmMessenger;
-struct cmCommandContext
-{
- struct cmCommandName
- {
- std::string Original;
- std::string Lower;
- cmCommandName() = default;
- cmCommandName(std::string name)
- : Original(std::move(name))
- , Lower(cmSystemTools::LowerCase(this->Original))
- {
- }
- } Name;
- long Line = 0;
- cmCommandContext() = default;
- cmCommandContext(std::string name, long line)
- : Name(std::move(name))
- , Line(line)
- {
- }
-};
-
struct cmListFileArgument
{
enum Delimiter
@@ -70,6 +48,54 @@ struct cmListFileArgument
long Line = 0;
};
+class cmListFileFunction
+{
+public:
+ cmListFileFunction(std::string name, long line,
+ std::vector<cmListFileArgument> args)
+ : Impl{ std::make_shared<Implementation>(std::move(name), line,
+ std::move(args)) }
+ {
+ }
+
+ std::string const& OriginalName() const noexcept
+ {
+ return this->Impl->OriginalName;
+ }
+
+ std::string const& LowerCaseName() const noexcept
+ {
+ return this->Impl->LowerCaseName;
+ }
+
+ long Line() const noexcept { return this->Impl->Line; }
+
+ std::vector<cmListFileArgument> const& Arguments() const noexcept
+ {
+ return this->Impl->Arguments;
+ }
+
+private:
+ struct Implementation
+ {
+ Implementation(std::string name, long line,
+ std::vector<cmListFileArgument> args)
+ : OriginalName{ std::move(name) }
+ , LowerCaseName{ cmSystemTools::LowerCase(this->OriginalName) }
+ , Line{ line }
+ , Arguments{ std::move(args) }
+ {
+ }
+
+ std::string OriginalName;
+ std::string LowerCaseName;
+ long Line = 0;
+ std::vector<cmListFileArgument> Arguments;
+ };
+
+ std::shared_ptr<Implementation const> Impl;
+};
+
class cmListFileContext
{
public:
@@ -99,14 +125,14 @@ public:
{
}
- static cmListFileContext FromCommandContext(
- cmCommandContext const& lfcc, std::string const& fileName,
+ static cmListFileContext FromListFileFunction(
+ cmListFileFunction const& lff, std::string const& fileName,
cm::optional<std::string> deferId = {})
{
cmListFileContext lfc;
lfc.FilePath = fileName;
- lfc.Line = lfcc.Line;
- lfc.Name = lfcc.Name.Original;
+ lfc.Line = lff.Line();
+ lfc.Name = lff.OriginalName();
lfc.DeferId = std::move(deferId);
return lfc;
}
@@ -117,50 +143,6 @@ bool operator<(const cmListFileContext& lhs, const cmListFileContext& rhs);
bool operator==(cmListFileContext const& lhs, cmListFileContext const& rhs);
bool operator!=(cmListFileContext const& lhs, cmListFileContext const& rhs);
-class cmListFileFunction
-{
-public:
- cmListFileFunction(std::string name, long line,
- std::vector<cmListFileArgument> args)
- : Impl{ std::make_shared<Implementation>(std::move(name), line,
- std::move(args)) }
- {
- }
-
- std::string const& OriginalName() const noexcept
- {
- return this->Impl->Name.Original;
- }
-
- std::string const& LowerCaseName() const noexcept
- {
- return this->Impl->Name.Lower;
- }
-
- long Line() const noexcept { return this->Impl->Line; }
-
- std::vector<cmListFileArgument> const& Arguments() const noexcept
- {
- return this->Impl->Arguments;
- }
-
- operator cmCommandContext const&() const noexcept { return *this->Impl; }
-
-private:
- struct Implementation : public cmCommandContext
- {
- Implementation(std::string name, long line,
- std::vector<cmListFileArgument> args)
- : cmCommandContext{ std::move(name), line }
- , Arguments{ std::move(args) }
- {
- }
- std::vector<cmListFileArgument> Arguments;
- };
-
- std::shared_ptr<Implementation const> Impl;
-};
-
// Represent a backtrace (call stack). Provide value semantics
// but use efficient reference-counting underneath to avoid copies.
class cmListFileBacktrace
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 77439d1..2adb232 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -3435,21 +3435,27 @@ void cmLocalGenerator::GenerateTargetInstallRules(
static bool cmLocalGeneratorShortenObjectName(std::string& objName,
std::string::size_type max_len)
{
+ // Check if the path can be shortened using an md5 sum replacement for
+ // a portion of the path.
+ std::string::size_type md5Len = 32;
+ std::string::size_type numExtraChars = objName.size() - max_len + md5Len;
+ std::string::size_type pos = objName.find('/', numExtraChars);
+ if (pos == std::string::npos) {
+ pos = objName.rfind('/', numExtraChars);
+ if (pos == std::string::npos || pos <= md5Len) {
+ return false;
+ }
+ }
+
// Replace the beginning of the path portion of the object name with
// its own md5 sum.
- std::string::size_type pos =
- objName.find('/', objName.size() - max_len + 32);
- if (pos != std::string::npos) {
- cmCryptoHash md5(cmCryptoHash::AlgoMD5);
- std::string md5name = cmStrCat(md5.HashString(objName.substr(0, pos)),
- cm::string_view(objName).substr(pos));
- objName = md5name;
+ cmCryptoHash md5(cmCryptoHash::AlgoMD5);
+ std::string md5name = cmStrCat(md5.HashString(objName.substr(0, pos)),
+ cm::string_view(objName).substr(pos));
+ objName = md5name;
- // The object name is now short enough.
- return true;
- }
- // The object name could not be shortened enough.
- return false;
+ // The object name is now shorter, check if it is short enough.
+ return pos >= numExtraChars;
}
bool cmLocalGeneratorCheckObjectName(std::string& objName,
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index 2700ded..0f8cdca 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -1274,7 +1274,7 @@ std::string cmLocalUnixMakefileGenerator3::CreateMakeVariable(
cmSystemTools::ReplaceString(ret, "-", "__");
cmSystemTools::ReplaceString(ret, "+", "___");
int ni = 0;
- char buffer[5];
+ char buffer[12];
// make sure the _ version is not already used, if
// it is used then add number to the end of the variable
while (this->ShortMakeVariableMap.count(ret) && ni < 1000) {
@@ -1302,7 +1302,7 @@ std::string cmLocalUnixMakefileGenerator3::CreateMakeVariable(
if (static_cast<int>(str1.size()) + static_cast<int>(str2.size()) > size) {
str1 = str1.substr(0, size - str2.size());
}
- char buffer[5];
+ char buffer[12];
int ni = 0;
snprintf(buffer, sizeof(buffer), "%04d", ni);
ret = str1 + str2 + buffer;
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index 4bf8df6..ed7e888 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -198,8 +198,8 @@ void cmLocalVisualStudio7Generator::GenerateTarget(cmGeneratorTarget* target)
// Intel Fortran for VS10 uses VS9 format ".vfproj" files.
cmGlobalVisualStudioGenerator::VSVersion realVersion = gg->GetVersion();
if (this->FortranProject &&
- gg->GetVersion() >= cmGlobalVisualStudioGenerator::VS10) {
- gg->SetVersion(cmGlobalVisualStudioGenerator::VS9);
+ gg->GetVersion() >= cmGlobalVisualStudioGenerator::VSVersion::VS10) {
+ gg->SetVersion(cmGlobalVisualStudioGenerator::VSVersion::VS9);
}
// add to the list of projects
@@ -1106,7 +1106,8 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
fout << "\t\t\t\tGenerateDebugInformation=\"true\"\n";
}
if (this->WindowsCEProject) {
- if (this->GetVersion() < cmGlobalVisualStudioGenerator::VS9) {
+ if (this->GetVersion() <
+ cmGlobalVisualStudioGenerator::VSVersion::VS9) {
fout << "\t\t\t\tSubSystem=\"9\"\n";
} else {
fout << "\t\t\t\tSubSystem=\"8\"\n";
@@ -1183,7 +1184,8 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
fout << "\t\t\t\tGenerateDebugInformation=\"true\"\n";
}
if (this->WindowsCEProject) {
- if (this->GetVersion() < cmGlobalVisualStudioGenerator::VS9) {
+ if (this->GetVersion() <
+ cmGlobalVisualStudioGenerator::VSVersion::VS9) {
fout << "\t\t\t\tSubSystem=\"9\"\n";
} else {
fout << "\t\t\t\tSubSystem=\"8\"\n";
@@ -2026,7 +2028,8 @@ void cmLocalVisualStudio7Generator::WriteProjectStart(
<< "<VisualStudioProject\n"
<< "\tProjectType=\"Visual C++\"\n";
/* clang-format on */
- fout << "\tVersion=\"" << (gg->GetVersion() / 10) << ".00\"\n";
+ fout << "\tVersion=\"" << (static_cast<uint16_t>(gg->GetVersion()) / 10)
+ << ".00\"\n";
cmValue p = target->GetProperty("PROJECT_LABEL");
const std::string projLabel = p ? *p : libName;
p = target->GetProperty("VS_KEYWORD");
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index cc687b1..68e61bb 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -339,7 +339,7 @@ public:
cm::optional<std::string> deferId, cmExecutionStatus& status)
: Makefile(mf)
{
- cmListFileContext const& lfc = cmListFileContext::FromCommandContext(
+ cmListFileContext const& lfc = cmListFileContext::FromListFileFunction(
lff, this->Makefile->StateSnapshot.GetExecutionListFile(),
std::move(deferId));
this->Makefile->Backtrace = this->Makefile->Backtrace.Push(lfc);
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 5d306ec..1c92c7f 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -16,6 +16,8 @@
#include <cmext/algorithm>
#include <cmext/string_view>
+#include "cm_codecvt.hxx"
+
#include "cmComputeLinkInformation.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandGenerator.h"
@@ -2077,11 +2079,22 @@ std::string cmMakefileTargetGenerator::CreateResponseFile(
const char* name, std::string const& options,
std::vector<std::string>& makefile_depends)
{
+ // FIXME: Find a better way to determine the response file encoding,
+ // perhaps using tool-specific platform information variables.
+ // For now, use the makefile encoding as a heuristic.
+ codecvt::Encoding responseEncoding =
+ this->GlobalGenerator->GetMakefileEncoding();
+ // Non-MSVC tooling may not understand a BOM.
+ if (responseEncoding == codecvt::UTF8_WITH_BOM &&
+ !this->Makefile->IsOn("MSVC")) {
+ responseEncoding = codecvt::UTF8;
+ }
+
// Create the response file.
std::string responseFileNameFull =
cmStrCat(this->TargetBuildDirectoryFull, '/', name);
- cmGeneratedFileStream responseStream(
- responseFileNameFull, false, this->GlobalGenerator->GetMakefileEncoding());
+ cmGeneratedFileStream responseStream(responseFileNameFull, false,
+ responseEncoding);
responseStream.SetCopyIfDifferent(true);
responseStream << options << "\n";
diff --git a/Source/cmOutputConverter.cxx b/Source/cmOutputConverter.cxx
index 4503038..b143170 100644
--- a/Source/cmOutputConverter.cxx
+++ b/Source/cmOutputConverter.cxx
@@ -8,6 +8,11 @@
#include <set>
#include <vector>
+#ifdef _WIN32
+# include <unordered_map>
+# include <utility>
+#endif
+
#include "cmState.h"
#include "cmStateDirectory.h"
#include "cmStringAlgorithms.h"
@@ -117,17 +122,34 @@ std::string cmOutputConverter::MaybeRelativeToCurBinDir(
std::string cmOutputConverter::ConvertToOutputForExisting(
const std::string& remote, OutputFormat format) const
{
+#ifdef _WIN32
+ // Cache the Short Paths since we only convert the same few paths anyway and
+ // calling `GetShortPathNameW` is really expensive.
+ static std::unordered_map<std::string, std::string> shortPathCache{};
+
// If this is a windows shell, the result has a space, and the path
// already exists, we can use a short-path to reference it without a
// space.
if (this->GetState()->UseWindowsShell() &&
remote.find_first_of(" #") != std::string::npos &&
cmSystemTools::FileExists(remote)) {
- std::string tmp;
- if (cmSystemTools::GetShortPath(remote, tmp)) {
- return this->ConvertToOutputFormat(tmp, format);
- }
+
+ std::string shortPath = [&]() {
+ auto cachedShortPathIt = shortPathCache.find(remote);
+
+ if (cachedShortPathIt != shortPathCache.end()) {
+ return cachedShortPathIt->second;
+ }
+
+ std::string tmp{};
+ cmSystemTools::GetShortPath(remote, tmp);
+ shortPathCache[remote] = tmp;
+ return tmp;
+ }();
+
+ return this->ConvertToOutputFormat(shortPath, format);
}
+#endif
// Otherwise, perform standard conversion.
return this->ConvertToOutputFormat(remote, format);
diff --git a/Source/cmStandardLevelResolver.cxx b/Source/cmStandardLevelResolver.cxx
index c027e29..785f356 100644
--- a/Source/cmStandardLevelResolver.cxx
+++ b/Source/cmStandardLevelResolver.cxx
@@ -210,8 +210,9 @@ struct StandardLevelComputer
// If the standard requested is older than the compiler's default or the
// extension mode doesn't match then we need to use a flag.
- if (stdIt < defaultStdIt ||
- (cmp0128 == cmPolicies::NEW && ext != defaultExt)) {
+ if ((cmp0128 != cmPolicies::NEW && stdIt <= defaultStdIt) ||
+ (cmp0128 == cmPolicies::NEW &&
+ (stdIt < defaultStdIt || ext != defaultExt))) {
auto offset = std::distance(cm::cbegin(stds), stdIt);
return cmStrCat("CMAKE_", this->Language, stdsStrings[offset], "_", type,
"_COMPILE_OPTION");
diff --git a/Source/cmStandardLexer.h b/Source/cmStandardLexer.h
index 417f14d..2722528 100644
--- a/Source/cmStandardLexer.h
+++ b/Source/cmStandardLexer.h
@@ -50,6 +50,10 @@
# endif
#endif
+#if defined(__LCC__)
+# pragma diag_suppress 1873 /* comparison between signed and unsigned */
+#endif
+
#if defined(__NVCOMPILER)
# pragma diag_suppress 111 /* statement is unreachable */
# pragma diag_suppress 550 /* variable set but never used */
diff --git a/Source/cmTimestamp.cxx b/Source/cmTimestamp.cxx
index 3826577..e2b6c20 100644
--- a/Source/cmTimestamp.cxx
+++ b/Source/cmTimestamp.cxx
@@ -17,18 +17,27 @@
#include <cstdlib>
#include <cstring>
#include <sstream>
+#include <utility>
#ifdef __MINGW32__
# include <libloaderapi.h>
#endif
+#include <cm3p/uv.h>
+
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
std::string cmTimestamp::CurrentTime(const std::string& formatString,
bool utcFlag) const
{
- time_t currentTimeT = time(nullptr);
+ // get current time with microsecond resolution
+ uv_timeval64_t timeval;
+ uv_gettimeofday(&timeval);
+ auto currentTimeT = static_cast<time_t>(timeval.tv_sec);
+ auto microseconds = static_cast<uint32_t>(timeval.tv_usec);
+
+ // check for override via SOURCE_DATE_EPOCH for reproducible builds
std::string source_date_epoch;
cmSystemTools::GetEnv("SOURCE_DATE_EPOCH", source_date_epoch);
if (!source_date_epoch.empty()) {
@@ -38,12 +47,15 @@ std::string cmTimestamp::CurrentTime(const std::string& formatString,
cmSystemTools::Error("Cannot parse SOURCE_DATE_EPOCH as integer");
exit(27);
}
+ // SOURCE_DATE_EPOCH has only a resolution in the seconds range
+ microseconds = 0;
}
if (currentTimeT == time_t(-1)) {
return std::string();
}
- return this->CreateTimestampFromTimeT(currentTimeT, formatString, utcFlag);
+ return this->CreateTimestampFromTimeT(currentTimeT, microseconds,
+ formatString, utcFlag);
}
std::string cmTimestamp::FileModificationTime(const char* path,
@@ -57,11 +69,32 @@ std::string cmTimestamp::FileModificationTime(const char* path,
return std::string();
}
- time_t mtime = cmsys::SystemTools::ModifiedTime(real_path);
- return this->CreateTimestampFromTimeT(mtime, formatString, utcFlag);
+ // use libuv's implementation of stat(2) to get the file information
+ time_t mtime = 0;
+ uint32_t microseconds = 0;
+ uv_fs_t req;
+ if (uv_fs_stat(nullptr, &req, real_path.c_str(), nullptr) == 0) {
+ mtime = static_cast<time_t>(req.statbuf.st_mtim.tv_sec);
+ // tv_nsec has nanosecond resolution, but we truncate it to microsecond
+ // resolution in order to be consistent with cmTimestamp::CurrentTime()
+ microseconds = static_cast<uint32_t>(req.statbuf.st_mtim.tv_nsec / 1000);
+ }
+ uv_fs_req_cleanup(&req);
+
+ return this->CreateTimestampFromTimeT(mtime, microseconds, formatString,
+ utcFlag);
+}
+
+std::string cmTimestamp::CreateTimestampFromTimeT(time_t timeT,
+ std::string formatString,
+ bool utcFlag) const
+{
+ return this->CreateTimestampFromTimeT(timeT, 0, std::move(formatString),
+ utcFlag);
}
std::string cmTimestamp::CreateTimestampFromTimeT(time_t timeT,
+ const uint32_t microseconds,
std::string formatString,
bool utcFlag) const
{
@@ -95,7 +128,8 @@ std::string cmTimestamp::CreateTimestampFromTimeT(time_t timeT,
: static_cast<char>(0);
if (c1 == '%' && c2 != 0) {
- result += this->AddTimestampComponent(c2, timeStruct, timeT);
+ result +=
+ this->AddTimestampComponent(c2, timeStruct, timeT, microseconds);
++i;
} else {
result += c1;
@@ -144,9 +178,9 @@ time_t cmTimestamp::CreateUtcTimeTFromTm(struct tm& tm) const
#endif
}
-std::string cmTimestamp::AddTimestampComponent(char flag,
- struct tm& timeStruct,
- const time_t timeT) const
+std::string cmTimestamp::AddTimestampComponent(
+ char flag, struct tm& timeStruct, const time_t timeT,
+ const uint32_t microseconds) const
{
std::string formatString = cmStrCat('%', flag);
@@ -180,13 +214,19 @@ std::string cmTimestamp::AddTimestampComponent(char flag,
const time_t unixEpoch = this->CreateUtcTimeTFromTm(tmUnixEpoch);
if (unixEpoch == -1) {
cmSystemTools::Error(
- "Error generating UNIX epoch in "
- "STRING(TIMESTAMP ...). Please, file a bug report against CMake");
+ "Error generating UNIX epoch in string(TIMESTAMP ...) or "
+ "file(TIMESTAMP ...). Please, file a bug report against CMake");
return std::string();
}
return std::to_string(static_cast<long int>(difftime(timeT, unixEpoch)));
}
+ case 'f': // microseconds
+ {
+ // clip number to 6 digits and pad with leading zeros
+ std::string microsecs = std::to_string(microseconds % 1000000);
+ return std::string(6 - microsecs.length(), '0') + microsecs;
+ }
default: {
return formatString;
}
diff --git a/Source/cmTimestamp.h b/Source/cmTimestamp.h
index 0e2c200..ada5006 100644
--- a/Source/cmTimestamp.h
+++ b/Source/cmTimestamp.h
@@ -4,6 +4,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <cstdint>
#include <ctime>
#include <string>
@@ -23,9 +24,14 @@ public:
std::string CreateTimestampFromTimeT(time_t timeT, std::string formatString,
bool utcFlag) const;
+ std::string CreateTimestampFromTimeT(time_t timeT, uint32_t microseconds,
+ std::string formatString,
+ bool utcFlag) const;
+
private:
time_t CreateUtcTimeTFromTm(struct tm& timeStruct) const;
std::string AddTimestampComponent(char flag, struct tm& timeStruct,
- time_t timeT) const;
+ time_t timeT,
+ uint32_t microseconds = 0) const;
};
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 96dcf0b..f325994 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -419,7 +419,7 @@ void cmVisualStudio10TargetGenerator::Generate()
if (this->ProjectType == VsProjectType::csproj &&
this->GeneratorTarget->IsDotNetSdkTarget() &&
this->GlobalGenerator->GetVersion() >=
- cmGlobalVisualStudioGenerator::VS16) {
+ cmGlobalVisualStudioGenerator::VSVersion::VS16) {
this->WriteSdkStyleProjectFile(BuildFileStream);
} else {
this->WriteClassicMsBuildProjectFile(BuildFileStream);
@@ -431,6 +431,9 @@ void cmVisualStudio10TargetGenerator::Generate()
// The groups are stored in a separate file for VS 10
this->WriteGroups();
+
+ // Update cache with project-specific entries.
+ this->UpdateCache();
}
void cmVisualStudio10TargetGenerator::WriteClassicMsBuildProjectFile(
@@ -443,7 +446,7 @@ void cmVisualStudio10TargetGenerator::WriteClassicMsBuildProjectFile(
e0.Attribute("DefaultTargets", "Build");
const char* toolsVersion = this->GlobalGenerator->GetToolsVersion();
if (this->GlobalGenerator->GetVersion() ==
- cmGlobalVisualStudioGenerator::VS12 &&
+ cmGlobalVisualStudioGenerator::VSVersion::VS12 &&
this->GlobalGenerator->TargetsWindowsCE()) {
toolsVersion = "4.0";
}
@@ -609,7 +612,7 @@ void cmVisualStudio10TargetGenerator::WriteClassicMsBuildProjectFile(
// project using an older toolset version is opened in a newer version of
// the IDE (respected by VS 2013 and above).
if (this->GlobalGenerator->GetVersion() >=
- cmGlobalVisualStudioGenerator::VS12) {
+ cmGlobalVisualStudioGenerator::VSVersion::VS12) {
e1.Element("VCProjectUpgraderObjectName", "NoUpgrade");
}
@@ -620,7 +623,7 @@ void cmVisualStudio10TargetGenerator::WriteClassicMsBuildProjectFile(
if (this->Managed) {
if (this->LocalGenerator->GetVersion() >=
- cmGlobalVisualStudioGenerator::VS17) {
+ cmGlobalVisualStudioGenerator::VSVersion::VS17) {
e1.Element("ManagedAssembly", "true");
}
std::string outputType;
@@ -1000,11 +1003,9 @@ bool cmVisualStudio10TargetGenerator::HasCustomCommands() const
void cmVisualStudio10TargetGenerator::WritePackageReferences(Elem& e0)
{
- std::vector<std::string> packageReferences;
- if (cmValue vsPackageReferences =
- this->GeneratorTarget->GetProperty("VS_PACKAGE_REFERENCES")) {
- cmExpandList(*vsPackageReferences, packageReferences);
- }
+ std::vector<std::string> packageReferences =
+ this->GeneratorTarget->GetPackageReferences();
+
if (!packageReferences.empty()) {
Elem e1(e0, "ItemGroup");
for (std::string const& ri : packageReferences) {
@@ -1750,13 +1751,13 @@ void cmVisualStudio10TargetGenerator::WriteCustomRuleCpp(
e2.WritePlatformConfigTag("AdditionalInputs", cond, additional_inputs);
e2.WritePlatformConfigTag("Outputs", cond, outputs);
if (this->LocalGenerator->GetVersion() >
- cmGlobalVisualStudioGenerator::VS10) {
+ cmGlobalVisualStudioGenerator::VSVersion::VS10) {
// VS >= 11 let us turn off linking of custom command outputs.
e2.WritePlatformConfigTag("LinkObjects", cond, "false");
}
if (symbolic &&
this->LocalGenerator->GetVersion() >=
- cmGlobalVisualStudioGenerator::VS16) {
+ cmGlobalVisualStudioGenerator::VSVersion::VS16) {
// VS >= 16.4 warn if outputs are not created, but one of our
// outputs is marked SYMBOLIC and not expected to be created.
e2.WritePlatformConfigTag("VerifyInputsAndOutputsExist", cond, "false");
@@ -2319,7 +2320,7 @@ void cmVisualStudio10TargetGenerator::WriteSource(Elem& e2,
bool forceRelative = sf->GetLanguage() == "CUDA";
std::string sourceFile = this->ConvertPath(sf->GetFullPath(), forceRelative);
if (this->LocalGenerator->GetVersion() ==
- cmGlobalVisualStudioGenerator::VS10 &&
+ cmGlobalVisualStudioGenerator::VSVersion::VS10 &&
cmSystemTools::FileIsFullPath(sourceFile)) {
// Normal path conversion resulted in a full path. VS 10 (but not 11)
// refuses to show the property page in the IDE for a source file with a
@@ -2417,7 +2418,7 @@ void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0)
case cmGeneratorTarget::SourceKindExternalObject:
tool = "Object";
if (this->LocalGenerator->GetVersion() <
- cmGlobalVisualStudioGenerator::VS11) {
+ cmGlobalVisualStudioGenerator::VSVersion::VS11) {
// For VS == 10 we cannot use LinkObjects to avoid linking custom
// command outputs. If an object file is generated in this target,
// then vs10 will use it in the build, and we have to list it as
@@ -3105,7 +3106,7 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
if (this->ProjectType == VsProjectType::vcxproj) {
clOptions.FixExceptionHandlingDefault();
if (this->GlobalGenerator->GetVersion() >=
- cmGlobalVisualStudioGenerator::VS15) {
+ cmGlobalVisualStudioGenerator::VSVersion::VS15) {
// Toolsets that come with VS 2017 may now enable UseFullPaths
// by default and there is no negative /FC option that projects
// can use to switch it back. Older toolsets disable this by
@@ -5375,3 +5376,32 @@ void cmVisualStudio10TargetGenerator::WriteStdOutEncodingUtf8(Elem& e1)
e1.Element("StdOutEncoding", "UTF-8");
}
}
+
+void cmVisualStudio10TargetGenerator::UpdateCache()
+{
+ std::vector<std::string> packageReferences;
+
+ if (this->GeneratorTarget->HasPackageReferences()) {
+ // Store a cache entry that later determines, if a package restore is
+ // required.
+ this->GeneratorTarget->Makefile->AddCacheDefinition(
+ this->GeneratorTarget->GetName() + "_REQUIRES_VS_PACKAGE_RESTORE", "ON",
+ "Value Computed by CMake", cmStateEnums::STATIC);
+ } else {
+ // If there are any dependencies that require package restore, inherit the
+ // cache variable.
+ cmGlobalGenerator::TargetDependSet const& unordered =
+ this->GlobalGenerator->GetTargetDirectDepends(this->GeneratorTarget);
+ using OrderedTargetDependSet =
+ cmGlobalVisualStudioGenerator::OrderedTargetDependSet;
+ OrderedTargetDependSet depends(unordered, CMAKE_CHECK_BUILD_SYSTEM_TARGET);
+
+ for (cmGeneratorTarget const* dt : depends) {
+ if (dt->HasPackageReferences()) {
+ this->GeneratorTarget->Makefile->AddCacheDefinition(
+ this->GeneratorTarget->GetName() + "_REQUIRES_VS_PACKAGE_RESTORE",
+ "ON", "Value Computed by CMake", cmStateEnums::STATIC);
+ }
+ }
+ }
+}
diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h
index 79aa5e8..8d777a3 100644
--- a/Source/cmVisualStudio10TargetGenerator.h
+++ b/Source/cmVisualStudio10TargetGenerator.h
@@ -198,6 +198,7 @@ private:
std::string GetCSharpSourceLink(cmSourceFile const* source);
void WriteStdOutEncodingUtf8(Elem& e1);
+ void UpdateCache();
private:
friend class cmVS10GeneratorOptions;
diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx
index e495db0..9045a4d 100644
--- a/Source/cmVisualStudioGeneratorOptions.cxx
+++ b/Source/cmVisualStudioGeneratorOptions.cxx
@@ -75,13 +75,13 @@ void cmVisualStudioGeneratorOptions::FixExceptionHandlingDefault()
// the flag to disable exception handling. When the user does
// remove the flag we need to override the IDE default of on.
switch (this->Version) {
- case cmGlobalVisualStudioGenerator::VS10:
- case cmGlobalVisualStudioGenerator::VS11:
- case cmGlobalVisualStudioGenerator::VS12:
- case cmGlobalVisualStudioGenerator::VS14:
- case cmGlobalVisualStudioGenerator::VS15:
- case cmGlobalVisualStudioGenerator::VS16:
- case cmGlobalVisualStudioGenerator::VS17:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS10:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS11:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS12:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS14:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS15:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS16:
+ case cmGlobalVisualStudioGenerator::VSVersion::VS17:
// by default VS puts <ExceptionHandling></ExceptionHandling> empty
// for a project, to make our projects look the same put a new line
// and space over for the closing </ExceptionHandling> as the default
@@ -108,7 +108,8 @@ void cmVisualStudioGeneratorOptions::SetVerboseMakefile(bool verbose)
if (verbose &&
this->FlagMap.find("SuppressStartupBanner") == this->FlagMap.end()) {
this->FlagMap["SuppressStartupBanner"] =
- this->Version < cmGlobalVisualStudioGenerator::VS10 ? "FALSE" : "";
+ this->Version < cmGlobalVisualStudioGenerator::VSVersion::VS10 ? "FALSE"
+ : "";
}
}
@@ -181,6 +182,10 @@ void cmVisualStudioGeneratorOptions::FixCudaCodeGeneration()
// First entries for the -arch=<arch> [-code=<code>,...] pair.
if (!arch.empty()) {
std::string arch_name = arch[0];
+ if (arch_name == "all" || arch_name == "all-major") {
+ AppendFlagString("AdditionalOptions", "-arch=" + arch_name);
+ return;
+ }
std::vector<std::string> codes;
if (!code.empty()) {
codes = cmTokenize(code[0], ",");
@@ -425,7 +430,7 @@ void cmVisualStudioGeneratorOptions::OutputPreprocessorDefinitions(
}
std::ostringstream oss;
- if (this->Version >= cmGlobalVisualStudioGenerator::VS10) {
+ if (this->Version >= cmGlobalVisualStudioGenerator::VSVersion::VS10) {
oss << "%(" << tag << ")";
}
std::vector<std::string>::const_iterator de =
@@ -433,13 +438,13 @@ void cmVisualStudioGeneratorOptions::OutputPreprocessorDefinitions(
for (std::string const& di : cmMakeRange(this->Defines.cbegin(), de)) {
// Escape the definition for the compiler.
std::string define;
- if (this->Version < cmGlobalVisualStudioGenerator::VS10) {
+ if (this->Version < cmGlobalVisualStudioGenerator::VSVersion::VS10) {
define = this->LocalGenerator->EscapeForShell(di, true);
} else {
define = di;
}
// Escape this flag for the MSBuild.
- if (this->Version >= cmGlobalVisualStudioGenerator::VS10) {
+ if (this->Version >= cmGlobalVisualStudioGenerator::VSVersion::VS10) {
cmVS10EscapeForMSBuild(define);
if (lang == "RC") {
cmSystemTools::ReplaceString(define, "\"", "\\\"");
@@ -481,7 +486,7 @@ void cmVisualStudioGeneratorOptions::OutputAdditionalIncludeDirectories(
}
// Escape this include for the MSBuild.
- if (this->Version >= cmGlobalVisualStudioGenerator::VS10) {
+ if (this->Version >= cmGlobalVisualStudioGenerator::VSVersion::VS10) {
cmVS10EscapeForMSBuild(include);
}
oss << sep << include;
@@ -493,7 +498,7 @@ void cmVisualStudioGeneratorOptions::OutputAdditionalIncludeDirectories(
}
}
- if (this->Version >= cmGlobalVisualStudioGenerator::VS10) {
+ if (this->Version >= cmGlobalVisualStudioGenerator::VSVersion::VS10) {
oss << sep << "%(" << tag << ")";
}
@@ -507,7 +512,7 @@ void cmVisualStudioGeneratorOptions::OutputFlagMap(std::ostream& fout,
std::ostringstream oss;
const char* sep = "";
for (std::string i : m.second) {
- if (this->Version >= cmGlobalVisualStudioGenerator::VS10) {
+ if (this->Version >= cmGlobalVisualStudioGenerator::VSVersion::VS10) {
cmVS10EscapeForMSBuild(i);
}
oss << sep << i;
diff --git a/Source/cm_utf8.c b/Source/cm_utf8.c
index 62e7e8c..b046aef 100644
--- a/Source/cm_utf8.c
+++ b/Source/cm_utf8.c
@@ -42,6 +42,11 @@ static unsigned int const cm_utf8_min[7] = {
const char* cm_utf8_decode_character(const char* first, const char* last,
unsigned int* pc)
{
+ /* We need at least one byte. */
+ if (first == last) {
+ return 0;
+ }
+
/* Count leading ones in the first byte. */
unsigned char c = (unsigned char)*first++;
unsigned char const ones = cm_utf8_ones[c];
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 72b26e1..ef4e37b 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -28,6 +28,7 @@
#include "cm_sys_stat.h"
+#include "cmBuildOptions.h"
#include "cmCMakePath.h"
#include "cmCMakePresetsGraph.h"
#include "cmCommandLineArgument.h"
@@ -3244,8 +3245,8 @@ std::vector<std::string> cmake::GetDebugConfigs()
int cmake::Build(int jobs, std::string dir, std::vector<std::string> targets,
std::string config, std::vector<std::string> nativeOptions,
- bool clean, bool verbose, const std::string& presetName,
- bool listPresets)
+ cmBuildOptions& buildOptions, bool verbose,
+ const std::string& presetName, bool listPresets)
{
this->SetHomeDirectory("");
this->SetHomeOutputDirectory("");
@@ -3351,8 +3352,12 @@ int cmake::Build(int jobs, std::string dir, std::vector<std::string> targets,
config = expandedPreset->Configuration;
}
- if (!clean && expandedPreset->CleanFirst) {
- clean = *expandedPreset->CleanFirst;
+ if (!buildOptions.Clean && expandedPreset->CleanFirst) {
+ buildOptions.Clean = *expandedPreset->CleanFirst;
+ }
+
+ if (expandedPreset->ResolvePackageReferences) {
+ buildOptions.ResolveMode = *expandedPreset->ResolvePackageReferences;
}
if (!verbose && expandedPreset->Verbose) {
@@ -3491,7 +3496,7 @@ int cmake::Build(int jobs, std::string dir, std::vector<std::string> targets,
this->GlobalGenerator->PrintBuildCommandAdvice(std::cerr, jobs);
return this->GlobalGenerator->Build(
- jobs, "", dir, projName, targets, output, "", config, clean, false,
+ jobs, "", dir, projName, targets, output, "", config, buildOptions,
verbose, cmDuration::zero(), cmSystemTools::OUTPUT_PASSTHROUGH,
nativeOptions);
}
diff --git a/Source/cmake.h b/Source/cmake.h
index aee9c04..1187be5 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -45,6 +45,7 @@ class cmMakefileProfilingData;
#endif
class cmMessenger;
class cmVariableWatch;
+struct cmBuildOptions;
struct cmDocumentationEntry;
/** \brief Represents a cmake invocation.
@@ -587,8 +588,8 @@ public:
//! run the --build option
int Build(int jobs, std::string dir, std::vector<std::string> targets,
std::string config, std::vector<std::string> nativeOptions,
- bool clean, bool verbose, const std::string& presetName,
- bool listPresets);
+ cmBuildOptions& buildOptions, bool verbose,
+ const std::string& presetName, bool listPresets);
//! run the --open option
bool Open(const std::string& dir, bool dryRun);
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index 00aafdc..f3d5536 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -5,6 +5,7 @@
#include <algorithm>
#include <cassert>
+#include <cctype>
#include <climits>
#include <cstdio>
#include <cstring>
@@ -19,6 +20,7 @@
#include <cm3p/uv.h>
+#include "cmBuildOptions.h"
#include "cmCommandLineArgument.h"
#include "cmConsoleBuf.h"
#include "cmDocumentationEntry.h" // IWYU pragma: keep
@@ -165,11 +167,11 @@ void cmakemainMessageCallback(const std::string& m,
// cannot use it to print messages. Another implementation will
// be needed to print colored messages on Windows.
static_cast<void>(md);
- std::cerr << m << cmakemainGetStack(cm) << "\n";
+ std::cerr << m << cmakemainGetStack(cm) << '\n' << std::flush;
#else
cmsysTerminal_cfprintf(md.desiredColor, stderr, "%s", m.c_str());
fflush(stderr); // stderr is buffered in some cases.
- std::cerr << cmakemainGetStack(cm) << "\n";
+ std::cerr << cmakemainGetStack(cm) << '\n' << std::flush;
#endif
}
@@ -445,6 +447,7 @@ int do_build(int ac, char const* const* av)
bool cleanFirst = false;
bool foundClean = false;
bool foundNonClean = false;
+ PackageResolveMode resolveMode = PackageResolveMode::FromCacheVariable;
bool verbose = cmSystemTools::HasEnv("VERBOSE");
std::string presetName;
bool listPresets = false;
@@ -478,6 +481,22 @@ int do_build(int ac, char const* const* av)
}
return false;
};
+ auto resolvePackagesLambda = [&](std::string const& value) -> bool {
+ std::string v = value;
+ std::transform(v.begin(), v.end(), v.begin(), ::tolower);
+
+ if (v == "on") {
+ resolveMode = PackageResolveMode::Force;
+ } else if (v == "only") {
+ resolveMode = PackageResolveMode::OnlyResolve;
+ } else if (v == "off") {
+ resolveMode = PackageResolveMode::Disable;
+ } else {
+ return false;
+ }
+
+ return true;
+ };
auto verboseLambda = [&](std::string const&) -> bool {
verbose = true;
return true;
@@ -514,6 +533,8 @@ int do_build(int ac, char const* const* av)
cleanFirst = true;
return true;
} },
+ CommandArgument{ "--resolve-package-references",
+ CommandArgument::Values::One, resolvePackagesLambda },
CommandArgument{ "-v", CommandArgument::Values::Zero, verboseLambda },
CommandArgument{ "--verbose", CommandArgument::Values::Zero,
verboseLambda },
@@ -639,6 +660,8 @@ int do_build(int ac, char const* const* av)
" --config <cfg> = For multi-configuration tools, choose <cfg>.\n"
" --clean-first = Build target 'clean' first, then build.\n"
" (To clean only, use --target 'clean'.)\n"
+ " --resolve-package-references={on|only|off}\n"
+ " = Restore/resolve package references during build.\n"
" --verbose, -v = Enable verbose output - if supported - including\n"
" the build commands to be executed. \n"
" -- = Pass remaining options to the native tool.\n"
@@ -656,8 +679,10 @@ int do_build(int ac, char const* const* av)
cmakemainProgressCallback(msg, prog, &cm);
});
+ cmBuildOptions buildOptions(cleanFirst, false, resolveMode);
+
return cm.Build(jobs, std::move(dir), std::move(targets), std::move(config),
- std::move(nativeOptions), cleanFirst, verbose, presetName,
+ std::move(nativeOptions), buildOptions, verbose, presetName,
listPresets);
#endif
}
diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt
index 7da5971..2253a83 100644
--- a/Source/kwsys/CMakeLists.txt
+++ b/Source/kwsys/CMakeLists.txt
@@ -192,6 +192,7 @@ endif()
if(KWSYS_USE_Directory)
set(KWSYS_USE_Encoding 1)
set(KWSYS_USE_Status 1)
+ set(KWSYS_USE_SystemTools 1)
endif()
if(KWSYS_USE_DynamicLoader)
set(KWSYS_USE_Encoding 1)
diff --git a/Source/kwsys/Directory.cxx b/Source/kwsys/Directory.cxx
index 6e31cbf..d520c14 100644
--- a/Source/kwsys/Directory.cxx
+++ b/Source/kwsys/Directory.cxx
@@ -7,6 +7,8 @@
#include KWSYS_HEADER(Encoding.hxx)
+#include KWSYS_HEADER(SystemTools.hxx)
+
// Work-around CMake dependency scanning limitation. This must
// duplicate the above list of headers.
#if 0
@@ -16,15 +18,48 @@
#endif
#include <string>
+#include <utility>
#include <vector>
+#if defined(_WIN32) && !defined(__CYGWIN__)
+# include <windows.h>
+
+# include <ctype.h>
+# include <fcntl.h>
+# include <io.h>
+# include <stdio.h>
+# include <stdlib.h>
+# include <string.h>
+# include <sys/stat.h>
+# include <sys/types.h>
+#endif
+
namespace KWSYS_NAMESPACE {
class DirectoryInternals
{
public:
+ struct FileData
+ {
+ std::string Name;
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ _wfinddata_t FindData;
+#endif
+ FileData(std::string name
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ ,
+ _wfinddata_t data
+#endif
+ )
+ : Name(std::move(name))
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ , FindData(std::move(data))
+#endif
+ {
+ }
+ };
// Array of Files
- std::vector<std::string> Files;
+ std::vector<FileData> Files;
// Path to Open'ed directory
std::string Path;
@@ -59,10 +94,45 @@ unsigned long Directory::GetNumberOfFiles() const
const char* Directory::GetFile(unsigned long dindex) const
{
- if (dindex >= this->Internal->Files.size()) {
- return nullptr;
+ return this->Internal->Files[dindex].Name.c_str();
+}
+
+std::string const& Directory::GetFileName(std::size_t i) const
+{
+ return this->Internal->Files[i].Name;
+}
+
+std::string Directory::GetFilePath(std::size_t i) const
+{
+ std::string abs = this->Internal->Path;
+ if (!abs.empty() && abs.back() != '/') {
+ abs += '/';
}
- return this->Internal->Files[dindex].c_str();
+ abs += this->Internal->Files[i].Name;
+ return abs;
+}
+
+bool Directory::FileIsDirectory(std::size_t i) const
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ _wfinddata_t const& data = this->Internal->Files[i].FindData;
+ return (data.attrib & FILE_ATTRIBUTE_DIRECTORY) != 0;
+#else
+ std::string const& path = this->GetFilePath(i);
+ return kwsys::SystemTools::FileIsDirectory(path);
+#endif
+}
+
+bool Directory::FileIsSymlink(std::size_t i) const
+{
+ std::string const& path = this->GetFilePath(i);
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ _wfinddata_t const& data = this->Internal->Files[i].FindData;
+ return kwsys::SystemTools::FileIsSymlinkWithAttr(
+ Encoding::ToWindowsExtendedPath(path), data.attrib);
+#else
+ return kwsys::SystemTools::FileIsSymlink(path);
+#endif
}
const char* Directory::GetPath() const
@@ -81,16 +151,6 @@ void Directory::Clear()
// First Windows platforms
#if defined(_WIN32) && !defined(__CYGWIN__)
-# include <windows.h>
-
-# include <ctype.h>
-# include <fcntl.h>
-# include <io.h>
-# include <stdio.h>
-# include <stdlib.h>
-# include <string.h>
-# include <sys/stat.h>
-# include <sys/types.h>
namespace KWSYS_NAMESPACE {
@@ -133,7 +193,7 @@ Status Directory::Load(std::string const& name, std::string* errorMessage)
// Loop through names
do {
- this->Internal->Files.push_back(Encoding::ToNarrow(data.name));
+ this->Internal->Files.emplace_back(Encoding::ToNarrow(data.name), data);
} while (_wfindnext(srchHandle, &data) != -1);
this->Internal->Path = name;
if (_findclose(srchHandle) == -1) {
diff --git a/Source/kwsys/Directory.hxx.in b/Source/kwsys/Directory.hxx.in
index d501116..9d0f462 100644
--- a/Source/kwsys/Directory.hxx.in
+++ b/Source/kwsys/Directory.hxx.in
@@ -6,6 +6,7 @@
#include <@KWSYS_NAMESPACE@/Configure.h>
#include <@KWSYS_NAMESPACE@/Status.hxx>
+#include <cstddef>
#include <string>
namespace @KWSYS_NAMESPACE@ {
@@ -55,6 +56,26 @@ public:
const char* GetFile(unsigned long) const;
/**
+ * Return the name of the file at the given 0-based index.
+ */
+ std::string const& GetFileName(std::size_t i) const;
+
+ /**
+ * Return the absolute path to the file at the given 0-based index.
+ */
+ std::string GetFilePath(std::size_t i) const;
+
+ /**
+ * Return whether the file at the given 0-based index is a directory.
+ */
+ bool FileIsDirectory(std::size_t i) const;
+
+ /**
+ * Return whether the file at the given 0-based index is a symlink.
+ */
+ bool FileIsSymlink(std::size_t i) const;
+
+ /**
* Return the path to Open'ed directory
*/
const char* GetPath() const;
diff --git a/Source/kwsys/Glob.cxx b/Source/kwsys/Glob.cxx
index c6d4b19..fa2c295 100644
--- a/Source/kwsys/Glob.cxx
+++ b/Source/kwsys/Glob.cxx
@@ -213,8 +213,8 @@ bool Glob::RecurseDirectory(std::string::size_type start,
fname = kwsys::SystemTools::LowerCase(fname);
#endif
- bool isDir = kwsys::SystemTools::FileIsDirectory(realname);
- bool isSymLink = kwsys::SystemTools::FileIsSymlink(realname);
+ bool isDir = d.FileIsDirectory(cc);
+ bool isSymLink = d.FileIsSymlink(cc);
if (isDir && (!isSymLink || this->RecurseThroughSymlinks)) {
if (isSymLink) {
diff --git a/Source/kwsys/ProcessUNIX.c b/Source/kwsys/ProcessUNIX.c
index 1963b27..19bf982 100644
--- a/Source/kwsys/ProcessUNIX.c
+++ b/Source/kwsys/ProcessUNIX.c
@@ -41,6 +41,12 @@ do.
/* Increase the file descriptor limit for select() before including
related system headers. (Default: 64) */
# define FD_SETSIZE 16384
+#elif defined(__APPLE__)
+/* Increase the file descriptor limit for select() before including
+ related system headers. (Default: 1024) */
+# define _DARWIN_UNLIMITED_SELECT
+# include <limits.h> /* OPEN_MAX */
+# define FD_SETSIZE OPEN_MAX
#endif
#include <assert.h> /* assert */
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index c339fd5..c38b456 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -2287,7 +2287,7 @@ bool SystemTools::FilesDiffer(const std::string& source,
if (statSource.nFileSizeHigh == 0 && statSource.nFileSizeLow == 0) {
return false;
}
- off_t nleft =
+ auto nleft =
((__int64)statSource.nFileSizeHigh << 32) + statSource.nFileSizeLow;
#else
@@ -3085,11 +3085,10 @@ bool SystemTools::FileIsExecutable(const std::string& name)
return !FileIsDirectory(name) && TestFileAccess(name, TEST_FILE_EXECUTE);
}
-bool SystemTools::FileIsSymlink(const std::string& name)
-{
#if defined(_WIN32)
- std::wstring path = Encoding::ToWindowsExtendedPath(name);
- DWORD attr = GetFileAttributesW(path.c_str());
+bool SystemTools::FileIsSymlinkWithAttr(const std::wstring& path,
+ unsigned long attr)
+{
if (attr != INVALID_FILE_ATTRIBUTES) {
if ((attr & FILE_ATTRIBUTE_REPARSE_POINT) != 0) {
// FILE_ATTRIBUTE_REPARSE_POINT means:
@@ -3118,9 +3117,17 @@ bool SystemTools::FileIsSymlink(const std::string& name)
(reparseTag == IO_REPARSE_TAG_MOUNT_POINT);
}
return false;
- } else {
- return false;
}
+
+ return false;
+}
+#endif
+
+bool SystemTools::FileIsSymlink(const std::string& name)
+{
+#if defined(_WIN32)
+ std::wstring path = Encoding::ToWindowsExtendedPath(name);
+ return FileIsSymlinkWithAttr(path, GetFileAttributesW(path.c_str()));
#else
struct stat fs;
if (lstat(name.c_str(), &fs) == 0) {
diff --git a/Source/kwsys/SystemTools.hxx.in b/Source/kwsys/SystemTools.hxx.in
index 6684695..acce015 100644
--- a/Source/kwsys/SystemTools.hxx.in
+++ b/Source/kwsys/SystemTools.hxx.in
@@ -688,6 +688,16 @@ public:
*/
static bool FileIsExecutable(const std::string& name);
+#if defined(_WIN32)
+ /**
+ * Return true if the file with FileAttributes `attr` is a symlink
+ * Only available on Windows. This avoids an expensive `GetFileAttributesW`
+ * call.
+ */
+ static bool FileIsSymlinkWithAttr(const std::wstring& path,
+ unsigned long attr);
+#endif
+
/**
* Return true if the file is a symlink
*/
diff --git a/Source/kwsys/testSystemTools.cxx b/Source/kwsys/testSystemTools.cxx
index e88a481..21d6f04 100644
--- a/Source/kwsys/testSystemTools.cxx
+++ b/Source/kwsys/testSystemTools.cxx
@@ -295,12 +295,15 @@ static bool CheckFileOperations()
// Reset umask
#ifdef __MSYS__
mode_t fullMask = S_IWRITE;
+ mode_t testPerm = S_IREAD;
#elif defined(_WIN32) && !defined(__CYGWIN__)
// NOTE: Windows doesn't support toggling _S_IREAD.
mode_t fullMask = _S_IWRITE;
+ mode_t testPerm = 0;
#else
// On a normal POSIX platform, we can toggle all permissions.
mode_t fullMask = S_IRWXU | S_IRWXG | S_IRWXO;
+ mode_t testPerm = S_IRUSR;
#endif
// Test file permissions without umask
@@ -311,7 +314,7 @@ static bool CheckFileOperations()
res = false;
}
- if (!kwsys::SystemTools::SetPermissions(testNewFile, 0)) {
+ if (!kwsys::SystemTools::SetPermissions(testNewFile, testPerm)) {
std::cerr << "Problem with SetPermissions (1) for: " << testNewFile
<< std::endl;
res = false;
@@ -323,10 +326,10 @@ static bool CheckFileOperations()
res = false;
}
- if ((thisPerm & fullMask) != 0) {
+ if ((thisPerm & fullMask) != testPerm) {
std::cerr << "SetPermissions failed to set permissions (1) for: "
<< testNewFile << ": actual = " << thisPerm
- << "; expected = " << 0 << std::endl;
+ << "; expected = " << testPerm << std::endl;
res = false;
}