summaryrefslogtreecommitdiffstats
path: root/Source/cmake.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmake.cxx')
-rw-r--r--Source/cmake.cxx326
1 files changed, 185 insertions, 141 deletions
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 013a87b..0d947a5 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -40,7 +40,6 @@
#include "cmCommands.h"
#include "cmDocumentation.h"
#include "cmDocumentationEntry.h"
-#include "cmDocumentationFormatter.h"
#include "cmDuration.h"
#include "cmExternalMakefileProjectGenerator.h"
#include "cmFileTimeCache.h"
@@ -71,6 +70,7 @@
# include <cm3p/curl/curl.h>
# include <cm3p/json/writer.h>
+# include "cmConfigureLog.h"
# include "cmFileAPI.h"
# include "cmGraphVizWriter.h"
# include "cmVariableWatch.h"
@@ -150,21 +150,136 @@ auto IgnoreAndTrueLambda = [](std::string const&, cmake*) -> bool {
using CommandArgument =
cmCommandLineArgument<bool(std::string const& value, cmake* state)>;
-} // namespace
-
-static bool cmakeCheckStampFile(const std::string& stampName);
-static bool cmakeCheckStampList(const std::string& stampList);
-
#ifndef CMAKE_BOOTSTRAP
-static void cmWarnUnusedCliWarning(const std::string& variable, int /*unused*/,
- void* ctx, const char* /*unused*/,
- const cmMakefile* /*unused*/)
+void cmWarnUnusedCliWarning(const std::string& variable, int /*unused*/,
+ void* ctx, const char* /*unused*/,
+ const cmMakefile* /*unused*/)
{
cmake* cm = reinterpret_cast<cmake*>(ctx);
cm->MarkCliAsUsed(variable);
}
#endif
+bool cmakeCheckStampFile(const std::string& stampName)
+{
+ // The stamp file does not exist. Use the stamp dependencies to
+ // determine whether it is really out of date. This works in
+ // conjunction with cmLocalVisualStudio7Generator to avoid
+ // repeatedly re-running CMake when the user rebuilds the entire
+ // solution.
+ std::string stampDepends = cmStrCat(stampName, ".depend");
+#if defined(_WIN32) || defined(__CYGWIN__)
+ cmsys::ifstream fin(stampDepends.c_str(), std::ios::in | std::ios::binary);
+#else
+ cmsys::ifstream fin(stampDepends.c_str());
+#endif
+ if (!fin) {
+ // The stamp dependencies file cannot be read. Just assume the
+ // build system is really out of date.
+ std::cout << "CMake is re-running because " << stampName
+ << " dependency file is missing.\n";
+ return false;
+ }
+
+ // Compare the stamp dependencies against the dependency file itself.
+ {
+ cmFileTimeCache ftc;
+ std::string dep;
+ while (cmSystemTools::GetLineFromStream(fin, dep)) {
+ int result;
+ if (!dep.empty() && dep[0] != '#' &&
+ (!ftc.Compare(stampDepends, dep, &result) || result < 0)) {
+ // The stamp depends file is older than this dependency. The
+ // build system is really out of date.
+ /* clang-format off */
+ std::cout << "CMake is re-running because " << stampName
+ << " is out-of-date.\n"
+ " the file '" << dep << "'\n"
+ " is newer than '" << stampDepends << "'\n"
+ " result='" << result << "'\n";
+ /* clang-format on */
+ return false;
+ }
+ }
+ }
+
+ // The build system is up to date. The stamp file has been removed
+ // by the VS IDE due to a "rebuild" request. Restore it atomically.
+ std::ostringstream stampTempStream;
+ stampTempStream << stampName << ".tmp" << cmSystemTools::RandomSeed();
+ std::string stampTemp = stampTempStream.str();
+ {
+ // TODO: Teach cmGeneratedFileStream to use a random temp file (with
+ // multiple tries in unlikely case of conflict) and use that here.
+ cmsys::ofstream stamp(stampTemp.c_str());
+ stamp << "# CMake generation timestamp file for this directory.\n";
+ }
+ std::string err;
+ if (cmSystemTools::RenameFile(stampTemp, stampName,
+ cmSystemTools::Replace::Yes, &err) ==
+ cmSystemTools::RenameResult::Success) {
+ // CMake does not need to re-run because the stamp file is up-to-date.
+ return true;
+ }
+ cmSystemTools::RemoveFile(stampTemp);
+ cmSystemTools::Error(
+ cmStrCat("Cannot restore timestamp \"", stampName, "\": ", err));
+ return false;
+}
+
+bool cmakeCheckStampList(const std::string& stampList)
+{
+ // If the stamp list does not exist CMake must rerun to generate it.
+ if (!cmSystemTools::FileExists(stampList)) {
+ std::cout << "CMake is re-running because generate.stamp.list "
+ "is missing.\n";
+ return false;
+ }
+ cmsys::ifstream fin(stampList.c_str());
+ if (!fin) {
+ std::cout << "CMake is re-running because generate.stamp.list "
+ "could not be read.\n";
+ return false;
+ }
+
+ // Check each stamp.
+ std::string stampName;
+ while (cmSystemTools::GetLineFromStream(fin, stampName)) {
+ if (!cmakeCheckStampFile(stampName)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+} // namespace
+
+cmDocumentationEntry cmake::CMAKE_STANDARD_OPTIONS_TABLE[18] = {
+ { "-S <path-to-source>", "Explicitly specify a source directory." },
+ { "-B <path-to-build>", "Explicitly specify a build directory." },
+ { "-C <initial-cache>", "Pre-load a script to populate the cache." },
+ { "-D <var>[:<type>]=<value>", "Create or update a cmake cache entry." },
+ { "-U <globbing_expr>", "Remove matching entries from CMake cache." },
+ { "-G <generator-name>", "Specify a build system generator." },
+ { "-T <toolset-name>", "Specify toolset name if supported by generator." },
+ { "-A <platform-name>", "Specify platform name if supported by generator." },
+ { "--toolchain <file>", "Specify toolchain file [CMAKE_TOOLCHAIN_FILE]." },
+ { "--install-prefix <directory>",
+ "Specify install directory [CMAKE_INSTALL_PREFIX]." },
+ { "-Wdev", "Enable developer warnings." },
+ { "-Wno-dev", "Suppress developer warnings." },
+ { "-Werror=dev", "Make developer warnings errors." },
+ { "-Wno-error=dev", "Make developer warnings not errors." },
+ { "-Wdeprecated", "Enable deprecation warnings." },
+ { "-Wno-deprecated", "Suppress deprecation warnings." },
+ { "-Werror=deprecated",
+ "Make deprecated macro and function warnings "
+ "errors." },
+ { "-Wno-error=deprecated",
+ "Make deprecated macro and function warnings "
+ "not errors." }
+};
+
cmake::cmake(Role role, cmState::Mode mode, cmState::ProjectKind projectKind)
: CMakeWorkingDirectory(cmSystemTools::GetCurrentWorkingDirectory())
, FileTimeCache(cm::make_unique<cmFileTimeCache>())
@@ -196,7 +311,7 @@ cmake::cmake(Role role, cmState::Mode mode, cmState::ProjectKind projectKind)
this->AddProjectCommands();
}
- if (mode == cmState::Project) {
+ if (mode == cmState::Project || mode == cmState::Help) {
this->LoadEnvironmentPresets();
}
@@ -1008,7 +1123,7 @@ void cmake::SetArgs(const std::vector<std::string>& args)
std::cout << "Running with debug output on for the 'find' commands "
"for package(s)";
for (auto const& v : find_pkgs) {
- std::cout << " " << v;
+ std::cout << ' ' << v;
state->SetDebugFindOutputPkgs(v);
}
std::cout << ".\n";
@@ -1021,7 +1136,7 @@ void cmake::SetArgs(const std::vector<std::string>& args)
std::vector<std::string> find_vars(cmTokenize(value, ","));
std::cout << "Running with debug output on for the variable(s)";
for (auto const& v : find_vars) {
- std::cout << " " << v;
+ std::cout << ' ' << v;
state->SetDebugFindOutputVars(v);
}
std::cout << ".\n";
@@ -1082,7 +1197,7 @@ void cmake::SetArgs(const std::vector<std::string>& args)
[](std::string const&, cmake* state) -> bool {
std::cout
<< "Not searching for unused variables given on the "
- << "command line.\n";
+ "command line.\n";
state->SetWarnUnusedCli(false);
return true;
} },
@@ -1090,7 +1205,7 @@ void cmake::SetArgs(const std::vector<std::string>& args)
"--check-system-vars", CommandArgument::Values::Zero,
[](std::string const&, cmake* state) -> bool {
std::cout << "Also check system files when warning about unused and "
- << "uninitialized variables.\n";
+ "uninitialized variables.\n";
state->SetCheckSystemVars(true);
return true;
} },
@@ -1098,7 +1213,7 @@ void cmake::SetArgs(const std::vector<std::string>& args)
"--compile-no-warning-as-error", CommandArgument::Values::Zero,
[](std::string const&, cmake* state) -> bool {
std::cout << "Ignoring COMPILE_WARNING_AS_ERROR target property and "
- << "CMAKE_COMPILE_WARNING_AS_ERROR variable.\n";
+ "CMAKE_COMPILE_WARNING_AS_ERROR variable.\n";
state->SetIgnoreWarningAsError(true);
return true;
} }
@@ -1497,7 +1612,7 @@ void cmake::SetTraceFile(const std::string& file)
cmSystemTools::Error(ss.str());
return;
}
- std::cout << "Trace will be written to " << file << "\n";
+ std::cout << "Trace will be written to " << file << '\n';
}
void cmake::PrintTraceFormatVersion()
@@ -1542,6 +1657,16 @@ void cmake::PrintTraceFormatVersion()
}
}
+void cmake::SetTraceRedirect(cmake* other)
+{
+ this->Trace = other->Trace;
+ this->TraceExpand = other->TraceExpand;
+ this->TraceFormatVar = other->TraceFormatVar;
+ this->TraceOnlyThisSources = other->TraceOnlyThisSources;
+
+ this->TraceRedirect = other;
+}
+
bool cmake::SetDirectoriesFromFile(const std::string& arg)
{
// Check if the argument refers to a CMakeCache.txt or
@@ -2010,12 +2135,10 @@ int cmake::HandleDeleteCacheVariables(const std::string& var)
}
std::vector<SaveCacheEntry> saved;
std::ostringstream warning;
- /* clang-format off */
warning
<< "You have changed variables that require your cache to be deleted.\n"
- << "Configure will be re-run and you may have to reset some variables.\n"
- << "The following variables have changed:\n";
- /* clang-format on */
+ "Configure will be re-run and you may have to reset some variables.\n"
+ "The following variables have changed:\n";
for (auto i = argsSplit.begin(); i != argsSplit.end(); ++i) {
SaveCacheEntry save;
save.key = *i;
@@ -2023,9 +2146,9 @@ int cmake::HandleDeleteCacheVariables(const std::string& var)
i++;
if (i != argsSplit.end()) {
save.value = *i;
- warning << *i << "\n";
+ warning << *i << '\n';
} else {
- warning << "\n";
+ warning << '\n';
i -= 1;
}
cmValue existingValue = this->State->GetCacheEntryValue(save.key);
@@ -2060,6 +2183,10 @@ int cmake::HandleDeleteCacheVariables(const std::string& var)
int cmake::Configure()
{
+#if !defined(CMAKE_BOOTSTRAP)
+ auto profilingRAII = this->CreateProfilingEntry("project", "configure");
+#endif
+
DiagLevel diagLevel;
if (this->DiagLevels.count("deprecated") == 1) {
@@ -2297,10 +2424,22 @@ int cmake::ActualConfigure()
#if !defined(CMAKE_BOOTSTRAP)
this->FileAPI = cm::make_unique<cmFileAPI>(this);
this->FileAPI->ReadQueries();
+
+ if (!this->GetIsInTryCompile()) {
+ this->TruncateOutputLog("CMakeConfigureLog.yaml");
+ this->ConfigureLog = cm::make_unique<cmConfigureLog>(
+ cmStrCat(this->GetHomeOutputDirectory(), "/CMakeFiles"_s),
+ this->FileAPI->GetConfigureLogVersions());
+ }
#endif
// actually do the configure
this->GlobalGenerator->Configure();
+
+#if !defined(CMAKE_BOOTSTRAP)
+ this->ConfigureLog.reset();
+#endif
+
// Before saving the cache
// if the project did not define one of the entries below, add them now
// so users can edit the values in the cache:
@@ -2423,7 +2562,7 @@ void cmake::CreateDefaultGlobalGenerator()
auto gen = this->EvaluateDefaultGlobalGenerator();
#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(CMAKE_BOOT_MINGW)
// This print could be unified for all platforms
- std::cout << "-- Building for: " << gen->GetName() << "\n";
+ std::cout << "-- Building for: " << gen->GetName() << '\n';
#endif
this->SetGlobalGenerator(std::move(gen));
}
@@ -2572,12 +2711,17 @@ int cmake::Generate()
if (!this->GlobalGenerator) {
return -1;
}
+
+#if !defined(CMAKE_BOOTSTRAP)
+ auto profilingRAII = this->CreateProfilingEntry("project", "generate");
+#endif
+
if (!this->GlobalGenerator->Compute()) {
return -1;
}
this->GlobalGenerator->Generate();
if (!this->GraphVizFile.empty()) {
- std::cout << "Generate graphviz: " << this->GraphVizFile << std::endl;
+ std::cout << "Generate graphviz: " << this->GraphVizFile << '\n';
this->GenerateGraphViz(this->GraphVizFile);
}
if (this->WarnUnusedCli) {
@@ -2818,17 +2962,15 @@ void cmake::AppendGlobalGeneratorsDocumentation(
std::vector<cmDocumentationEntry>& v)
{
const auto defaultGenerator = this->EvaluateDefaultGlobalGenerator();
- const std::string defaultName = defaultGenerator->GetName();
- bool foundDefaultOne = false;
+ const auto defaultName = defaultGenerator->GetName();
+ auto foundDefaultOne = false;
for (const auto& g : this->Generators) {
- cmDocumentationEntry e;
- g->GetDocumentation(e);
- if (!foundDefaultOne && cmHasPrefix(e.Name, defaultName)) {
- e.CustomNamePrefix = '*';
+ v.emplace_back(g->GetDocumentation());
+ if (!foundDefaultOne && cmHasPrefix(v.back().Name, defaultName)) {
+ v.back().CustomNamePrefix = '*';
foundDefaultOne = true;
}
- v.push_back(std::move(e));
}
}
@@ -2841,21 +2983,14 @@ void cmake::AppendExtraGeneratorsDocumentation(
// Aliases:
for (std::string const& a : eg->Aliases) {
- cmDocumentationEntry e;
- e.Name = a;
- e.Brief = doc;
- v.push_back(std::move(e));
+ v.emplace_back(cmDocumentationEntry{ a, doc });
}
// Full names:
- const std::vector<std::string> generators =
- eg->GetSupportedGlobalGenerators();
- for (std::string const& g : generators) {
- cmDocumentationEntry e;
- e.Name =
- cmExternalMakefileProjectGenerator::CreateFullGeneratorName(g, name);
- e.Brief = doc;
- v.push_back(std::move(e));
+ for (std::string const& g : eg->GetSupportedGlobalGenerators()) {
+ v.emplace_back(cmDocumentationEntry{
+ cmExternalMakefileProjectGenerator::CreateFullGeneratorName(g, name),
+ doc });
}
}
}
@@ -2874,7 +3009,7 @@ void cmake::PrintGeneratorList()
cmDocumentation doc;
auto generators = this->GetGeneratorsDocumentation();
doc.AppendSection("Generators", generators);
- std::cerr << "\n";
+ std::cerr << '\n';
doc.PrintDocumentation(cmDocumentation::ListGenerators, std::cerr);
#endif
}
@@ -2926,7 +3061,7 @@ int cmake::CheckBuildSystem()
if (verbose) {
std::ostringstream msg;
msg << "Re-run cmake missing file: " << this->CheckBuildSystemArgument
- << "\n";
+ << '\n';
cmSystemTools::Stdout(msg.str());
}
return 1;
@@ -2946,7 +3081,7 @@ int cmake::CheckBuildSystem()
if (verbose) {
std::ostringstream msg;
msg << "Re-run cmake error reading : " << this->CheckBuildSystemArgument
- << "\n";
+ << '\n';
cmSystemTools::Stdout(msg.str());
}
// There was an error reading the file. Just rerun.
@@ -2977,9 +3112,8 @@ int cmake::CheckBuildSystem()
for (std::string const& p : products) {
if (!(cmSystemTools::FileExists(p) || cmSystemTools::FileIsSymlink(p))) {
if (verbose) {
- std::ostringstream msg;
- msg << "Re-run cmake, missing byproduct: " << p << "\n";
- cmSystemTools::Stdout(msg.str());
+ cmSystemTools::Stdout(
+ cmStrCat("Re-run cmake, missing byproduct: ", p, '\n'));
}
return 1;
}
@@ -3044,7 +3178,7 @@ int cmake::CheckBuildSystem()
if (verbose) {
std::ostringstream msg;
msg << "Re-run cmake file: " << out_oldest
- << " older than: " << dep_newest << "\n";
+ << " older than: " << dep_newest << '\n';
cmSystemTools::Stdout(msg.str());
}
return 1;
@@ -3220,7 +3354,7 @@ int cmake::GetSystemInformation(std::vector<std::string>& args)
// permissions are questionable or some other process has deleted the
// directory
std::cerr << "Failed to change to directory " << destPath << " : "
- << std::strerror(workdir.GetLastResult()) << std::endl;
+ << std::strerror(workdir.GetLastResult()) << '\n';
return 1;
}
std::vector<std::string> args2;
@@ -3257,96 +3391,6 @@ int cmake::GetSystemInformation(std::vector<std::string>& args)
return 0;
}
-static bool cmakeCheckStampFile(const std::string& stampName)
-{
- // The stamp file does not exist. Use the stamp dependencies to
- // determine whether it is really out of date. This works in
- // conjunction with cmLocalVisualStudio7Generator to avoid
- // repeatedly re-running CMake when the user rebuilds the entire
- // solution.
- std::string stampDepends = cmStrCat(stampName, ".depend");
-#if defined(_WIN32) || defined(__CYGWIN__)
- cmsys::ifstream fin(stampDepends.c_str(), std::ios::in | std::ios::binary);
-#else
- cmsys::ifstream fin(stampDepends.c_str());
-#endif
- if (!fin) {
- // The stamp dependencies file cannot be read. Just assume the
- // build system is really out of date.
- std::cout << "CMake is re-running because " << stampName
- << " dependency file is missing.\n";
- return false;
- }
-
- // Compare the stamp dependencies against the dependency file itself.
- {
- cmFileTimeCache ftc;
- std::string dep;
- while (cmSystemTools::GetLineFromStream(fin, dep)) {
- int result;
- if (!dep.empty() && dep[0] != '#' &&
- (!ftc.Compare(stampDepends, dep, &result) || result < 0)) {
- // The stamp depends file is older than this dependency. The
- // build system is really out of date.
- std::cout << "CMake is re-running because " << stampName
- << " is out-of-date.\n";
- std::cout << " the file '" << dep << "'\n";
- std::cout << " is newer than '" << stampDepends << "'\n";
- std::cout << " result='" << result << "'\n";
- return false;
- }
- }
- }
-
- // The build system is up to date. The stamp file has been removed
- // by the VS IDE due to a "rebuild" request. Restore it atomically.
- std::ostringstream stampTempStream;
- stampTempStream << stampName << ".tmp" << cmSystemTools::RandomSeed();
- std::string stampTemp = stampTempStream.str();
- {
- // TODO: Teach cmGeneratedFileStream to use a random temp file (with
- // multiple tries in unlikely case of conflict) and use that here.
- cmsys::ofstream stamp(stampTemp.c_str());
- stamp << "# CMake generation timestamp file for this directory.\n";
- }
- std::string err;
- if (cmSystemTools::RenameFile(stampTemp, stampName,
- cmSystemTools::Replace::Yes, &err) ==
- cmSystemTools::RenameResult::Success) {
- // CMake does not need to re-run because the stamp file is up-to-date.
- return true;
- }
- cmSystemTools::RemoveFile(stampTemp);
- cmSystemTools::Error(
- cmStrCat("Cannot restore timestamp \"", stampName, "\": ", err));
- return false;
-}
-
-static bool cmakeCheckStampList(const std::string& stampList)
-{
- // If the stamp list does not exist CMake must rerun to generate it.
- if (!cmSystemTools::FileExists(stampList)) {
- std::cout << "CMake is re-running because generate.stamp.list "
- << "is missing.\n";
- return false;
- }
- cmsys::ifstream fin(stampList.c_str());
- if (!fin) {
- std::cout << "CMake is re-running because generate.stamp.list "
- << "could not be read.\n";
- return false;
- }
-
- // Check each stamp.
- std::string stampName;
- while (cmSystemTools::GetLineFromStream(fin, stampName)) {
- if (!cmakeCheckStampFile(stampName)) {
- return false;
- }
- }
- return true;
-}
-
void cmake::IssueMessage(MessageType t, std::string const& text,
cmListFileBacktrace const& backtrace) const
{