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/cmCTestCurl.cxx2
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.cxx44
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.h3
-rw-r--r--Source/CTest/cmCTestRunTest.cxx61
-rw-r--r--Source/CTest/cmCTestRunTest.h13
-rw-r--r--Source/CTest/cmCTestSubmitHandler.cxx2
-rw-r--r--Source/CTest/cmProcess.cxx28
-rw-r--r--Source/CTest/cmProcess.h11
-rw-r--r--Source/cmBuildCommand.cxx2
-rw-r--r--Source/cmBuildNameCommand.cxx4
-rw-r--r--Source/cmCommonTargetGenerator.cxx2
-rw-r--r--Source/cmExtraEclipseCDT4Generator.cxx6
-rw-r--r--Source/cmFindLibraryCommand.cxx4
-rw-r--r--Source/cmFindPackageCommand.cxx4
-rw-r--r--Source/cmFindPathCommand.cxx4
-rw-r--r--Source/cmFindProgramCommand.cxx4
-rw-r--r--Source/cmGeneratorTarget.cxx84
-rw-r--r--Source/cmGetFilenameComponentCommand.cxx4
-rw-r--r--Source/cmGlobalGenerator.cxx4
-rw-r--r--Source/cmGlobalGhsMultiGenerator.cxx10
-rw-r--r--Source/cmGlobalVisualStudio7Generator.cxx2
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx8
-rw-r--r--Source/cmLinkLineComputer.cxx8
-rw-r--r--Source/cmMakefile.cxx16
-rw-r--r--Source/cmMakefile.h6
-rw-r--r--Source/cmMakefileProfilingData.cxx113
-rw-r--r--Source/cmMakefileProfilingData.h29
-rw-r--r--Source/cmProjectCommand.cxx8
-rw-r--r--Source/cmSetCommand.cxx4
-rw-r--r--Source/cmSiteNameCommand.cxx3
-rw-r--r--Source/cmTarget.cxx2
-rw-r--r--Source/cmUtilitySourceCommand.cxx12
-rw-r--r--Source/cmake.cxx57
-rw-r--r--Source/cmake.h12
-rw-r--r--Source/cmakemain.cxx6
37 files changed, 473 insertions, 112 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 24370aa..467abe9 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -354,6 +354,7 @@ set(SRCS
cmMakefileTargetGenerator.cxx
cmMakefileExecutableTargetGenerator.cxx
cmMakefileLibraryTargetGenerator.cxx
+ cmMakefileProfilingData.cxx
cmMakefileUtilityTargetGenerator.cxx
cmMessageType.h
cmMessenger.cxx
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index ff03496..edbac48 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 17)
-set(CMake_VERSION_PATCH 20200311)
+set(CMake_VERSION_PATCH 20200316)
#set(CMake_VERSION_RC 0)
set(CMake_VERSION_IS_DIRTY 0)
diff --git a/Source/CTest/cmCTestCurl.cxx b/Source/CTest/cmCTestCurl.cxx
index 3ad4749..69c5793 100644
--- a/Source/CTest/cmCTestCurl.cxx
+++ b/Source/CTest/cmCTestCurl.cxx
@@ -55,7 +55,7 @@ size_t curlDebugCallback(CURL* /*unused*/, curl_infotype /*unused*/,
char* chPtr, size_t size, void* data)
{
cm::append(*static_cast<std::vector<char>*>(data), chPtr, chPtr + size);
- return size;
+ return 0;
}
}
diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx
index 2192843..50c963d 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.cxx
+++ b/Source/CTest/cmCTestMultiProcessHandler.cxx
@@ -12,13 +12,13 @@
#include <iomanip>
#include <iostream>
#include <list>
-#include <memory>
#include <sstream>
#include <stack>
#include <unordered_map>
#include <utility>
#include <vector>
+#include <cm/memory>
#include <cmext/algorithm>
#include "cmsys/FStream.hxx"
@@ -172,7 +172,8 @@ bool cmCTestMultiProcessHandler::StartTestProcess(int test)
this->EraseTest(test);
this->RunningCount += GetProcessorsUsed(test);
- cmCTestRunTest* testRun = new cmCTestRunTest(*this);
+ auto testRun = cm::make_unique<cmCTestRunTest>(*this);
+
if (this->RepeatMode != cmCTest::Repeat::Never) {
testRun->SetRepeatMode(this->RepeatMode);
testRun->SetNumberOfRuns(this->RepeatCount);
@@ -229,28 +230,25 @@ bool cmCTestMultiProcessHandler::StartTestProcess(int test)
e << "\n";
}
e << "Resource spec file:\n\n " << this->TestHandler->ResourceSpecFile;
- testRun->StartFailure(e.str(), "Insufficient resources");
- this->FinishTestProcess(testRun, false);
+ cmCTestRunTest::StartFailure(std::move(testRun), e.str(),
+ "Insufficient resources");
return false;
}
cmWorkingDirectory workdir(this->Properties[test]->Directory);
if (workdir.Failed()) {
- testRun->StartFailure("Failed to change working directory to " +
- this->Properties[test]->Directory + " : " +
- std::strerror(workdir.GetLastResult()),
- "Failed to change working directory");
- } else {
- if (testRun->StartTest(this->Completed, this->Total)) {
- // Ownership of 'testRun' has moved to another structure.
- // When the test finishes, FinishTestProcess will be called.
- return true;
- }
+ cmCTestRunTest::StartFailure(std::move(testRun),
+ "Failed to change working directory to " +
+ this->Properties[test]->Directory + " : " +
+ std::strerror(workdir.GetLastResult()),
+ "Failed to change working directory");
+ return false;
}
- // Pass ownership of 'testRun'.
- this->FinishTestProcess(testRun, false);
- return false;
+ // Ownership of 'testRun' has moved to another structure.
+ // When the test finishes, FinishTestProcess will be called.
+ return cmCTestRunTest::StartTest(std::move(testRun), this->Completed,
+ this->Total);
}
bool cmCTestMultiProcessHandler::AllocateResources(int index)
@@ -540,7 +538,8 @@ void cmCTestMultiProcessHandler::StartNextTests()
if (this->SerialTestRunning) {
break;
}
- // We can only start a RUN_SERIAL test if no other tests are also running.
+ // We can only start a RUN_SERIAL test if no other tests are also
+ // running.
if (this->Properties[test]->RunSerial && this->RunningCount > 0) {
continue;
}
@@ -618,8 +617,8 @@ void cmCTestMultiProcessHandler::OnTestLoadRetryCB(uv_timer_t* timer)
self->StartNextTests();
}
-void cmCTestMultiProcessHandler::FinishTestProcess(cmCTestRunTest* runner,
- bool started)
+void cmCTestMultiProcessHandler::FinishTestProcess(
+ std::unique_ptr<cmCTestRunTest> runner, bool started)
{
this->Completed++;
@@ -631,7 +630,8 @@ void cmCTestMultiProcessHandler::FinishTestProcess(cmCTestRunTest* runner,
this->SetStopTimePassed();
}
if (started) {
- if (!this->StopTimePassed && runner->StartAgain(this->Completed)) {
+ if (!this->StopTimePassed &&
+ cmCTestRunTest::StartAgain(std::move(runner), this->Completed)) {
this->Completed--; // remove the completed test because run again
return;
}
@@ -659,7 +659,7 @@ void cmCTestMultiProcessHandler::FinishTestProcess(cmCTestRunTest* runner,
}
properties->Affinity.clear();
- delete runner;
+ runner.reset();
if (started) {
this->StartNextTests();
}
diff --git a/Source/CTest/cmCTestMultiProcessHandler.h b/Source/CTest/cmCTestMultiProcessHandler.h
index 5b429d4..c3686bc 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.h
+++ b/Source/CTest/cmCTestMultiProcessHandler.h
@@ -6,6 +6,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <map>
+#include <memory>
#include <set>
#include <string>
#include <vector>
@@ -124,7 +125,7 @@ protected:
// Removes the checkpoint file
void MarkFinished();
void EraseTest(int index);
- void FinishTestProcess(cmCTestRunTest* runner, bool started);
+ void FinishTestProcess(std::unique_ptr<cmCTestRunTest> runner, bool started);
static void OnTestLoadRetryCB(uv_timer_t* timer);
diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx
index ec54960..7d0f69b 100644
--- a/Source/CTest/cmCTestRunTest.cxx
+++ b/Source/CTest/cmCTestRunTest.cxx
@@ -314,23 +314,27 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started)
return passed || skipped;
}
-bool cmCTestRunTest::StartAgain(size_t completed)
+bool cmCTestRunTest::StartAgain(std::unique_ptr<cmCTestRunTest> runner,
+ size_t completed)
{
- if (!this->RunAgain) {
+ auto* testRun = runner.get();
+
+ if (!testRun->RunAgain) {
return false;
}
- this->RunAgain = false; // reset
+ testRun->RunAgain = false; // reset
+ testRun->TestProcess = cm::make_unique<cmProcess>(std::move(runner));
// change to tests directory
- cmWorkingDirectory workdir(this->TestProperties->Directory);
+ cmWorkingDirectory workdir(testRun->TestProperties->Directory);
if (workdir.Failed()) {
- this->StartFailure("Failed to change working directory to " +
- this->TestProperties->Directory + " : " +
- std::strerror(workdir.GetLastResult()),
- "Failed to change working directory");
+ testRun->StartFailure("Failed to change working directory to " +
+ testRun->TestProperties->Directory + " : " +
+ std::strerror(workdir.GetLastResult()),
+ "Failed to change working directory");
return true;
}
- this->StartTest(completed, this->TotalNumberOfTests);
+ testRun->StartTest(completed, testRun->TotalNumberOfTests);
return true;
}
@@ -382,6 +386,18 @@ void cmCTestRunTest::MemCheckPostProcess()
handler->PostProcessTest(this->TestResult, this->Index);
}
+void cmCTestRunTest::StartFailure(std::unique_ptr<cmCTestRunTest> runner,
+ std::string const& output,
+ std::string const& detail)
+{
+ auto* testRun = runner.get();
+
+ testRun->TestProcess = cm::make_unique<cmProcess>(std::move(runner));
+ testRun->StartFailure(output, detail);
+
+ testRun->FinalizeTest(false);
+}
+
void cmCTestRunTest::StartFailure(std::string const& output,
std::string const& detail)
{
@@ -413,7 +429,6 @@ void cmCTestRunTest::StartFailure(std::string const& output,
this->TestResult.Path = this->TestProperties->Directory;
this->TestResult.Output = output;
this->TestResult.FullCommandLine.clear();
- this->TestProcess = cm::make_unique<cmProcess>(*this);
}
std::string cmCTestRunTest::GetTestPrefix(size_t completed, size_t total) const
@@ -437,6 +452,21 @@ std::string cmCTestRunTest::GetTestPrefix(size_t completed, size_t total) const
return outputStream.str();
}
+bool cmCTestRunTest::StartTest(std::unique_ptr<cmCTestRunTest> runner,
+ size_t completed, size_t total)
+{
+ auto* testRun = runner.get();
+
+ testRun->TestProcess = cm::make_unique<cmProcess>(std::move(runner));
+
+ if (!testRun->StartTest(completed, total)) {
+ testRun->FinalizeTest(false);
+ return false;
+ }
+
+ return true;
+}
+
// Starts the execution of a test. Returns once it has started
bool cmCTestRunTest::StartTest(size_t completed, size_t total)
{
@@ -468,7 +498,6 @@ bool cmCTestRunTest::StartTest(size_t completed, size_t total)
if (this->TestProperties->Disabled) {
this->TestResult.CompletionStatus = "Disabled";
this->TestResult.Status = cmCTestTestHandler::NOT_RUN;
- this->TestProcess = cm::make_unique<cmProcess>(*this);
this->TestResult.Output = "Disabled";
this->TestResult.FullCommandLine.clear();
return false;
@@ -482,7 +511,6 @@ bool cmCTestRunTest::StartTest(size_t completed, size_t total)
// its arguments are irrelevant. This matters for the case where a fixture
// dependency might be creating the executable we want to run.
if (!this->FailedDependencies.empty()) {
- this->TestProcess = cm::make_unique<cmProcess>(*this);
std::string msg = "Failed test dependencies:";
for (std::string const& failedDep : this->FailedDependencies) {
msg += " " + failedDep;
@@ -499,7 +527,6 @@ bool cmCTestRunTest::StartTest(size_t completed, size_t total)
this->ComputeArguments();
std::vector<std::string>& args = this->TestProperties->Args;
if (args.size() >= 2 && args[1] == "NOT_AVAILABLE") {
- this->TestProcess = cm::make_unique<cmProcess>(*this);
std::string msg;
if (this->CTest->GetConfigType().empty()) {
msg = "Test not available without configuration. (Missing \"-C "
@@ -521,7 +548,6 @@ bool cmCTestRunTest::StartTest(size_t completed, size_t total)
for (std::string const& file : this->TestProperties->RequiredFiles) {
if (!cmSystemTools::FileExists(file)) {
// Required file was not found
- this->TestProcess = cm::make_unique<cmProcess>(*this);
*this->TestHandler->LogFile << "Unable to find required file: " << file
<< std::endl;
cmCTestLog(this->CTest, ERROR_MESSAGE,
@@ -537,7 +563,6 @@ bool cmCTestRunTest::StartTest(size_t completed, size_t total)
if (this->ActualCommand.empty()) {
// if the command was not found create a TestResult object
// that has that information
- this->TestProcess = cm::make_unique<cmProcess>(*this);
*this->TestHandler->LogFile << "Unable to find executable: " << args[1]
<< std::endl;
cmCTestLog(this->CTest, ERROR_MESSAGE,
@@ -649,7 +674,6 @@ bool cmCTestRunTest::ForkProcess(cmDuration testTimeOut, bool explicitTimeout,
std::vector<std::string>* environment,
std::vector<size_t>* affinity)
{
- this->TestProcess = cm::make_unique<cmProcess>(*this);
this->TestProcess->SetId(this->Index);
this->TestProcess->SetWorkingDirectory(this->TestProperties->Directory);
this->TestProcess->SetCommand(this->ActualCommand);
@@ -816,7 +840,8 @@ void cmCTestRunTest::WriteLogOutputTop(size_t completed, size_t total)
"Testing " << this->TestProperties->Name << " ... ");
}
-void cmCTestRunTest::FinalizeTest()
+void cmCTestRunTest::FinalizeTest(bool started)
{
- this->MultiTestHandler.FinishTestProcess(this, true);
+ this->MultiTestHandler.FinishTestProcess(this->TestProcess->GetRunner(),
+ started);
}
diff --git a/Source/CTest/cmCTestRunTest.h b/Source/CTest/cmCTestRunTest.h
index 4988839..b1d188a 100644
--- a/Source/CTest/cmCTestRunTest.h
+++ b/Source/CTest/cmCTestRunTest.h
@@ -65,6 +65,15 @@ public:
// Read and store output. Returns true if it must be called again.
void CheckOutput(std::string const& line);
+ static bool StartTest(std::unique_ptr<cmCTestRunTest> runner,
+ size_t completed, size_t total);
+ static bool StartAgain(std::unique_ptr<cmCTestRunTest> runner,
+ size_t completed);
+
+ static void StartFailure(std::unique_ptr<cmCTestRunTest> runner,
+ std::string const& output,
+ std::string const& detail);
+
// launch the test process, return whether it started correctly
bool StartTest(size_t completed, size_t total);
// capture and report the test results
@@ -74,8 +83,6 @@ public:
void ComputeWeightedCost();
- bool StartAgain(size_t completed);
-
void StartFailure(std::string const& output, std::string const& detail);
cmCTest* GetCTest() const { return this->CTest; }
@@ -84,7 +91,7 @@ public:
const std::vector<std::string>& GetArguments() { return this->Arguments; }
- void FinalizeTest();
+ void FinalizeTest(bool started = true);
bool TimedOutForStopTime() const { return this->TimeoutIsForStopTime; }
diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx
index a8f201a..22ab48f 100644
--- a/Source/CTest/cmCTestSubmitHandler.cxx
+++ b/Source/CTest/cmCTestSubmitHandler.cxx
@@ -110,7 +110,7 @@ static size_t cmCTestSubmitHandlerCurlDebugCallback(CURL* /*unused*/,
{
cm::append(*static_cast<cmCTestSubmitHandlerVectorOfChar*>(data), chPtr,
chPtr + size);
- return size;
+ return 0;
}
cmCTestSubmitHandler::cmCTestSubmitHandler()
diff --git a/Source/CTest/cmProcess.cxx b/Source/CTest/cmProcess.cxx
index cdf899c..76ffb20 100644
--- a/Source/CTest/cmProcess.cxx
+++ b/Source/CTest/cmProcess.cxx
@@ -5,6 +5,7 @@
#include <csignal>
#include <iostream>
#include <string>
+#include <utility>
#include <cmext/algorithm>
@@ -18,12 +19,11 @@
#if defined(_WIN32)
# include "cm_kwiml.h"
#endif
-#include <utility>
#define CM_PROCESS_BUF_SIZE 65536
-cmProcess::cmProcess(cmCTestRunTest& runner)
- : Runner(runner)
+cmProcess::cmProcess(std::unique_ptr<cmCTestRunTest> runner)
+ : Runner(std::move(runner))
, Conv(cmProcessOutput::UTF8, CM_PROCESS_BUF_SIZE)
{
this->Timeout = cmDuration::zero();
@@ -69,7 +69,7 @@ bool cmProcess::StartProcess(uv_loop_t& loop, std::vector<size_t>* affinity)
cm::uv_timer_ptr timer;
int status = timer.init(loop, this);
if (status != 0) {
- cmCTestLog(this->Runner.GetCTest(), ERROR_MESSAGE,
+ cmCTestLog(this->Runner->GetCTest(), ERROR_MESSAGE,
"Error initializing timer: " << uv_strerror(status)
<< std::endl);
return false;
@@ -84,7 +84,7 @@ bool cmProcess::StartProcess(uv_loop_t& loop, std::vector<size_t>* affinity)
int fds[2] = { -1, -1 };
status = cmGetPipes(fds);
if (status != 0) {
- cmCTestLog(this->Runner.GetCTest(), ERROR_MESSAGE,
+ cmCTestLog(this->Runner->GetCTest(), ERROR_MESSAGE,
"Error initializing pipe: " << uv_strerror(status)
<< std::endl);
return false;
@@ -127,7 +127,7 @@ bool cmProcess::StartProcess(uv_loop_t& loop, std::vector<size_t>* affinity)
uv_read_start(pipe_reader, &cmProcess::OnAllocateCB, &cmProcess::OnReadCB);
if (status != 0) {
- cmCTestLog(this->Runner.GetCTest(), ERROR_MESSAGE,
+ cmCTestLog(this->Runner->GetCTest(), ERROR_MESSAGE,
"Error starting read events: " << uv_strerror(status)
<< std::endl);
return false;
@@ -135,7 +135,7 @@ bool cmProcess::StartProcess(uv_loop_t& loop, std::vector<size_t>* affinity)
status = this->Process.spawn(loop, options, this);
if (status != 0) {
- cmCTestLog(this->Runner.GetCTest(), ERROR_MESSAGE,
+ cmCTestLog(this->Runner->GetCTest(), ERROR_MESSAGE,
"Process not started\n " << this->Command << "\n["
<< uv_strerror(status) << "]\n");
return false;
@@ -152,7 +152,7 @@ bool cmProcess::StartProcess(uv_loop_t& loop, std::vector<size_t>* affinity)
void cmProcess::StartTimer()
{
- auto properties = this->Runner.GetTestProperties();
+ auto properties = this->Runner->GetTestProperties();
auto msec =
std::chrono::duration_cast<std::chrono::milliseconds>(this->Timeout);
@@ -222,7 +222,7 @@ void cmProcess::OnRead(ssize_t nread, const uv_buf_t* buf)
cm::append(this->Output, strdata);
while (this->Output.GetLine(line)) {
- this->Runner.CheckOutput(line);
+ this->Runner->CheckOutput(line);
line.clear();
}
@@ -236,20 +236,20 @@ void cmProcess::OnRead(ssize_t nread, const uv_buf_t* buf)
// The process will provide no more data.
if (nread != UV_EOF) {
auto error = static_cast<int>(nread);
- cmCTestLog(this->Runner.GetCTest(), ERROR_MESSAGE,
+ cmCTestLog(this->Runner->GetCTest(), ERROR_MESSAGE,
"Error reading stream: " << uv_strerror(error) << std::endl);
}
// Look for partial last lines.
if (this->Output.GetLast(line)) {
- this->Runner.CheckOutput(line);
+ this->Runner->CheckOutput(line);
}
this->ReadHandleClosed = true;
this->PipeReader.reset();
if (this->ProcessHandleClosed) {
uv_timer_stop(this->Timer);
- this->Runner.FinalizeTest();
+ this->Runner->FinalizeTest();
}
}
@@ -291,7 +291,7 @@ void cmProcess::OnTimeout()
// Our on-exit handler already ran but did not finish the test
// because we were still reading output. We've just dropped
// our read handler, so we need to finish the test now.
- this->Runner.FinalizeTest();
+ this->Runner->FinalizeTest();
}
}
@@ -333,7 +333,7 @@ void cmProcess::OnExit(int64_t exit_status, int term_signal)
this->ProcessHandleClosed = true;
if (this->ReadHandleClosed) {
uv_timer_stop(this->Timer);
- this->Runner.FinalizeTest();
+ this->Runner->FinalizeTest();
}
}
diff --git a/Source/CTest/cmProcess.h b/Source/CTest/cmProcess.h
index 2c24f2d..0f69f68 100644
--- a/Source/CTest/cmProcess.h
+++ b/Source/CTest/cmProcess.h
@@ -6,7 +6,9 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <chrono>
+#include <memory>
#include <string>
+#include <utility>
#include <vector>
#include <stddef.h>
@@ -28,7 +30,7 @@ class cmCTestRunTest;
class cmProcess
{
public:
- explicit cmProcess(cmCTestRunTest& runner);
+ explicit cmProcess(std::unique_ptr<cmCTestRunTest> runner);
~cmProcess();
void SetCommand(std::string const& command);
void SetCommandArguments(std::vector<std::string> const& arg);
@@ -70,6 +72,11 @@ public:
Exception GetExitException();
std::string GetExitExceptionString();
+ std::unique_ptr<cmCTestRunTest> GetRunner()
+ {
+ return std::move(this->Runner);
+ }
+
private:
cmDuration Timeout;
std::chrono::steady_clock::time_point StartTime;
@@ -82,7 +89,7 @@ private:
cm::uv_timer_ptr Timer;
std::vector<char> Buf;
- cmCTestRunTest& Runner;
+ std::unique_ptr<cmCTestRunTest> Runner;
cmProcessOutput Conv;
int Signal = 0;
cmProcess::State ProcessState = cmProcess::State::Starting;
diff --git a/Source/cmBuildCommand.cxx b/Source/cmBuildCommand.cxx
index 49c9439..b82fb9a 100644
--- a/Source/cmBuildCommand.cxx
+++ b/Source/cmBuildCommand.cxx
@@ -108,7 +108,7 @@ bool TwoArgsSignature(std::vector<std::string> const& args,
if (cacheValue) {
return true;
}
- mf.AddCacheDefinition(define, makecommand.c_str(),
+ mf.AddCacheDefinition(define, makecommand,
"Command used to build entire project "
"from the command line.",
cmStateEnums::STRING);
diff --git a/Source/cmBuildNameCommand.cxx b/Source/cmBuildNameCommand.cxx
index 3e517dc..ad4d665 100644
--- a/Source/cmBuildNameCommand.cxx
+++ b/Source/cmBuildNameCommand.cxx
@@ -28,7 +28,7 @@ bool cmBuildNameCommand(std::vector<std::string> const& args,
std::replace(cv.begin(), cv.end(), '/', '_');
std::replace(cv.begin(), cv.end(), '(', '_');
std::replace(cv.begin(), cv.end(), ')', '_');
- mf.AddCacheDefinition(args[0], cv.c_str(), "Name of build.",
+ mf.AddCacheDefinition(args[0], cv, "Name of build.",
cmStateEnums::STRING);
}
return true;
@@ -54,7 +54,7 @@ bool cmBuildNameCommand(std::vector<std::string> const& args,
std::replace(buildname.begin(), buildname.end(), '(', '_');
std::replace(buildname.begin(), buildname.end(), ')', '_');
- mf.AddCacheDefinition(args[0], buildname.c_str(), "Name of build.",
+ mf.AddCacheDefinition(args[0], buildname, "Name of build.",
cmStateEnums::STRING);
return true;
}
diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx
index 5ff6f8c..033cb60 100644
--- a/Source/cmCommonTargetGenerator.cxx
+++ b/Source/cmCommonTargetGenerator.cxx
@@ -248,7 +248,7 @@ void cmCommonTargetGenerator::AppendOSXVerFlag(std::string& flags,
int major;
int minor;
int patch;
- std::string prop = cmStrCat("OSX_", name, "_VERSION");
+ std::string prop = cmStrCat("MACHO_", name, "_VERSION");
std::string fallback_prop = so ? "SOVERSION" : "VERSION";
this->GeneratorTarget->GetTargetVersionFallback(prop, fallback_prop, major,
minor, patch);
diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx
index 78cabce..8ab30c0 100644
--- a/Source/cmExtraEclipseCDT4Generator.cxx
+++ b/Source/cmExtraEclipseCDT4Generator.cxx
@@ -255,8 +255,8 @@ void cmExtraEclipseCDT4Generator::AddEnvVar(std::ostream& out,
// The variable is in the env, but not in the cache. Use it and put it
// in the cache
valueToUse = envVarValue;
- mf->AddCacheDefinition(cacheEntryName, valueToUse.c_str(),
- cacheEntryName.c_str(), cmStateEnums::STRING, true);
+ mf->AddCacheDefinition(cacheEntryName, valueToUse, cacheEntryName.c_str(),
+ cmStateEnums::STRING, true);
mf->GetCMakeInstance()->SaveCache(lg.GetBinaryDirectory());
} else if (!envVarSet && cacheValue != nullptr) {
// It is already in the cache, but not in the env, so use it from the cache
@@ -270,7 +270,7 @@ void cmExtraEclipseCDT4Generator::AddEnvVar(std::ostream& out,
valueToUse = *cacheValue;
if (valueToUse.find(envVarValue) == std::string::npos) {
valueToUse = envVarValue;
- mf->AddCacheDefinition(cacheEntryName, valueToUse.c_str(),
+ mf->AddCacheDefinition(cacheEntryName, valueToUse,
cacheEntryName.c_str(), cmStateEnums::STRING,
true);
mf->GetCMakeInstance()->SaveCache(lg.GetBinaryDirectory());
diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx
index 6f9f7a2..31f1201 100644
--- a/Source/cmFindLibraryCommand.cxx
+++ b/Source/cmFindLibraryCommand.cxx
@@ -76,13 +76,13 @@ bool cmFindLibraryCommand::InitialPass(std::vector<std::string> const& argsIn)
std::string const library = this->FindLibrary();
if (!library.empty()) {
// Save the value in the cache
- this->Makefile->AddCacheDefinition(this->VariableName, library.c_str(),
+ this->Makefile->AddCacheDefinition(this->VariableName, library,
this->VariableDocumentation.c_str(),
cmStateEnums::FILEPATH);
return true;
}
std::string notfound = this->VariableName + "-NOTFOUND";
- this->Makefile->AddCacheDefinition(this->VariableName, notfound.c_str(),
+ this->Makefile->AddCacheDefinition(this->VariableName, notfound,
this->VariableDocumentation.c_str(),
cmStateEnums::FILEPATH);
if (this->Required) {
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index 297c72b..f606002 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -1060,8 +1060,8 @@ bool cmFindPackageCommand::FindConfig()
cmStrCat("The directory containing a CMake configuration file for ",
this->Name, '.');
// We force the value since we do not get here if it was already set.
- this->Makefile->AddCacheDefinition(this->Variable, init.c_str(),
- help.c_str(), cmStateEnums::PATH, true);
+ this->Makefile->AddCacheDefinition(this->Variable, init, help.c_str(),
+ cmStateEnums::PATH, true);
return found;
}
diff --git a/Source/cmFindPathCommand.cxx b/Source/cmFindPathCommand.cxx
index f5b52c2..4bab469 100644
--- a/Source/cmFindPathCommand.cxx
+++ b/Source/cmFindPathCommand.cxx
@@ -44,12 +44,12 @@ bool cmFindPathCommand::InitialPass(std::vector<std::string> const& argsIn)
std::string result = this->FindHeader();
if (!result.empty()) {
this->Makefile->AddCacheDefinition(
- this->VariableName, result.c_str(), this->VariableDocumentation.c_str(),
+ this->VariableName, result, this->VariableDocumentation.c_str(),
(this->IncludeFileInPath) ? cmStateEnums::FILEPATH : cmStateEnums::PATH);
return true;
}
this->Makefile->AddCacheDefinition(
- this->VariableName, (this->VariableName + "-NOTFOUND").c_str(),
+ this->VariableName, this->VariableName + "-NOTFOUND",
this->VariableDocumentation.c_str(),
(this->IncludeFileInPath) ? cmStateEnums::FILEPATH : cmStateEnums::PATH);
if (this->Required) {
diff --git a/Source/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx
index cbc3c78..4b88bea 100644
--- a/Source/cmFindProgramCommand.cxx
+++ b/Source/cmFindProgramCommand.cxx
@@ -128,14 +128,14 @@ bool cmFindProgramCommand::InitialPass(std::vector<std::string> const& argsIn)
std::string const result = FindProgram();
if (!result.empty()) {
// Save the value in the cache
- this->Makefile->AddCacheDefinition(this->VariableName, result.c_str(),
+ this->Makefile->AddCacheDefinition(this->VariableName, result,
this->VariableDocumentation.c_str(),
cmStateEnums::FILEPATH);
return true;
}
this->Makefile->AddCacheDefinition(
- this->VariableName, (this->VariableName + "-NOTFOUND").c_str(),
+ this->VariableName, this->VariableName + "-NOTFOUND",
this->VariableDocumentation.c_str(), cmStateEnums::FILEPATH);
if (this->Required) {
this->Makefile->IssueMessage(
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index ad142d7..cb80fe6 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -1282,6 +1282,86 @@ std::string cmGeneratorTarget::EvaluateInterfaceProperty(
}
namespace {
+std::string AddSwiftInterfaceIncludeDirectories(
+ const cmGeneratorTarget* root, const cmGeneratorTarget* target,
+ const std::string& config, cmGeneratorExpressionDAGChecker* context)
+{
+ cmGeneratorExpressionDAGChecker dag{ target->GetBacktrace(), target,
+ "Swift_MODULE_DIRECTORY", nullptr,
+ context };
+ switch (dag.Check()) {
+ case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
+ dag.ReportError(nullptr,
+ "$<TARGET_PROPERTY:" + target->GetName() +
+ ",Swift_MODULE_DIRECTORY>");
+ return "";
+ case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE:
+ // No error. We just skip cyclic references.
+ return "";
+ case cmGeneratorExpressionDAGChecker::ALREADY_SEEN:
+ // No error. We have already seen this transitive property.
+ return "";
+ case cmGeneratorExpressionDAGChecker::DAG:
+ break;
+ }
+
+ std::string directories;
+ if (const auto* interface =
+ target->GetLinkInterfaceLibraries(config, root, true)) {
+ for (const cmLinkItem& library : interface->Libraries) {
+ if (const cmGeneratorTarget* dependency = library.Target) {
+ if (cmContains(dependency->GetAllConfigCompileLanguages(), "Swift")) {
+ std::string value =
+ dependency->GetSafeProperty("Swift_MODULE_DIRECTORY");
+ if (value.empty()) {
+ value =
+ dependency->GetLocalGenerator()->GetCurrentBinaryDirectory();
+ }
+
+ if (!directories.empty()) {
+ directories += ";";
+ }
+ directories += value;
+ }
+ }
+ }
+ }
+ return directories;
+}
+
+void AddSwiftImplicitIncludeDirectories(
+ const cmGeneratorTarget* target, const std::string& config,
+ std::vector<EvaluatedTargetPropertyEntry>& entries)
+{
+ if (const auto* libraries = target->GetLinkImplementationLibraries(config)) {
+ cmGeneratorExpressionDAGChecker dag{ target->GetBacktrace(), target,
+ "Swift_MODULE_DIRECTORY", nullptr,
+ nullptr };
+
+ for (const cmLinkImplItem& library : libraries->Libraries) {
+ if (const cmGeneratorTarget* dependency = library.Target) {
+ if (cmContains(dependency->GetAllConfigCompileLanguages(), "Swift")) {
+ EvaluatedTargetPropertyEntry entry{ library, library.Backtrace };
+
+ if (const char* val =
+ dependency->GetProperty("Swift_MODULE_DIRECTORY")) {
+ entry.Values.emplace_back(val);
+ } else {
+ entry.Values.emplace_back(
+ dependency->GetLocalGenerator()->GetCurrentBinaryDirectory());
+ }
+
+ cmExpandList(AddSwiftInterfaceIncludeDirectories(target, dependency,
+ config, &dag),
+ entry.Values);
+
+ entries.emplace_back(std::move(entry));
+ }
+ }
+ }
+ }
+}
+
void AddInterfaceEntries(cmGeneratorTarget const* headTarget,
std::string const& config, std::string const& prop,
std::string const& lang,
@@ -3177,6 +3257,10 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories(
EvaluateTargetPropertyEntries(this, config, lang, &dagChecker,
this->IncludeDirectoriesEntries);
+ if (lang == "Swift") {
+ AddSwiftImplicitIncludeDirectories(this, config, entries);
+ }
+
AddInterfaceEntries(this, config, "INTERFACE_INCLUDE_DIRECTORIES", lang,
&dagChecker, entries);
diff --git a/Source/cmGetFilenameComponentCommand.cxx b/Source/cmGetFilenameComponentCommand.cxx
index 7d91a75..811421a 100644
--- a/Source/cmGetFilenameComponentCommand.cxx
+++ b/Source/cmGetFilenameComponentCommand.cxx
@@ -120,11 +120,11 @@ bool cmGetFilenameComponentCommand(std::vector<std::string> const& args,
if (args.size() >= 4 && args.back() == "CACHE") {
if (!programArgs.empty() && !storeArgs.empty()) {
status.GetMakefile().AddCacheDefinition(
- storeArgs, programArgs.c_str(), "",
+ storeArgs, programArgs, "",
args[2] == "PATH" ? cmStateEnums::FILEPATH : cmStateEnums::STRING);
}
status.GetMakefile().AddCacheDefinition(
- args.front(), result.c_str(), "",
+ args.front(), result, "",
args[2] == "PATH" ? cmStateEnums::FILEPATH : cmStateEnums::STRING);
} else {
if (!programArgs.empty() && !storeArgs.empty()) {
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 0404715..0b9a3e5 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -446,8 +446,8 @@ bool cmGlobalGenerator::FindMakeProgram(cmMakefile* mf)
cmSystemTools::GetShortPath(makeProgram, makeProgram);
cmSystemTools::SplitProgramPath(makeProgram, dir, file);
makeProgram = cmStrCat(dir, '/', saveFile);
- mf->AddCacheDefinition("CMAKE_MAKE_PROGRAM", makeProgram.c_str(),
- "make program", cmStateEnums::FILEPATH);
+ mf->AddCacheDefinition("CMAKE_MAKE_PROGRAM", makeProgram, "make program",
+ cmStateEnums::FILEPATH);
}
return true;
}
diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx
index 78e3b43..9754fd5 100644
--- a/Source/cmGlobalGhsMultiGenerator.cxx
+++ b/Source/cmGlobalGhsMultiGenerator.cxx
@@ -91,7 +91,7 @@ bool cmGlobalGhsMultiGenerator::SetGeneratorToolset(std::string const& ts,
/* store the full toolset for later use
* -- already done if -T<toolset> was specified
*/
- mf->AddCacheDefinition("CMAKE_GENERATOR_TOOLSET", tsp.c_str(),
+ mf->AddCacheDefinition("CMAKE_GENERATOR_TOOLSET", tsp,
"Location of generator toolset.",
cmStateEnums::INTERNAL);
}
@@ -113,8 +113,8 @@ bool cmGlobalGhsMultiGenerator::SetGeneratorToolset(std::string const& ts,
}
/* store the toolset that is being used for this build */
- mf->AddCacheDefinition("CMAKE_MAKE_PROGRAM", gbuild.c_str(),
- "build program to use", cmStateEnums::INTERNAL, true);
+ mf->AddCacheDefinition("CMAKE_MAKE_PROGRAM", gbuild, "build program to use",
+ cmStateEnums::INTERNAL, true);
mf->AddDefinition("CMAKE_SYSTEM_VERSION", tsp);
@@ -133,7 +133,7 @@ bool cmGlobalGhsMultiGenerator::SetGeneratorPlatform(std::string const& p,
/* store the platform name for later use
* -- already done if -A<arch> was specified
*/
- mf->AddCacheDefinition("CMAKE_GENERATOR_PLATFORM", arch.c_str(),
+ mf->AddCacheDefinition("CMAKE_GENERATOR_PLATFORM", arch,
"Name of generator platform.",
cmStateEnums::INTERNAL);
} else {
@@ -167,7 +167,7 @@ bool cmGlobalGhsMultiGenerator::SetGeneratorPlatform(std::string const& p,
if (cmIsOff(bspName) && platform.find("integrity") != std::string::npos) {
bspName = "sim" + arch;
/* write back the calculate name for next time */
- mf->AddCacheDefinition("GHS_BSP_NAME", bspName.c_str(),
+ mf->AddCacheDefinition("GHS_BSP_NAME", bspName,
"Name of GHS target platform.",
cmStateEnums::STRING, true);
std::string m = cmStrCat(
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
index eb33825..43d31bc 100644
--- a/Source/cmGlobalVisualStudio7Generator.cxx
+++ b/Source/cmGlobalVisualStudio7Generator.cxx
@@ -128,7 +128,7 @@ void cmGlobalVisualStudio7Generator::EnableLanguage(
// does not know about.
std::string extraPath;
if (cmSystemTools::GetEnv("CMAKE_MSVCIDE_RUN_PATH", extraPath)) {
- mf->AddCacheDefinition("CMAKE_MSVCIDE_RUN_PATH", extraPath.c_str(),
+ mf->AddCacheDefinition("CMAKE_MSVCIDE_RUN_PATH", extraPath,
"Saved environment variable CMAKE_MSVCIDE_RUN_PATH",
cmStateEnums::STATIC);
}
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index ac7d204..9db4817 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -2369,8 +2369,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
int minor;
int patch;
- // OSX_CURRENT_VERSION or VERSION -> current_version
- gtgt->GetTargetVersionFallback("OSX_CURRENT_VERSION", "VERSION", major,
+ // MACHO_CURRENT_VERSION or VERSION -> current_version
+ gtgt->GetTargetVersionFallback("MACHO_CURRENT_VERSION", "VERSION", major,
minor, patch);
std::ostringstream v;
@@ -2381,8 +2381,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
buildSettings->AddAttribute("DYLIB_CURRENT_VERSION",
this->CreateString(v.str()));
- // OSX_COMPATIBILITY_VERSION or SOVERSION -> compatibility_version
- gtgt->GetTargetVersionFallback("OSX_COMPATIBILITY_VERSION", "SOVERSION",
+ // MACHO_COMPATIBILITY_VERSION or SOVERSION -> compatibility_version
+ gtgt->GetTargetVersionFallback("MACHO_COMPATIBILITY_VERSION", "SOVERSION",
major, minor, patch);
std::ostringstream vso;
diff --git a/Source/cmLinkLineComputer.cxx b/Source/cmLinkLineComputer.cxx
index 86ee953..480c005 100644
--- a/Source/cmLinkLineComputer.cxx
+++ b/Source/cmLinkLineComputer.cxx
@@ -156,9 +156,11 @@ void cmLinkLineComputer::ComputeLinkPath(
type = cmStateEnums::ImportLibraryArtifact;
}
- linkPathNoBT += cmStrCat(
- " ", libPathFlag, item.Target->GetDirectory(cli.GetConfig(), type),
- libPathTerminator, " ");
+ linkPathNoBT +=
+ cmStrCat(" ", libPathFlag,
+ this->ConvertToOutputForExisting(
+ item.Target->GetDirectory(cli.GetConfig(), type)),
+ libPathTerminator, " ");
}
}
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 94d99b7..76c559f 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -60,6 +60,7 @@
#include "cmake.h"
#ifndef CMAKE_BOOTSTRAP
+# include "cmMakefileProfilingData.h"
# include "cmVariableWatch.h"
#endif
@@ -372,19 +373,30 @@ void cmMakefile::PrintCommandTrace(const cmListFileFunction& lff) const
class cmMakefileCall
{
public:
- cmMakefileCall(cmMakefile* mf, cmCommandContext const& cc,
+ cmMakefileCall(cmMakefile* mf, cmListFileFunction const& lff,
cmExecutionStatus& status)
: Makefile(mf)
{
cmListFileContext const& lfc = cmListFileContext::FromCommandContext(
- cc, this->Makefile->StateSnapshot.GetExecutionListFile());
+ lff, this->Makefile->StateSnapshot.GetExecutionListFile());
this->Makefile->Backtrace = this->Makefile->Backtrace.Push(lfc);
++this->Makefile->RecursionDepth;
this->Makefile->ExecutionStatusStack.push_back(&status);
+#if !defined(CMAKE_BOOTSTRAP)
+ if (this->Makefile->GetCMakeInstance()->IsProfilingEnabled()) {
+ this->Makefile->GetCMakeInstance()->GetProfilingOutput().StartEntry(lff,
+ lfc);
+ }
+#endif
}
~cmMakefileCall()
{
+#if !defined(CMAKE_BOOTSTRAP)
+ if (this->Makefile->GetCMakeInstance()->IsProfilingEnabled()) {
+ this->Makefile->GetCMakeInstance()->GetProfilingOutput().StopEntry();
+ }
+#endif
this->Makefile->ExecutionStatusStack.pop_back();
--this->Makefile->RecursionDepth;
this->Makefile->Backtrace = this->Makefile->Backtrace.Pop();
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index 9c6dca6..081e69d 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -317,6 +317,12 @@ public:
void AddCacheDefinition(const std::string& name, const char* value,
const char* doc, cmStateEnums::CacheEntryType type,
bool force = false);
+ void AddCacheDefinition(const std::string& name, const std::string& value,
+ const char* doc, cmStateEnums::CacheEntryType type,
+ bool force = false)
+ {
+ AddCacheDefinition(name, value.c_str(), doc, type, force);
+ }
/**
* Remove a variable definition from the build. This is not valid
diff --git a/Source/cmMakefileProfilingData.cxx b/Source/cmMakefileProfilingData.cxx
new file mode 100644
index 0000000..ea64132
--- /dev/null
+++ b/Source/cmMakefileProfilingData.cxx
@@ -0,0 +1,113 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmMakefileProfilingData.h"
+
+#include <chrono>
+#include <cstdint>
+#include <stdexcept>
+#include <vector>
+
+#include "cmsys/FStream.hxx"
+#include "cmsys/SystemInformation.hxx"
+
+#include "cm_jsoncpp_value.h"
+#include "cm_jsoncpp_writer.h"
+
+#include "cmListFileCache.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+
+cmMakefileProfilingData::cmMakefileProfilingData(
+ const std::string& profileStream)
+{
+ std::ios::openmode omode = std::ios::out | std::ios::trunc;
+ this->ProfileStream.open(profileStream.c_str(), omode);
+ Json::StreamWriterBuilder wbuilder;
+ this->JsonWriter =
+ std::unique_ptr<Json::StreamWriter>(wbuilder.newStreamWriter());
+ if (!this->ProfileStream.good()) {
+ throw std::runtime_error(std::string("Unable to open: ") + profileStream);
+ }
+
+ this->ProfileStream << "[";
+};
+
+cmMakefileProfilingData::~cmMakefileProfilingData() noexcept
+{
+ if (this->ProfileStream.good()) {
+ try {
+ this->ProfileStream << "]";
+ this->ProfileStream.close();
+ } catch (...) {
+ cmSystemTools::Error("Error writing profiling output!");
+ }
+ }
+}
+
+void cmMakefileProfilingData::StartEntry(const cmListFileFunction& lff,
+ cmListFileContext const& lfc)
+{
+ /* Do not try again if we previously failed to write to output. */
+ if (!this->ProfileStream.good()) {
+ return;
+ }
+
+ try {
+ if (this->ProfileStream.tellp() > 1) {
+ this->ProfileStream << ",";
+ }
+ cmsys::SystemInformation info;
+ Json::Value v;
+ v["ph"] = "B";
+ v["name"] = lff.Name.Original;
+ v["cat"] = "cmake";
+ v["ts"] = uint64_t(std::chrono::duration_cast<std::chrono::microseconds>(
+ std::chrono::steady_clock::now().time_since_epoch())
+ .count());
+ v["pid"] = static_cast<int>(info.GetProcessId());
+ v["tid"] = 0;
+ Json::Value argsValue;
+ if (!lff.Arguments.empty()) {
+ std::string args;
+ for (const auto& a : lff.Arguments) {
+ args += (args.empty() ? "" : " ") + a.Value;
+ }
+ argsValue["functionArgs"] = args;
+ }
+ argsValue["location"] = lfc.FilePath + ":" + std::to_string(lfc.Line);
+ v["args"] = argsValue;
+
+ this->JsonWriter->write(v, &this->ProfileStream);
+ } catch (std::ios_base::failure& fail) {
+ cmSystemTools::Error(
+ cmStrCat("Failed to write to profiling output: ", fail.what()));
+ } catch (...) {
+ cmSystemTools::Error("Error writing profiling output!");
+ }
+}
+
+void cmMakefileProfilingData::StopEntry()
+{
+ /* Do not try again if we previously failed to write to output. */
+ if (!this->ProfileStream.good()) {
+ return;
+ }
+
+ try {
+ this->ProfileStream << ",";
+ cmsys::SystemInformation info;
+ Json::Value v;
+ v["ph"] = "E";
+ v["ts"] = uint64_t(std::chrono::duration_cast<std::chrono::microseconds>(
+ std::chrono::steady_clock::now().time_since_epoch())
+ .count());
+ v["pid"] = static_cast<int>(info.GetProcessId());
+ v["tid"] = 0;
+ this->JsonWriter->write(v, &this->ProfileStream);
+ } catch (std::ios_base::failure& fail) {
+ cmSystemTools::Error(
+ cmStrCat("Failed to write to profiling output:", fail.what()));
+ } catch (...) {
+ cmSystemTools::Error("Error writing profiling output!");
+ }
+}
diff --git a/Source/cmMakefileProfilingData.h b/Source/cmMakefileProfilingData.h
new file mode 100644
index 0000000..1babd97
--- /dev/null
+++ b/Source/cmMakefileProfilingData.h
@@ -0,0 +1,29 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmMakefileProfilingData_h
+#define cmMakefileProfilingData_h
+#include <memory>
+#include <string>
+
+#include "cmsys/FStream.hxx"
+
+namespace Json {
+class StreamWriter;
+}
+
+class cmListFileContext;
+struct cmListFileFunction;
+
+class cmMakefileProfilingData
+{
+public:
+ cmMakefileProfilingData(const std::string&);
+ ~cmMakefileProfilingData() noexcept;
+ void StartEntry(const cmListFileFunction& lff, cmListFileContext const& lfc);
+ void StopEntry();
+
+private:
+ cmsys::ofstream ProfileStream;
+ std::unique_ptr<Json::StreamWriter> JsonWriter;
+};
+#endif
diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx
index a25fd42..2ec66d9 100644
--- a/Source/cmProjectCommand.cxx
+++ b/Source/cmProjectCommand.cxx
@@ -47,10 +47,10 @@ bool cmProjectCommand(std::vector<std::string> const& args,
mf.SetProjectName(projectName);
mf.AddCacheDefinition(projectName + "_BINARY_DIR",
- mf.GetCurrentBinaryDirectory().c_str(),
+ mf.GetCurrentBinaryDirectory(),
"Value Computed by CMake", cmStateEnums::STATIC);
mf.AddCacheDefinition(projectName + "_SOURCE_DIR",
- mf.GetCurrentSourceDirectory().c_str(),
+ mf.GetCurrentSourceDirectory(),
"Value Computed by CMake", cmStateEnums::STATIC);
mf.AddDefinition("PROJECT_BINARY_DIR", mf.GetCurrentBinaryDirectory());
@@ -66,7 +66,7 @@ bool cmProjectCommand(std::vector<std::string> const& args,
// will work.
if (!mf.GetDefinition("CMAKE_PROJECT_NAME") || mf.IsRootMakefile()) {
mf.AddDefinition("CMAKE_PROJECT_NAME", projectName);
- mf.AddCacheDefinition("CMAKE_PROJECT_NAME", projectName.c_str(),
+ mf.AddCacheDefinition("CMAKE_PROJECT_NAME", projectName,
"Value Computed by CMake", cmStateEnums::STATIC);
}
@@ -379,7 +379,7 @@ static void TopLevelCMakeVarCondSet(cmMakefile& mf, std::string const& name,
// CMakeLists.txt file, then go with the last one.
if (!mf.GetDefinition(name) || mf.IsRootMakefile()) {
mf.AddDefinition(name, value);
- mf.AddCacheDefinition(name, value.c_str(), "Value Computed by CMake",
+ mf.AddCacheDefinition(name, value, "Value Computed by CMake",
cmStateEnums::STATIC);
}
}
diff --git a/Source/cmSetCommand.cxx b/Source/cmSetCommand.cxx
index 5e2a146..d8927e8 100644
--- a/Source/cmSetCommand.cxx
+++ b/Source/cmSetCommand.cxx
@@ -149,8 +149,8 @@ bool cmSetCommand(std::vector<std::string> const& args,
// if it is meant to be in the cache then define it in the cache
if (cache) {
- status.GetMakefile().AddCacheDefinition(variable, value.c_str(), docstring,
- type, force);
+ status.GetMakefile().AddCacheDefinition(variable, value, docstring, type,
+ force);
} else {
// add the definition
status.GetMakefile().AddDefinition(variable, value);
diff --git a/Source/cmSiteNameCommand.cxx b/Source/cmSiteNameCommand.cxx
index d47f121..b2d905e 100644
--- a/Source/cmSiteNameCommand.cxx
+++ b/Source/cmSiteNameCommand.cxx
@@ -72,8 +72,7 @@ bool cmSiteNameCommand(std::vector<std::string> const& args,
}
#endif
status.GetMakefile().AddCacheDefinition(
- args[0], siteName.c_str(),
- "Name of the computer/site where compile is being run",
+ args[0], siteName, "Name of the computer/site where compile is being run",
cmStateEnums::STRING);
return true;
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 987f526..10515c2 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -1007,7 +1007,7 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf, std::string const& lib,
dependencies += ";";
dependencies += lib;
dependencies += ";";
- mf.AddCacheDefinition(targetEntry, dependencies.c_str(),
+ mf.AddCacheDefinition(targetEntry, dependencies,
"Dependencies for the target", cmStateEnums::STATIC);
}
}
diff --git a/Source/cmUtilitySourceCommand.cxx b/Source/cmUtilitySourceCommand.cxx
index a43165c..5865a19 100644
--- a/Source/cmUtilitySourceCommand.cxx
+++ b/Source/cmUtilitySourceCommand.cxx
@@ -102,15 +102,15 @@ bool cmUtilitySourceCommand(std::vector<std::string> const& args,
cmSystemTools::ReplaceString(utilityExecutable, "/./", "/");
// Enter the value into the cache.
- status.GetMakefile().AddCacheDefinition(
- cacheEntry, utilityExecutable.c_str(), "Path to an internal program.",
- cmStateEnums::FILEPATH);
+ status.GetMakefile().AddCacheDefinition(cacheEntry, utilityExecutable,
+ "Path to an internal program.",
+ cmStateEnums::FILEPATH);
// add a value into the cache that maps from the
// full path to the name of the project
cmSystemTools::ConvertToUnixSlashes(utilityExecutable);
- status.GetMakefile().AddCacheDefinition(
- utilityExecutable, utilityName.c_str(), "Executable to project name.",
- cmStateEnums::INTERNAL);
+ status.GetMakefile().AddCacheDefinition(utilityExecutable, utilityName,
+ "Executable to project name.",
+ cmStateEnums::INTERNAL);
return true;
}
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index f4b9f16..29ed61d 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -9,6 +9,7 @@
#include <initializer_list>
#include <iostream>
#include <sstream>
+#include <stdexcept>
#include <utility>
#include <cm/memory>
@@ -39,6 +40,9 @@
#include "cmLinkLineComputer.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
+#if !defined(CMAKE_BOOTSTRAP)
+# include "cmMakefileProfilingData.h"
+#endif
#include "cmMessenger.h"
#include "cmState.h"
#include "cmStateDirectory.h"
@@ -613,6 +617,10 @@ void cmake::SetArgs(const std::vector<std::string>& args)
{
bool haveToolset = false;
bool havePlatform = false;
+#if !defined(CMAKE_BOOTSTRAP)
+ std::string profilingFormat;
+ std::string profilingOutput;
+#endif
for (unsigned int i = 1; i < args.size(); ++i) {
std::string const& arg = args[i];
if (arg.find("-H", 0) == 0 || arg.find("-S", 0) == 0) {
@@ -839,6 +847,20 @@ void cmake::SetArgs(const std::vector<std::string>& args)
return;
}
this->SetGlobalGenerator(std::move(gen));
+#if !defined(CMAKE_BOOTSTRAP)
+ } else if (arg.find("--profiling-format", 0) == 0) {
+ profilingFormat = arg.substr(strlen("--profiling-format="));
+ if (profilingFormat.empty()) {
+ cmSystemTools::Error("No format specified for --profiling-format");
+ }
+ } else if (arg.find("--profiling-output", 0) == 0) {
+ profilingOutput = arg.substr(strlen("--profiling-output="));
+ profilingOutput = cmSystemTools::CollapseFullPath(profilingOutput);
+ cmSystemTools::ConvertToUnixSlashes(profilingOutput);
+ if (profilingOutput.empty()) {
+ cmSystemTools::Error("No path specified for --profiling-output");
+ }
+#endif
}
// no option assume it is the path to the source or an existing build
else {
@@ -856,6 +878,29 @@ void cmake::SetArgs(const std::vector<std::string>& args)
}
}
+#if !defined(CMAKE_BOOTSTRAP)
+ if (!profilingOutput.empty() || !profilingFormat.empty()) {
+ if (profilingOutput.empty()) {
+ cmSystemTools::Error(
+ "--profiling-format specified but no --profiling-output!");
+ return;
+ }
+ if (profilingFormat == "google-trace") {
+ try {
+ this->ProfilingOutput =
+ cm::make_unique<cmMakefileProfilingData>(profilingOutput);
+ } catch (std::runtime_error& e) {
+ cmSystemTools::Error(
+ cmStrCat("Could not start profiling: ", e.what()));
+ return;
+ }
+ } else {
+ cmSystemTools::Error("Invalid format specified for --profiling-format");
+ return;
+ }
+ }
+#endif
+
const bool haveSourceDir = !this->GetHomeDirectory().empty();
const bool haveBinaryDir = !this->GetHomeOutputDirectory().empty();
@@ -2952,3 +2997,15 @@ void cmake::SetDeprecatedWarningsAsErrors(bool b)
" and functions.",
cmStateEnums::INTERNAL);
}
+
+#if !defined(CMAKE_BOOTSTRAP)
+cmMakefileProfilingData& cmake::GetProfilingOutput()
+{
+ return *(this->ProfilingOutput);
+}
+
+bool cmake::IsProfilingEnabled() const
+{
+ return static_cast<bool>(this->ProfilingOutput);
+}
+#endif
diff --git a/Source/cmake.h b/Source/cmake.h
index 35425ec..58769fd 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -34,6 +34,9 @@ class cmFileTimeCache;
class cmGlobalGenerator;
class cmGlobalGeneratorFactory;
class cmMakefile;
+#if !defined(CMAKE_BOOTSTRAP)
+class cmMakefileProfilingData;
+#endif
class cmMessenger;
class cmVariableWatch;
struct cmDocumentationEntry;
@@ -549,6 +552,11 @@ public:
bool GetRegenerateDuringBuild() const { return this->RegenerateDuringBuild; }
+#if !defined(CMAKE_BOOTSTRAP)
+ cmMakefileProfilingData& GetProfilingOutput();
+ bool IsProfilingEnabled() const;
+#endif
+
protected:
void RunCheckForUnusedVariables();
int HandleDeleteCacheVariables(const std::string& var);
@@ -657,6 +665,10 @@ private:
void AppendGlobalGeneratorsDocumentation(std::vector<cmDocumentationEntry>&);
void AppendExtraGeneratorsDocumentation(std::vector<cmDocumentationEntry>&);
+
+#if !defined(CMAKE_BOOTSTRAP)
+ std::unique_ptr<cmMakefileProfilingData> ProfilingOutput;
+#endif
};
#define CMAKE_STANDARD_OPTIONS_TABLE \
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index 494d5d9..90d8ea6 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -93,6 +93,12 @@ const char* cmDocumentationOptions[][2] = {
{ "--check-system-vars",
"Find problems with variable usage in system "
"files." },
+# if !defined(CMAKE_BOOTSTRAP)
+ { "--profiling-format=<fmt>", "Output data for profiling CMake scripts." },
+ { "--profiling-output=<file>",
+ "Select an output path for the profiling data enabled through "
+ "--profiling-format." },
+# endif
{ nullptr, nullptr }
};