Merge branch 'master' into cmp0082-exclude-from-all

This commit is contained in:
Kyle Edwards
2021-05-24 13:57:40 -04:00
1081 changed files with 17081 additions and 5402 deletions
+4 -3
View File
@@ -44,7 +44,7 @@ endif()
if(NOT CMake_DEFAULT_RECURSION_LIMIT)
if(DEFINED ENV{DASHBOARD_TEST_FROM_CTEST})
set(CMake_DEFAULT_RECURSION_LIMIT 100)
elseif(MINGW)
elseif(MINGW OR MSYS)
set(CMake_DEFAULT_RECURSION_LIMIT 400)
elseif(WIN32 AND CMAKE_C_COMPILER_ID STREQUAL "IntelLLVM")
set(CMake_DEFAULT_RECURSION_LIMIT 600)
@@ -198,6 +198,8 @@ set(SRCS
cmCMakePath.cxx
cmCMakePresetsFile.cxx
cmCMakePresetsFile.h
cmCMakePresetsFileInternal.h
cmCMakePresetsFileReadJSON.cxx
cmCommandArgumentParserHelper.cxx
cmCommonTargetGenerator.cxx
cmCommonTargetGenerator.h
@@ -636,6 +638,7 @@ set(SRCS
cmMathCommand.h
cmMessageCommand.cxx
cmMessageCommand.h
cmMessageMetadata.h
cmOptionCommand.cxx
cmOptionCommand.h
cmOutputRequiredFilesCommand.cxx
@@ -785,8 +788,6 @@ if (WIN32)
cmVisualStudioGeneratorOptions.cxx
cmVisualStudio10TargetGenerator.h
cmVisualStudio10TargetGenerator.cxx
cmVisualStudio10ToolsetOptions.h
cmVisualStudio10ToolsetOptions.cxx
cmLocalVisualStudio10Generator.cxx
cmLocalVisualStudio10Generator.h
cmGlobalVisualStudio10Generator.h
+1 -1
View File
@@ -1,7 +1,7 @@
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
set(CMake_VERSION_MINOR 20)
set(CMake_VERSION_PATCH 2)
set(CMake_VERSION_PATCH 20210524)
#set(CMake_VERSION_RC 0)
set(CMake_VERSION_IS_DIRTY 0)
+76 -31
View File
@@ -7,6 +7,8 @@
#include <sstream>
#include <utility>
#include <cm/string_view>
#include "cmCPackComponentGroup.h"
#include "cmCPackIFWCommon.h"
#include "cmCPackIFWGenerator.h"
@@ -30,44 +32,67 @@ cmCPackIFWPackage::DependenceStruct::DependenceStruct() = default;
cmCPackIFWPackage::DependenceStruct::DependenceStruct(
const std::string& dependence)
{
// Search compare section
size_t pos = std::string::npos;
if ((pos = dependence.find("<=")) != std::string::npos) {
this->Compare.Type = cmCPackIFWPackage::CompareLessOrEqual;
this->Compare.Value = dependence.substr(pos + 2);
} else if ((pos = dependence.find(">=")) != std::string::npos) {
this->Compare.Type = cmCPackIFWPackage::CompareGreaterOrEqual;
this->Compare.Value = dependence.substr(pos + 2);
} else if ((pos = dependence.find('<')) != std::string::npos) {
this->Compare.Type = cmCPackIFWPackage::CompareLess;
this->Compare.Value = dependence.substr(pos + 1);
} else if ((pos = dependence.find('=')) != std::string::npos) {
this->Compare.Type = cmCPackIFWPackage::CompareEqual;
this->Compare.Value = dependence.substr(pos + 1);
} else if ((pos = dependence.find('>')) != std::string::npos) {
this->Compare.Type = cmCPackIFWPackage::CompareGreater;
this->Compare.Value = dependence.substr(pos + 1);
} else if ((pos = dependence.find('-')) != std::string::npos) {
this->Compare.Type = cmCPackIFWPackage::CompareNone;
this->Compare.Value = dependence.substr(pos + 1);
// Preferred format is name and version are separated by a colon (:), but
// note that this is only supported with QtIFW 3.1 or later. Backward
// compatibility allows a hyphen (-) as a separator instead, but names then
// cannot contain a hyphen.
size_t pos;
if ((pos = dependence.find(':')) == std::string::npos) {
pos = dependence.find('-');
}
size_t dashPos = dependence.find('-');
if (dashPos != std::string::npos) {
pos = dashPos;
if (pos != std::string::npos) {
this->Name = dependence.substr(0, pos);
++pos;
if (pos == dependence.size()) {
// Nothing after the separator. Treat this as no version constraint.
return;
}
const auto versionPart =
cm::string_view(dependence.data() + pos, dependence.size() - pos);
if (cmHasLiteralPrefix(versionPart, "<=")) {
this->Compare.Type = cmCPackIFWPackage::CompareLessOrEqual;
this->Compare.Value = std::string(versionPart.substr(2));
} else if (cmHasLiteralPrefix(versionPart, ">=")) {
this->Compare.Type = cmCPackIFWPackage::CompareGreaterOrEqual;
this->Compare.Value = std::string(versionPart.substr(2));
} else if (cmHasPrefix(versionPart, '<')) {
this->Compare.Type = cmCPackIFWPackage::CompareLess;
this->Compare.Value = std::string(versionPart.substr(1));
} else if (cmHasPrefix(versionPart, '=')) {
this->Compare.Type = cmCPackIFWPackage::CompareEqual;
this->Compare.Value = std::string(versionPart.substr(1));
} else if (cmHasPrefix(versionPart, '>')) {
this->Compare.Type = cmCPackIFWPackage::CompareGreater;
this->Compare.Value = std::string(versionPart.substr(1));
} else {
// We found no operator but a version specification is still expected to
// follow. The default behavior is to treat this the same as =. We
// explicitly record that as our type (it simplifies our logic a little
// and is also clearer).
this->Compare.Type = cmCPackIFWPackage::CompareEqual;
this->Compare.Value = std::string(versionPart);
}
} else {
this->Name = dependence;
}
this->Name = dependence.substr(0, pos);
}
std::string cmCPackIFWPackage::DependenceStruct::NameWithCompare() const
{
if (this->Compare.Type == cmCPackIFWPackage::CompareNone) {
return this->Name;
}
std::string result = this->Name;
if (this->Compare.Type != cmCPackIFWPackage::CompareNone ||
!this->Compare.Value.empty()) {
if (this->Name.find('-') != std::string::npos) {
// When a name contains a hyphen, we must use a colon after the name to
// prevent the hyphen from being parsed by QtIFW as the separator between
// the name and the version. Note that a colon is only supported with
// QtIFW 3.1 or later.
result += ":";
} else if (this->Compare.Type != cmCPackIFWPackage::CompareNone ||
!this->Compare.Value.empty()) {
// No hyphen in the name and we know a version part will follow. Use a
// hyphen as a separator since this works for all QtIFW versions.
result += "-";
}
@@ -609,6 +634,9 @@ void cmCPackIFWPackage::GeneratePackageFile()
}
// Dependencies
const bool hyphensInNamesUnsupported = this->Generator &&
!this->Generator->FrameworkVersion.empty() && this->IsVersionLess("3.1");
bool warnUnsupportedNames = false;
std::set<DependenceStruct> compDepSet;
for (DependenceStruct* ad : this->AlienDependencies) {
compDepSet.insert(*ad);
@@ -620,9 +648,13 @@ void cmCPackIFWPackage::GeneratePackageFile()
if (!compDepSet.empty()) {
std::ostringstream dependencies;
auto it = compDepSet.begin();
warnUnsupportedNames |=
hyphensInNamesUnsupported && it->Name.find('-') != std::string::npos;
dependencies << it->NameWithCompare();
++it;
while (it != compDepSet.end()) {
warnUnsupportedNames |=
hyphensInNamesUnsupported && it->Name.find('-') != std::string::npos;
dependencies << "," << it->NameWithCompare();
++it;
}
@@ -638,15 +670,28 @@ void cmCPackIFWPackage::GeneratePackageFile()
if (!compAutoDepSet.empty()) {
std::ostringstream dependencies;
auto it = compAutoDepSet.begin();
warnUnsupportedNames |=
hyphensInNamesUnsupported && it->Name.find('-') != std::string::npos;
dependencies << it->NameWithCompare();
++it;
while (it != compAutoDepSet.end()) {
warnUnsupportedNames |=
hyphensInNamesUnsupported && it->Name.find('-') != std::string::npos;
dependencies << "," << it->NameWithCompare();
++it;
}
xout.Element("AutoDependOn", dependencies.str());
}
if (warnUnsupportedNames) {
cmCPackIFWLogger(
WARNING,
"The dependencies for component \""
<< this->Name << "\" specify names that contain hyphens. "
<< "This requires QtIFW 3.1 or later, but you are using version "
<< this->Generator->FrameworkVersion << std::endl);
}
// Licenses (copy to meta dir)
std::vector<std::string> licenses = this->Licenses;
for (size_t i = 1; i < licenses.size(); i += 2) {
+11 -28
View File
@@ -2,14 +2,13 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCPackArchiveGenerator.h"
#include <cstdlib>
#include <cstring>
#include <map>
#include <ostream>
#include <utility>
#include <vector>
#include <cm3p/archive.h>
#include "cmCPackComponentGroup.h"
#include "cmCPackGenerator.h"
#include "cmCPackLog.h"
@@ -154,15 +153,9 @@ int cmCPackArchiveGenerator::addOneComponentToArchive(
<< (filename) << ">." << std::endl); \
return 0; \
} \
cmArchiveWrite archive(gf, this->Compress, this->ArchiveFormat); \
cmArchiveWrite archive(gf, this->Compress, this->ArchiveFormat, 0, \
this->GetThreadCount()); \
do { \
if (!this->SetArchiveOptions(&archive)) { \
cmCPackLogger(cmCPackLog::LOG_ERROR, \
"Problem to set archive options <" \
<< (filename) << ">, ERROR = " << (archive).GetError() \
<< std::endl); \
return 0; \
} \
if (!archive.Open()) { \
cmCPackLogger(cmCPackLog::LOG_ERROR, \
"Problem to open archive <" \
@@ -346,26 +339,16 @@ bool cmCPackArchiveGenerator::SupportsComponentInstallation() const
return this->IsOn("CPACK_ARCHIVE_COMPONENT_INSTALL");
}
bool cmCPackArchiveGenerator::SetArchiveOptions(cmArchiveWrite* archive)
int cmCPackArchiveGenerator::GetThreadCount() const
{
#if ARCHIVE_VERSION_NUMBER >= 3004000
// Upstream fixed an issue with their integer parsing in 3.4.0 which would
// cause spurious errors to be raised from `strtoull`.
if (this->Compress == cmArchiveWrite::CompressXZ) {
const char* threads = "1";
int threads = 1;
// CPACK_ARCHIVE_THREADS overrides CPACK_THREADS
if (this->IsSet("CPACK_ARCHIVE_THREADS")) {
threads = this->GetOption("CPACK_ARCHIVE_THREADS");
} else if (this->IsSet("CPACK_THREADS")) {
threads = this->GetOption("CPACK_THREADS");
}
if (!archive->SetFilterOption("xz", "threads", threads)) {
return false;
}
// CPACK_ARCHIVE_THREADS overrides CPACK_THREADS
if (this->IsSet("CPACK_ARCHIVE_THREADS")) {
threads = std::atoi(this->GetOption("CPACK_ARCHIVE_THREADS"));
} else if (this->IsSet("CPACK_THREADS")) {
threads = std::atoi(this->GetOption("CPACK_THREADS"));
}
#endif
return true;
return threads;
}
+1 -1
View File
@@ -85,7 +85,7 @@ private:
return this->OutputExtension.c_str();
}
bool SetArchiveOptions(cmArchiveWrite* archive);
int GetThreadCount() const;
private:
cmArchiveWrite::Compress Compress;
-6
View File
@@ -130,11 +130,6 @@ DebGenerator::DebGenerator(
"Unrecognized number of threads: " << numThreads
<< std::endl);
}
if (this->NumThreads < 0) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Number of threads cannot be negative" << std::endl);
}
}
bool DebGenerator::generate() const
@@ -172,7 +167,6 @@ void DebGenerator::generateControlFile() const
unsigned long totalSize = 0;
{
std::string dirName = cmStrCat(this->TemporaryDir, '/');
for (std::string const& file : this->PackageFiles) {
totalSize += cmSystemTools::FileLength(file);
}
+7 -2
View File
@@ -273,6 +273,11 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
? this->GetOption("CPACK_DMG_FORMAT")
: "UDZO";
const std::string cpack_dmg_filesystem =
this->GetOption("CPACK_DMG_FILESYSTEM")
? this->GetOption("CPACK_DMG_FILESYSTEM")
: "HFS+";
// Get optional arguments ...
std::string cpack_license_file =
this->GetOption("CPACK_RESOURCE_FILE_LICENSE")
@@ -319,7 +324,7 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
staging << src_dir;
// Add a symlink to /Applications so users can drag-and-drop the bundle
// into it unless this behaviour was disabled
// into it unless this behavior was disabled
if (!cpack_dmg_disable_applications_symlink) {
std::ostringstream application_link;
application_link << staging.str() << "/Applications";
@@ -418,7 +423,7 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
temp_image_command << " -ov";
temp_image_command << " -srcfolder \"" << staging.str() << "\"";
temp_image_command << " -volname \"" << cpack_dmg_volume_name << "\"";
temp_image_command << " -fs HFS+";
temp_image_command << " -fs \"" << cpack_dmg_filesystem << "\"";
temp_image_command << " -format " << temp_image_format;
temp_image_command << " \"" << temp_image << "\"";
+3 -2
View File
@@ -384,7 +384,8 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories(
for (std::string const& gf : this->files) {
bool skip = false;
std::string inFile = gf;
if (cmSystemTools::FileIsDirectory(gf)) {
if (cmSystemTools::FileIsDirectory(gf) &&
!cmSystemTools::FileIsSymlink(gf)) {
inFile += '/';
}
for (cmsys::RegularExpression& reg : ignoreFilesRegex) {
@@ -693,7 +694,7 @@ int cmCPackGenerator::RunPreinstallTarget(
// Does this generator require pre-install?
if (const char* preinstall = globalGenerator->GetPreinstallTargetName()) {
std::string buildCommand = globalGenerator->GenerateCMakeBuildCommand(
preinstall, buildConfig, "", false);
preinstall, buildConfig, "", "", false);
cmCPackLogger(cmCPackLog::LOG_DEBUG,
"- Install command: " << buildCommand << std::endl);
cmCPackLogger(cmCPackLog::LOG_OUTPUT,
+3 -1
View File
@@ -437,7 +437,9 @@ int cmCPackNSISGenerator::InitializeInternal()
}
#endif
nsisPath = cmSystemTools::FindProgram("makensis", path, false);
this->SetOptionIfNotSet("CPACK_NSIS_EXECUTABLE", "makensis");
nsisPath = cmSystemTools::FindProgram(
this->GetOption("CPACK_NSIS_EXECUTABLE"), path, false);
if (nsisPath.empty()) {
cmCPackLogger(
+7 -6
View File
@@ -51,15 +51,16 @@ int cmCPackSTGZGenerator::PackageFiles()
* so we must iterate over generated packages.
*/
for (std::string const& pfn : this->packageFileNames) {
retval &= cmSystemTools::SetPermissions(pfn.c_str(),
retval &= static_cast<bool>(
cmSystemTools::SetPermissions(pfn.c_str(),
#if defined(_MSC_VER) || defined(__MINGW32__)
S_IREAD | S_IWRITE | S_IEXEC
S_IREAD | S_IWRITE | S_IEXEC
#else
S_IRUSR | S_IWUSR | S_IXUSR |
S_IRGRP | S_IWGRP | S_IXGRP |
S_IROTH | S_IWOTH | S_IXOTH
S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP |
S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH |
S_IXOTH
#endif
);
));
}
return retval;
}
+1 -1
View File
@@ -341,7 +341,7 @@ int main(int argc, char const* const* argv)
cmMakefile* mf = &globalMF;
cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE,
"Specified generator: " << gen << std::endl);
if (parsed && !mf->GetDefinition("CPACK_PACKAGE_NAME")) {
if (!mf->GetDefinition("CPACK_PACKAGE_NAME")) {
cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
"CPack project name not specified" << std::endl);
parsed = 0;
+3 -1
View File
@@ -19,6 +19,8 @@
#include "cmWorkingDirectory.h"
#include "cmake.h"
struct cmMessageMetadata;
cmCTestBuildAndTestHandler::cmCTestBuildAndTestHandler()
{
this->BuildTwoConfig = false;
@@ -125,7 +127,7 @@ public:
: CM(cm)
{
cmSystemTools::SetMessageCallback(
[&s](const std::string& msg, const char* /*unused*/) {
[&s](const std::string& msg, const cmMessageMetadata& /* unused */) {
s += msg;
s += "\n";
});
+3 -2
View File
@@ -27,6 +27,7 @@ void cmCTestBuildCommand::BindArguments()
this->Bind("CONFIGURATION"_s, this->Configuration);
this->Bind("FLAGS"_s, this->Flags);
this->Bind("PROJECT_NAME"_s, this->ProjectName);
this->Bind("PARALLEL_LEVEL"_s, this->ParallelLevel);
}
cmCTestBuildCommand::~cmCTestBuildCommand() = default;
@@ -98,8 +99,8 @@ cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler()
std::string dir = this->CTest->GetCTestConfiguration("BuildDirectory");
std::string buildCommand =
this->GlobalGenerator->GenerateCMakeBuildCommand(
cmakeBuildTarget, cmakeBuildConfiguration, cmakeBuildAdditionalFlags,
this->Makefile->IgnoreErrorsCMP0061());
cmakeBuildTarget, cmakeBuildConfiguration, this->ParallelLevel,
cmakeBuildAdditionalFlags, this->Makefile->IgnoreErrorsCMP0061());
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"SetMakeCommand:" << buildCommand << "\n",
this->Quiet);
+1
View File
@@ -60,4 +60,5 @@ protected:
std::string Configuration;
std::string Flags;
std::string ProjectName;
std::string ParallelLevel;
};
+2 -3
View File
@@ -3,7 +3,6 @@
#include "cmCTestBuildHandler.h"
#include <cstdlib>
#include <cstring>
#include <set>
#include <utility>
@@ -657,14 +656,14 @@ bool cmCTestBuildHandler::IsLaunchedErrorFile(const char* fname)
{
// error-{hash}.xml
return (cmHasLiteralPrefix(fname, "error-") &&
strcmp(fname + strlen(fname) - 4, ".xml") == 0);
cmHasLiteralSuffix(fname, ".xml"));
}
bool cmCTestBuildHandler::IsLaunchedWarningFile(const char* fname)
{
// warning-{hash}.xml
return (cmHasLiteralPrefix(fname, "warning-") &&
strcmp(fname + strlen(fname) - 4, ".xml") == 0);
cmHasLiteralSuffix(fname, ".xml"));
}
//######################################################################
@@ -16,7 +16,7 @@ bool cmCTestEmptyBinaryDirectoryCommand::InitialPass(
return false;
}
if (!cmCTestScriptHandler::EmptyBinaryDirectory(args[0].c_str())) {
if (!cmCTestScriptHandler::EmptyBinaryDirectory(args[0])) {
std::ostringstream ostr;
ostr << "problem removing the binary directory: " << args[0];
this->SetError(ostr.str());
+40 -14
View File
@@ -21,32 +21,47 @@ cmCTestGenericHandler::cmCTestGenericHandler()
cmCTestGenericHandler::~cmCTestGenericHandler() = default;
void cmCTestGenericHandler::SetOption(const std::string& op, const char* value)
/* Modify the given `map`, setting key `op` to `value` if `value`
* is non-null, otherwise removing key `op` (if it exists).
*/
static void SetMapValue(cmCTestGenericHandler::t_StringToString& map,
const std::string& op, const char* value)
{
if (!value) {
auto remit = this->Options.find(op);
if (remit != this->Options.end()) {
this->Options.erase(remit);
}
map.erase(op);
return;
}
this->Options[op] = value;
map[op] = value;
}
void cmCTestGenericHandler::SetOption(const std::string& op, const char* value)
{
SetMapValue(this->Options, op, value);
}
void cmCTestGenericHandler::SetPersistentOption(const std::string& op,
const char* value)
{
this->SetOption(op, value);
if (!value) {
auto remit = this->PersistentOptions.find(op);
if (remit != this->PersistentOptions.end()) {
this->PersistentOptions.erase(remit);
}
return;
}
SetMapValue(this->PersistentOptions, op, value);
}
this->PersistentOptions[op] = value;
void cmCTestGenericHandler::AddMultiOption(const std::string& op,
const std::string& value)
{
if (!value.empty()) {
this->MultiOptions[op].emplace_back(value);
}
}
void cmCTestGenericHandler::AddPersistentMultiOption(const std::string& op,
const std::string& value)
{
if (!value.empty()) {
this->MultiOptions[op].emplace_back(value);
this->PersistentMultiOptions[op].emplace_back(value);
}
}
void cmCTestGenericHandler::Initialize()
@@ -68,6 +83,17 @@ const char* cmCTestGenericHandler::GetOption(const std::string& op)
return remit->second.c_str();
}
std::vector<std::string> cmCTestGenericHandler::GetMultiOption(
const std::string& optionName) const
{
// Avoid inserting a key, which MultiOptions[op] would do.
auto remit = this->MultiOptions.find(optionName);
if (remit == this->MultiOptions.end()) {
return {};
}
return remit->second;
}
bool cmCTestGenericHandler::StartResultingXML(cmCTest::Part part,
const char* name,
cmGeneratedFileStream& xofs)
+31 -3
View File
@@ -13,7 +13,6 @@
#include "cmCTest.h"
#include "cmSystemTools.h"
class cmCTestCommand;
class cmGeneratedFileStream;
class cmMakefile;
@@ -72,12 +71,40 @@ public:
virtual ~cmCTestGenericHandler();
using t_StringToString = std::map<std::string, std::string>;
using t_StringToMultiString =
std::map<std::string, std::vector<std::string>>;
/**
* Options collect a single value from flags; passing the
* flag multiple times on the command-line *overwrites* values,
* and only the last one specified counts. Set an option to
* nullptr to "unset" it.
*
* The value is stored as a string. The values set for single
* and multi-options (see below) live in different spaces,
* so calling a single-getter for a key that has only been set
* as a multi-value will return nullptr.
*/
void SetPersistentOption(const std::string& op, const char* value);
void SetOption(const std::string& op, const char* value);
const char* GetOption(const std::string& op);
void SetCommand(cmCTestCommand* command) { this->Command = command; }
/**
* Multi-Options collect one or more values from flags; passing
* the flag multiple times on the command-line *adds* values,
* rather than overwriting the previous values.
*
* Adding an empty value does nothing.
*
* The value is stored as a vector of strings. The values set for single
* (see above) and multi-options live in different spaces,
* so calling a multi-getter for a key that has only been set
* as a single-value will return an empty vector.
*/
void AddPersistentMultiOption(const std::string& optionName,
const std::string& value);
void AddMultiOption(const std::string& optionName, const std::string& value);
std::vector<std::string> GetMultiOption(const std::string& op) const;
void SetSubmitIndex(int idx) { this->SubmitIndex = idx; }
int GetSubmitIndex() { return this->SubmitIndex; }
@@ -100,8 +127,9 @@ protected:
cmCTest* CTest;
t_StringToString Options;
t_StringToString PersistentOptions;
t_StringToMultiString MultiOptions;
t_StringToMultiString PersistentMultiOptions;
t_StringToString LogFileNames;
cmCTestCommand* Command;
int SubmitIndex;
};
+1 -1
View File
@@ -14,7 +14,7 @@ void cmCTestMemCheckCommand::BindArguments()
this->Bind("DEFECT_COUNT"_s, this->DefectCount);
}
cmCTestGenericHandler* cmCTestMemCheckCommand::InitializeActualHandler()
cmCTestTestHandler* cmCTestMemCheckCommand::InitializeActualHandler()
{
cmCTestMemCheckHandler* handler = this->CTest->GetMemCheckHandler();
handler->Initialize();
+2 -1
View File
@@ -13,6 +13,7 @@
#include "cmCommand.h"
class cmCTestGenericHandler;
class cmCTestTestHandler;
/** \class cmCTestMemCheck
* \brief Run a ctest script
@@ -36,7 +37,7 @@ public:
protected:
void BindArguments() override;
cmCTestGenericHandler* InitializeActualHandler() override;
cmCTestTestHandler* InitializeActualHandler() override;
void ProcessAdditionalValues(cmCTestGenericHandler* handler) override;
+5 -5
View File
@@ -587,24 +587,24 @@ void cmCTestMultiProcessHandler::StartNextTests()
onlyRunSerialTestsLeft = false;
}
}
cmCTestLog(this->CTest, HANDLER_OUTPUT, "***** WAITING, ");
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "***** WAITING, ");
if (this->SerialTestRunning) {
cmCTestLog(this->CTest, HANDLER_OUTPUT,
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"Waiting for RUN_SERIAL test to finish.");
} else if (onlyRunSerialTestsLeft) {
cmCTestLog(this->CTest, HANDLER_OUTPUT,
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"Only RUN_SERIAL tests remain, awaiting available slot.");
} else {
/* clang-format off */
cmCTestLog(this->CTest, HANDLER_OUTPUT,
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"System Load: " << systemLoad << ", "
"Max Allowed Load: " << this->TestLoad << ", "
"Smallest test " << testWithMinProcessors <<
" requires " << minProcessorsRequired);
/* clang-format on */
}
cmCTestLog(this->CTest, HANDLER_OUTPUT, "*****" << std::endl);
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "*****" << std::endl);
// Wait between 1 and 5 seconds before trying again.
unsigned int milliseconds = (cmSystemTools::RandomSeed() % 5 + 1) * 1000;
+2 -2
View File
@@ -37,8 +37,8 @@ bool cmCTestRunScriptCommand::InitialPass(std::vector<std::string> const& args,
++i;
} else {
int ret;
cmCTestScriptHandler::RunScript(this->CTest, this->Makefile,
args[i].c_str(), !np, &ret);
cmCTestScriptHandler::RunScript(this->CTest, this->Makefile, args[i],
!np, &ret);
this->Makefile->AddDefinition(returnVariable, std::to_string(ret));
}
}
+11 -14
View File
@@ -4,7 +4,6 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <map>
#include <ratio>
#include <sstream>
@@ -91,7 +90,7 @@ void cmCTestScriptHandler::Initialize()
cmCTestScriptHandler::~cmCTestScriptHandler() = default;
// just adds an argument to the vector
void cmCTestScriptHandler::AddConfigurationScript(const char* script,
void cmCTestScriptHandler::AddConfigurationScript(const std::string& script,
bool pscope)
{
this->ConfigurationScripts.emplace_back(script);
@@ -676,7 +675,7 @@ int cmCTestScriptHandler::RunConfigurationDashboard()
// clear the binary directory?
if (this->EmptyBinDir) {
if (!cmCTestScriptHandler::EmptyBinaryDirectory(this->BinaryDir.c_str())) {
if (!cmCTestScriptHandler::EmptyBinaryDirectory(this->BinaryDir)) {
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Problem removing the binary directory" << std::endl);
}
@@ -724,8 +723,8 @@ int cmCTestScriptHandler::RunConfigurationDashboard()
// put the initial cache into the bin dir
if (!this->InitialCache.empty()) {
if (!cmCTestScriptHandler::WriteInitialCache(this->BinaryDir.c_str(),
this->InitialCache.c_str())) {
if (!cmCTestScriptHandler::WriteInitialCache(this->BinaryDir,
this->InitialCache)) {
this->RestoreBackupDirectories();
return 9;
}
@@ -812,8 +811,8 @@ int cmCTestScriptHandler::RunConfigurationDashboard()
return 0;
}
bool cmCTestScriptHandler::WriteInitialCache(const char* directory,
const char* text)
bool cmCTestScriptHandler::WriteInitialCache(const std::string& directory,
const std::string& text)
{
std::string cacheFile = cmStrCat(directory, "/CMakeCache.txt");
cmGeneratedFileStream fout(cacheFile);
@@ -821,9 +820,7 @@ bool cmCTestScriptHandler::WriteInitialCache(const char* directory,
return false;
}
if (text != nullptr) {
fout.write(text, strlen(text));
}
fout.write(text.data(), text.size());
// Make sure the operating system has finished writing the file
// before closing it. This will ensure the file is finished before
@@ -852,7 +849,7 @@ void cmCTestScriptHandler::RestoreBackupDirectories()
}
bool cmCTestScriptHandler::RunScript(cmCTest* ctest, cmMakefile* mf,
const char* sname, bool InProcess,
const std::string& sname, bool InProcess,
int* returnValue)
{
auto sh = cm::make_unique<cmCTestScriptHandler>();
@@ -866,10 +863,10 @@ bool cmCTestScriptHandler::RunScript(cmCTest* ctest, cmMakefile* mf,
return true;
}
bool cmCTestScriptHandler::EmptyBinaryDirectory(const char* sname)
bool cmCTestScriptHandler::EmptyBinaryDirectory(const std::string& sname)
{
// try to avoid deleting root
if (!sname || strlen(sname) < 2) {
if (sname.size() < 2) {
return false;
}
@@ -924,7 +921,7 @@ bool cmCTestScriptHandler::TryToRemoveBinaryDirectoryOnce(
}
}
return cmSystemTools::RemoveADirectory(directoryPath);
return static_cast<bool>(cmSystemTools::RemoveADirectory(directoryPath));
}
cmDuration cmCTestScriptHandler::GetRemainingTimeAllowed()
+7 -5
View File
@@ -62,7 +62,7 @@ public:
/**
* Add a script to run, and if is should run in the current process
*/
void AddConfigurationScript(const char*, bool pscope);
void AddConfigurationScript(const std::string&, bool pscope);
/**
* Run a dashboard using a specified confiuration script
@@ -72,19 +72,21 @@ public:
/*
* Run a script
*/
static bool RunScript(cmCTest* ctest, cmMakefile* mf, const char* script,
bool InProcess, int* returnValue);
static bool RunScript(cmCTest* ctest, cmMakefile* mf,
const std::string& script, bool InProcess,
int* returnValue);
int RunCurrentScript();
/*
* Empty Binary Directory
*/
static bool EmptyBinaryDirectory(const char* dir);
static bool EmptyBinaryDirectory(const std::string& dir);
/*
* Write an initial CMakeCache.txt from the given contents.
*/
static bool WriteInitialCache(const char* directory, const char* text);
static bool WriteInitialCache(const std::string& directory,
const std::string& text);
/*
* Some elapsed time handling functions
+10 -6
View File
@@ -9,7 +9,6 @@
#include <cmext/string_view>
#include "cmCTest.h"
#include "cmCTestGenericHandler.h"
#include "cmCTestTestHandler.h"
#include "cmDuration.h"
#include "cmMakefile.h"
@@ -36,6 +35,7 @@ void cmCTestTestCommand::BindArguments()
this->Bind("TEST_LOAD"_s, this->TestLoad);
this->Bind("RESOURCE_SPEC_FILE"_s, this->ResourceSpecFile);
this->Bind("STOP_ON_FAILURE"_s, this->StopOnFailure);
this->Bind("OUTPUT_JUNIT"_s, this->OutputJUnit);
}
cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler()
@@ -60,7 +60,7 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler()
this->ResourceSpecFile = *resourceSpecFile;
}
cmCTestGenericHandler* handler = this->InitializeActualHandler();
cmCTestTestHandler* handler = this->InitializeActualHandler();
if (!this->Start.empty() || !this->End.empty() || !this->Stride.empty()) {
handler->SetOption(
"TestsToRunInformation",
@@ -73,11 +73,11 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler()
handler->SetOption("IncludeRegularExpression", this->Include.c_str());
}
if (!this->ExcludeLabel.empty()) {
handler->SetOption("ExcludeLabelRegularExpression",
this->ExcludeLabel.c_str());
handler->AddMultiOption("ExcludeLabelRegularExpression",
this->ExcludeLabel);
}
if (!this->IncludeLabel.empty()) {
handler->SetOption("LabelRegularExpression", this->IncludeLabel.c_str());
handler->AddMultiOption("LabelRegularExpression", this->IncludeLabel);
}
if (!this->ExcludeFixture.empty()) {
handler->SetOption("ExcludeFixtureRegularExpression",
@@ -140,11 +140,15 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler()
*labelsForSubprojects, this->Quiet);
}
if (!this->OutputJUnit.empty()) {
handler->SetJUnitXMLFileName(this->OutputJUnit);
}
handler->SetQuiet(this->Quiet);
return handler;
}
cmCTestGenericHandler* cmCTestTestCommand::InitializeActualHandler()
cmCTestTestHandler* cmCTestTestCommand::InitializeActualHandler()
{
cmCTestTestHandler* handler = this->CTest->GetTestHandler();
handler->Initialize();
+3 -1
View File
@@ -13,6 +13,7 @@
#include "cmCommand.h"
class cmCTestGenericHandler;
class cmCTestTestHandler;
/** \class cmCTestTest
* \brief Run a ctest script
@@ -40,7 +41,7 @@ public:
protected:
void BindArguments() override;
virtual cmCTestGenericHandler* InitializeActualHandler();
virtual cmCTestTestHandler* InitializeActualHandler();
cmCTestGenericHandler* InitializeHandler() override;
std::string Start;
@@ -59,5 +60,6 @@ protected:
std::string StopTime;
std::string TestLoad;
std::string ResourceSpecFile;
std::string OutputJUnit;
bool StopOnFailure = false;
};
+192 -49
View File
@@ -42,6 +42,7 @@
#include "cmStateSnapshot.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTimestamp.h"
#include "cmWorkingDirectory.h"
#include "cmXMLWriter.h"
#include "cmake.h"
@@ -287,8 +288,6 @@ cmCTestTestHandler::cmCTestTestHandler()
{
this->UseUnion = false;
this->UseIncludeLabelRegExpFlag = false;
this->UseExcludeLabelRegExpFlag = false;
this->UseIncludeRegExpFlag = false;
this->UseExcludeRegExpFlag = false;
this->UseExcludeRegExpFirst = false;
@@ -301,6 +300,9 @@ cmCTestTestHandler::cmCTestTestHandler()
this->LogFile = nullptr;
// Support for JUnit XML output.
this->JUnitXMLFileName = "";
// regex to detect <DartMeasurement>...</DartMeasurement>
this->DartStuff.compile("(<DartMeasurement.*/DartMeasurement[a-zA-Z]*>)");
// regex to detect each individual <DartMeasurement>...</DartMeasurement>
@@ -327,13 +329,11 @@ void cmCTestTestHandler::Initialize()
this->TestsToRun.clear();
this->UseIncludeLabelRegExpFlag = false;
this->UseExcludeLabelRegExpFlag = false;
this->UseIncludeRegExpFlag = false;
this->UseExcludeRegExpFlag = false;
this->UseExcludeRegExpFirst = false;
this->IncludeLabelRegularExpression = "";
this->ExcludeLabelRegularExpression = "";
this->IncludeLabelRegularExpressions.clear();
this->ExcludeLabelRegularExpressions.clear();
this->IncludeRegExp.clear();
this->ExcludeRegExp.clear();
this->ExcludeFixtureRegExp.clear();
@@ -460,6 +460,10 @@ int cmCTestTestHandler::ProcessHandler()
return 1;
}
if (!this->WriteJUnitXML()) {
return 1;
}
if (!this->PostProcessHandler()) {
this->LogFile = nullptr;
return -1;
@@ -479,6 +483,22 @@ int cmCTestTestHandler::ProcessHandler()
return 0;
}
/* Given a multi-option value `parts`, compile those parts into
* regular expressions in `expressions`. Skip empty values.
* Returns true if there were any expressions.
*/
static bool BuildLabelRE(const std::vector<std::string>& parts,
std::vector<cmsys::RegularExpression>& expressions)
{
expressions.clear();
for (const auto& p : parts) {
if (!p.empty()) {
expressions.emplace_back(p);
}
}
return !expressions.empty();
}
bool cmCTestTestHandler::ProcessOptions()
{
// Update internal data structure from generic one
@@ -519,18 +539,11 @@ bool cmCTestTestHandler::ProcessOptions()
this->CTest->SetStopOnFailure(true);
}
const char* val;
val = this->GetOption("LabelRegularExpression");
if (val) {
this->UseIncludeLabelRegExpFlag = true;
this->IncludeLabelRegExp = val;
}
val = this->GetOption("ExcludeLabelRegularExpression");
if (val) {
this->UseExcludeLabelRegExpFlag = true;
this->ExcludeLabelRegExp = val;
}
val = this->GetOption("IncludeRegularExpression");
BuildLabelRE(this->GetMultiOption("LabelRegularExpression"),
this->IncludeLabelRegularExpressions);
BuildLabelRE(this->GetMultiOption("ExcludeLabelRegularExpression"),
this->ExcludeLabelRegularExpressions);
const char* val = this->GetOption("IncludeRegularExpression");
if (val) {
this->UseIncludeRegExp();
this->SetIncludeRegExp(val);
@@ -763,10 +776,40 @@ void cmCTestTestHandler::PrintLabelOrSubprojectSummary(bool doSubProject)
cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "\n", this->Quiet);
}
/**
* Check if the labels (from a test) match all the expressions.
*
* Each of the RE's must match at least one label
* (e.g. all of the REs must match **some** label,
* in order for the filter to apply to the test).
*/
static bool MatchLabelsAgainstFilterRE(
const std::vector<std::string>& labels,
const std::vector<cmsys::RegularExpression>& expressions)
{
for (const auto& re : expressions) {
// check to see if the label regular expression matches
bool found = false; // assume it does not match
cmsys::RegularExpressionMatch match;
// loop over all labels and look for match
for (std::string const& l : labels) {
if (re.find(l.c_str(), match)) {
found = true;
break;
}
}
// if no match was found, exclude the test
if (!found) {
return false;
}
}
return true;
}
void cmCTestTestHandler::CheckLabelFilterInclude(cmCTestTestProperties& it)
{
// if not using Labels to filter then return
if (!this->UseIncludeLabelRegExpFlag) {
if (this->IncludeLabelRegularExpressions.empty()) {
return;
}
// if there are no labels and we are filtering by labels
@@ -775,16 +818,9 @@ void cmCTestTestHandler::CheckLabelFilterInclude(cmCTestTestProperties& it)
it.IsInBasedOnREOptions = false;
return;
}
// check to see if the label regular expression matches
bool found = false; // assume it does not match
// loop over all labels and look for match
for (std::string const& l : it.Labels) {
if (this->IncludeLabelRegularExpression.find(l)) {
found = true;
}
}
// if no match was found, exclude the test
if (!found) {
if (!MatchLabelsAgainstFilterRE(it.Labels,
this->IncludeLabelRegularExpressions)) {
it.IsInBasedOnREOptions = false;
}
}
@@ -792,7 +828,7 @@ void cmCTestTestHandler::CheckLabelFilterInclude(cmCTestTestProperties& it)
void cmCTestTestHandler::CheckLabelFilterExclude(cmCTestTestProperties& it)
{
// if not using Labels to filter then return
if (!this->UseExcludeLabelRegExpFlag) {
if (this->ExcludeLabelRegularExpressions.empty()) {
return;
}
// if there are no labels and we are excluding by labels
@@ -800,16 +836,9 @@ void cmCTestTestHandler::CheckLabelFilterExclude(cmCTestTestProperties& it)
if (it.Labels.empty()) {
return;
}
// check to see if the label regular expression matches
bool found = false; // assume it does not match
// loop over all labels and look for match
for (std::string const& l : it.Labels) {
if (this->ExcludeLabelRegularExpression.find(l)) {
found = true;
}
}
// if match was found, exclude the test
if (found) {
if (MatchLabelsAgainstFilterRE(it.Labels,
this->ExcludeLabelRegularExpressions)) {
it.IsInBasedOnREOptions = false;
}
}
@@ -1704,19 +1733,11 @@ bool cmCTestTestHandler::ParseResourceGroupsProperty(
bool cmCTestTestHandler::GetListOfTests()
{
if (!this->IncludeLabelRegExp.empty()) {
this->IncludeLabelRegularExpression.compile(
this->IncludeLabelRegExp.c_str());
}
if (!this->ExcludeLabelRegExp.empty()) {
this->ExcludeLabelRegularExpression.compile(
this->ExcludeLabelRegExp.c_str());
}
if (!this->IncludeRegExp.empty()) {
this->IncludeTestsRegularExpression.compile(this->IncludeRegExp.c_str());
this->IncludeTestsRegularExpression.compile(this->IncludeRegExp);
}
if (!this->ExcludeRegExp.empty()) {
this->ExcludeTestsRegularExpression.compile(this->ExcludeRegExp.c_str());
this->ExcludeTestsRegularExpression.compile(this->ExcludeRegExp);
}
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"Constructing a list of tests" << std::endl, this->Quiet);
@@ -1868,7 +1889,7 @@ void cmCTestTestHandler::ExpandTestsToRunInformationForRerunFailed()
std::string dirName = this->CTest->GetBinaryDir() + "/Testing/Temporary";
cmsys::Directory directory;
if (directory.Load(dirName) == 0) {
if (!directory.Load(dirName)) {
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Unable to read the contents of " << dirName << std::endl);
return;
@@ -2444,3 +2465,125 @@ bool cmCTestTestHandler::cmCTestTestResourceRequirement::operator!=(
{
return !(*this == other);
}
void cmCTestTestHandler::SetJUnitXMLFileName(const std::string& filename)
{
this->JUnitXMLFileName = filename;
}
bool cmCTestTestHandler::WriteJUnitXML()
{
if (this->JUnitXMLFileName.empty()) {
return true;
}
// Open new XML file for writing.
cmGeneratedFileStream xmlfile;
xmlfile.SetTempExt("tmp");
xmlfile.Open(this->JUnitXMLFileName);
if (!xmlfile) {
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Problem opening file: " << this->JUnitXMLFileName
<< std::endl);
return false;
}
cmXMLWriter xml(xmlfile);
// Iterate over the test results to get the number of tests that
// passed, failed, etc.
auto num_tests = 0;
auto num_passed = 0;
auto num_failed = 0;
auto num_notrun = 0;
auto num_disabled = 0;
SetOfTests resultsSet(this->TestResults.begin(), this->TestResults.end());
for (cmCTestTestResult const& result : resultsSet) {
num_tests++;
if (result.Status == cmCTestTestHandler::COMPLETED) {
num_passed++;
} else if (result.Status == cmCTestTestHandler::NOT_RUN) {
if (result.CompletionStatus == "Disabled") {
num_disabled++;
} else {
num_notrun++;
}
} else {
num_failed++;
}
}
// Write <testsuite> element.
xml.StartDocument();
xml.StartElement("testsuite");
xml.Attribute("name",
cmCTest::SafeBuildIdField(
this->CTest->GetCTestConfiguration("BuildName")));
xml.BreakAttributes();
xml.Attribute("tests", num_tests);
xml.Attribute("failures", num_failed);
// CTest disabled => JUnit disabled
xml.Attribute("disabled", num_disabled);
// Otherwise, CTest notrun => JUnit skipped.
// The distinction between JUnit disabled vs. skipped is that
// skipped tests can have a message associated with them
// (why the test was skipped).
xml.Attribute("skipped", num_notrun);
xml.Attribute("hostname", this->CTest->GetCTestConfiguration("Site"));
xml.Attribute(
"time",
std::chrono::duration_cast<std::chrono::seconds>(this->ElapsedTestingTime)
.count());
const std::time_t start_test_time_t =
std::chrono::system_clock::to_time_t(this->StartTestTime);
cmTimestamp cmts;
xml.Attribute("timestamp",
cmts.CreateTimestampFromTimeT(start_test_time_t,
"%Y-%m-%dT%H:%M:%S", false));
// Write <testcase> elements.
for (cmCTestTestResult const& result : resultsSet) {
xml.StartElement("testcase");
xml.Attribute("name", result.Name);
xml.Attribute("classname", result.Name);
xml.Attribute("time", result.ExecutionTime.count());
std::string status;
if (result.Status == cmCTestTestHandler::COMPLETED) {
status = "run";
} else if (result.Status == cmCTestTestHandler::NOT_RUN) {
if (result.CompletionStatus == "Disabled") {
status = "disabled";
} else {
status = "notrun";
}
} else {
status = "fail";
}
xml.Attribute("status", status);
if (status == "notrun") {
xml.StartElement("skipped");
xml.Attribute("message", result.CompletionStatus);
xml.EndElement(); // </skipped>
} else if (status == "fail") {
xml.StartElement("failure");
xml.Attribute("message", result.Reason);
xml.EndElement(); // </failure>
}
// Note: compressed test output is unconditionally disabled when
// --output-junit is specified.
xml.Element("system-out", result.Output);
xml.EndElement(); // </testcase>
}
xml.EndElement(); // </testsuite>
xml.EndDocument();
return true;
}
+12 -6
View File
@@ -209,6 +209,9 @@ public:
using ListOfTests = std::vector<cmCTestTestProperties>;
// Support for writing test results in JUnit XML format.
void SetJUnitXMLFileName(const std::string& id);
protected:
using SetOfTests =
std::set<cmCTestTestHandler::cmCTestTestResult, cmCTestTestResultLess>;
@@ -274,6 +277,11 @@ private:
*/
virtual void GenerateDartOutput(cmXMLWriter& xml);
/**
* Write test results in JUnit XML format
*/
bool WriteJUnitXML();
void PrintLabelOrSubprojectSummary(bool isSubProject);
/**
@@ -320,20 +328,16 @@ private:
std::vector<int> TestsToRun;
bool UseIncludeLabelRegExpFlag;
bool UseExcludeLabelRegExpFlag;
bool UseIncludeRegExpFlag;
bool UseExcludeRegExpFlag;
bool UseExcludeRegExpFirst;
std::string IncludeLabelRegExp;
std::string ExcludeLabelRegExp;
std::string IncludeRegExp;
std::string ExcludeRegExp;
std::string ExcludeFixtureRegExp;
std::string ExcludeFixtureSetupRegExp;
std::string ExcludeFixtureCleanupRegExp;
cmsys::RegularExpression IncludeLabelRegularExpression;
cmsys::RegularExpression ExcludeLabelRegularExpression;
std::vector<cmsys::RegularExpression> IncludeLabelRegularExpressions;
std::vector<cmsys::RegularExpression> ExcludeLabelRegularExpressions;
cmsys::RegularExpression IncludeTestsRegularExpression;
cmsys::RegularExpression ExcludeTestsRegularExpression;
@@ -358,4 +362,6 @@ private:
cmCTest::Repeat RepeatMode = cmCTest::Repeat::Never;
int RepeatCount = 1;
bool RerunFailed;
std::string JUnitXMLFileName;
};
-1
View File
@@ -75,7 +75,6 @@ cmCTestGenericHandler* cmCTestUpdateCommand::InitializeHandler()
cmCTestUpdateHandler* handler = this->CTest->GetUpdateHandler();
handler->Initialize();
handler->SetCommand(this);
if (source_dir.empty()) {
this->SetError("source directory not specified. Please use SOURCE tag");
return nullptr;
+3 -1
View File
@@ -80,7 +80,9 @@ if(CMake_HAVE_CXX_MAKE_UNIQUE)
set(CMake_HAVE_CXX_UNIQUE_PTR 1)
endif()
cm_check_cxx_feature(unique_ptr)
if (NOT CMAKE_CXX_STANDARD LESS "17")
if (NOT CMAKE_CXX_STANDARD LESS "17"
AND NOT MSYS # FIXME: RunCMake.cmake_path cases crash with MSYS std::filesystem
)
if (NOT CMAKE_CROSSCOMPILING OR CMAKE_CROSSCOMPILING_EMULATOR)
cm_check_cxx_feature(filesystem TRY_RUN)
else()
+3 -2
View File
@@ -19,6 +19,7 @@
#include "cmCursesStandardIncludes.h"
#include "cmDocumentation.h"
#include "cmDocumentationEntry.h" // IWYU pragma: keep
#include "cmMessageMetadata.h"
#include "cmState.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -181,8 +182,8 @@ int main(int argc, char const* const* argv)
return msg;
};
cmSystemTools::SetMessageCallback(
[&](const std::string& message, const char* title) {
myform->AddError(cleanMessage(message), title);
[&](const std::string& message, const cmMessageMetadata& md) {
myform->AddError(cleanMessage(message), md.title);
});
cmSystemTools::SetStderrCallback([&](const std::string& message) {
myform->AddError(cleanMessage(message), "");
+1 -1
View File
@@ -5,7 +5,7 @@ project(CMAKE_FORM)
# Disable warnings to avoid changing 3rd party code.
if(CMAKE_C_COMPILER_ID MATCHES
"^(GNU|Clang|AppleClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM)$")
"^(GNU|Clang|AppleClang|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")
+49 -37
View File
@@ -1,8 +1,8 @@
/* A Bison parser, made by GNU Bison 3.7.4. */
/* A Bison parser, made by GNU Bison 3.7.5. */
/* Bison implementation for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation,
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
Inc.
This program is free software: you can redistribute it and/or modify
@@ -46,10 +46,10 @@
USER NAME SPACE" below. */
/* Identify Bison output, and Bison version. */
#define YYBISON 30704
#define YYBISON 30705
/* Bison version string. */
#define YYBISON_VERSION "3.7.4"
#define YYBISON_VERSION "3.7.5"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -228,6 +228,18 @@ typedef int_least16_t yytype_int16;
typedef short yytype_int16;
#endif
/* Work around bug in HP-UX 11.23, which defines these macros
incorrectly for preprocessor constants. This workaround can likely
be removed in 2023, as HPE has promised support for HP-UX 11.23
(aka HP-UX 11i v2) only through the end of 2022; see Table 2 of
<https://h20195.www2.hpe.com/V2/getpdf.aspx/4AA4-7673ENW.pdf>. */
#ifdef __hpux
# undef UINT_LEAST8_MAX
# undef UINT_LEAST16_MAX
# define UINT_LEAST8_MAX 255
# define UINT_LEAST16_MAX 65535
#endif
#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__
typedef __UINT_LEAST8_TYPE__ yytype_uint8;
#elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \
@@ -325,9 +337,9 @@ typedef int yy_state_fast_t;
/* Suppress unused-variable warnings by "using" E. */
#if ! defined lint || defined __GNUC__
# define YYUSE(E) ((void) (E))
# define YY_USE(E) ((void) (E))
#else
# define YYUSE(E) /* empty */
# define YY_USE(E) /* empty */
#endif
#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
@@ -635,7 +647,7 @@ static const yytype_int8 yypgoto[] =
/* YYDEFGOTO[NTERM-NUM]. */
static const yytype_int8 yydefgoto[] =
{
-1, 11, 12, 13, 14, 15, 19, 20, 21, 22
0, 11, 12, 13, 14, 15, 19, 20, 21, 22
};
/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
@@ -761,8 +773,8 @@ yy_symbol_value_print (FILE *yyo,
yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep, yyscan_t yyscanner)
{
FILE *yyoutput = yyo;
YYUSE (yyoutput);
YYUSE (yyscanner);
YY_USE (yyoutput);
YY_USE (yyscanner);
if (!yyvaluep)
return;
# ifdef YYPRINT
@@ -770,7 +782,7 @@ yy_symbol_value_print (FILE *yyo,
YYPRINT (yyo, yytoknum[yykind], *yyvaluep);
# endif
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
YYUSE (yykind);
YY_USE (yykind);
YY_IGNORE_MAYBE_UNINITIALIZED_END
}
@@ -1151,14 +1163,14 @@ static void
yydestruct (const char *yymsg,
yysymbol_kind_t yykind, YYSTYPE *yyvaluep, yyscan_t yyscanner)
{
YYUSE (yyvaluep);
YYUSE (yyscanner);
YY_USE (yyvaluep);
YY_USE (yyscanner);
if (!yymsg)
yymsg = "Deleting";
YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp);
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
YYUSE (yykind);
YY_USE (yykind);
YY_IGNORE_MAYBE_UNINITIALIZED_END
}
@@ -1433,7 +1445,7 @@ yyreduce:
(yyval.str) = 0;
yyGetParser->SetResult((yyvsp[0].str));
}
#line 1437 "cmCommandArgumentParser.cxx"
#line 1449 "cmCommandArgumentParser.cxx"
break;
case 3: /* GoalWithOptionalBackSlash: Goal */
@@ -1441,7 +1453,7 @@ yyreduce:
{
(yyval.str) = (yyvsp[0].str);
}
#line 1445 "cmCommandArgumentParser.cxx"
#line 1457 "cmCommandArgumentParser.cxx"
break;
case 4: /* GoalWithOptionalBackSlash: Goal "\\" */
@@ -1449,7 +1461,7 @@ yyreduce:
{
(yyval.str) = yyGetParser->CombineUnions((yyvsp[-1].str), (yyvsp[0].str));
}
#line 1453 "cmCommandArgumentParser.cxx"
#line 1465 "cmCommandArgumentParser.cxx"
break;
case 5: /* Goal: %empty */
@@ -1457,7 +1469,7 @@ yyreduce:
{
(yyval.str) = 0;
}
#line 1461 "cmCommandArgumentParser.cxx"
#line 1473 "cmCommandArgumentParser.cxx"
break;
case 6: /* Goal: String Goal */
@@ -1465,7 +1477,7 @@ yyreduce:
{
(yyval.str) = yyGetParser->CombineUnions((yyvsp[-1].str), (yyvsp[0].str));
}
#line 1469 "cmCommandArgumentParser.cxx"
#line 1481 "cmCommandArgumentParser.cxx"
break;
case 7: /* String: OuterText */
@@ -1473,7 +1485,7 @@ yyreduce:
{
(yyval.str) = (yyvsp[0].str);
}
#line 1477 "cmCommandArgumentParser.cxx"
#line 1489 "cmCommandArgumentParser.cxx"
break;
case 8: /* String: Variable */
@@ -1481,7 +1493,7 @@ yyreduce:
{
(yyval.str) = (yyvsp[0].str);
}
#line 1485 "cmCommandArgumentParser.cxx"
#line 1497 "cmCommandArgumentParser.cxx"
break;
case 9: /* OuterText: cal_NAME */
@@ -1489,7 +1501,7 @@ yyreduce:
{
(yyval.str) = (yyvsp[0].str);
}
#line 1493 "cmCommandArgumentParser.cxx"
#line 1505 "cmCommandArgumentParser.cxx"
break;
case 10: /* OuterText: "@" */
@@ -1497,7 +1509,7 @@ yyreduce:
{
(yyval.str) = (yyvsp[0].str);
}
#line 1501 "cmCommandArgumentParser.cxx"
#line 1513 "cmCommandArgumentParser.cxx"
break;
case 11: /* OuterText: "$" */
@@ -1505,7 +1517,7 @@ yyreduce:
{
(yyval.str) = (yyvsp[0].str);
}
#line 1509 "cmCommandArgumentParser.cxx"
#line 1521 "cmCommandArgumentParser.cxx"
break;
case 12: /* OuterText: "{" */
@@ -1513,7 +1525,7 @@ yyreduce:
{
(yyval.str) = (yyvsp[0].str);
}
#line 1517 "cmCommandArgumentParser.cxx"
#line 1529 "cmCommandArgumentParser.cxx"
break;
case 13: /* OuterText: "}" */
@@ -1521,7 +1533,7 @@ yyreduce:
{
(yyval.str) = (yyvsp[0].str);
}
#line 1525 "cmCommandArgumentParser.cxx"
#line 1537 "cmCommandArgumentParser.cxx"
break;
case 14: /* OuterText: cal_SYMBOL */
@@ -1529,7 +1541,7 @@ yyreduce:
{
(yyval.str) = (yyvsp[0].str);
}
#line 1533 "cmCommandArgumentParser.cxx"
#line 1545 "cmCommandArgumentParser.cxx"
break;
case 15: /* Variable: cal_ENVCURLY EnvVarName "}" */
@@ -1537,7 +1549,7 @@ yyreduce:
{
(yyval.str) = yyGetParser->ExpandSpecialVariable((yyvsp[-2].str), (yyvsp[-1].str));
}
#line 1541 "cmCommandArgumentParser.cxx"
#line 1553 "cmCommandArgumentParser.cxx"
break;
case 16: /* Variable: cal_NCURLY MultipleIds "}" */
@@ -1545,7 +1557,7 @@ yyreduce:
{
(yyval.str) = yyGetParser->ExpandSpecialVariable((yyvsp[-2].str), (yyvsp[-1].str));
}
#line 1549 "cmCommandArgumentParser.cxx"
#line 1561 "cmCommandArgumentParser.cxx"
break;
case 17: /* Variable: cal_DCURLY MultipleIds "}" */
@@ -1553,7 +1565,7 @@ yyreduce:
{
(yyval.str) = yyGetParser->ExpandVariable((yyvsp[-1].str));
}
#line 1557 "cmCommandArgumentParser.cxx"
#line 1569 "cmCommandArgumentParser.cxx"
break;
case 18: /* Variable: cal_ATNAME */
@@ -1561,7 +1573,7 @@ yyreduce:
{
(yyval.str) = yyGetParser->ExpandVariableForAt((yyvsp[0].str));
}
#line 1565 "cmCommandArgumentParser.cxx"
#line 1577 "cmCommandArgumentParser.cxx"
break;
case 19: /* EnvVarName: MultipleIds */
@@ -1569,7 +1581,7 @@ yyreduce:
{
(yyval.str) = (yyvsp[0].str);
}
#line 1573 "cmCommandArgumentParser.cxx"
#line 1585 "cmCommandArgumentParser.cxx"
break;
case 20: /* EnvVarName: cal_SYMBOL EnvVarName */
@@ -1577,7 +1589,7 @@ yyreduce:
{
(yyval.str) = (yyvsp[-1].str);
}
#line 1581 "cmCommandArgumentParser.cxx"
#line 1593 "cmCommandArgumentParser.cxx"
break;
case 21: /* MultipleIds: %empty */
@@ -1585,7 +1597,7 @@ yyreduce:
{
(yyval.str) = 0;
}
#line 1589 "cmCommandArgumentParser.cxx"
#line 1601 "cmCommandArgumentParser.cxx"
break;
case 22: /* MultipleIds: ID MultipleIds */
@@ -1593,7 +1605,7 @@ yyreduce:
{
(yyval.str) = yyGetParser->CombineUnions((yyvsp[-1].str), (yyvsp[0].str));
}
#line 1597 "cmCommandArgumentParser.cxx"
#line 1609 "cmCommandArgumentParser.cxx"
break;
case 23: /* ID: cal_NAME */
@@ -1601,7 +1613,7 @@ yyreduce:
{
(yyval.str) = (yyvsp[0].str);
}
#line 1605 "cmCommandArgumentParser.cxx"
#line 1617 "cmCommandArgumentParser.cxx"
break;
case 24: /* ID: Variable */
@@ -1609,11 +1621,11 @@ yyreduce:
{
(yyval.str) = (yyvsp[0].str);
}
#line 1613 "cmCommandArgumentParser.cxx"
#line 1625 "cmCommandArgumentParser.cxx"
break;
#line 1617 "cmCommandArgumentParser.cxx"
#line 1629 "cmCommandArgumentParser.cxx"
default: break;
}
@@ -1,8 +1,8 @@
/* A Bison parser, made by GNU Bison 3.7.4. */
/* A Bison parser, made by GNU Bison 3.7.5. */
/* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation,
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
Inc.
This program is free software: you can redistribute it and/or modify
File diff suppressed because it is too large Load Diff
@@ -1,8 +1,8 @@
/* A Bison parser, made by GNU Bison 3.7.4. */
/* A Bison parser, made by GNU Bison 3.7.5. */
/* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation,
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
Inc.
This program is free software: you can redistribute it and/or modify
+132 -116
View File
@@ -1,8 +1,8 @@
/* A Bison parser, made by GNU Bison 3.7.4. */
/* A Bison parser, made by GNU Bison 3.7.5. */
/* Bison implementation for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation,
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
Inc.
This program is free software: you can redistribute it and/or modify
@@ -46,10 +46,10 @@
USER NAME SPACE" below. */
/* Identify Bison output, and Bison version. */
#define YYBISON 30704
#define YYBISON 30705
/* Bison version string. */
#define YYBISON_VERSION "3.7.4"
#define YYBISON_VERSION "3.7.5"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -120,7 +120,11 @@ static void cmExpr_yyerror(yyscan_t yyscanner, const char* message);
# endif
#endif
#line 124 "cmExprParser.cxx"
#if defined(__NVCOMPILER)
# pragma diag_suppress 550 /* variable set but never used */
#endif
#line 128 "cmExprParser.cxx"
# ifndef YY_CAST
# ifdef __cplusplus
@@ -218,6 +222,18 @@ typedef int_least16_t yytype_int16;
typedef short yytype_int16;
#endif
/* Work around bug in HP-UX 11.23, which defines these macros
incorrectly for preprocessor constants. This workaround can likely
be removed in 2023, as HPE has promised support for HP-UX 11.23
(aka HP-UX 11i v2) only through the end of 2022; see Table 2 of
<https://h20195.www2.hpe.com/V2/getpdf.aspx/4AA4-7673ENW.pdf>. */
#ifdef __hpux
# undef UINT_LEAST8_MAX
# undef UINT_LEAST16_MAX
# define UINT_LEAST8_MAX 255
# define UINT_LEAST16_MAX 65535
#endif
#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__
typedef __UINT_LEAST8_TYPE__ yytype_uint8;
#elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \
@@ -315,9 +331,9 @@ typedef int yy_state_fast_t;
/* Suppress unused-variable warnings by "using" E. */
#if ! defined lint || defined __GNUC__
# define YYUSE(E) ((void) (E))
# define YY_USE(E) ((void) (E))
#else
# define YYUSE(E) /* empty */
# define YY_USE(E) /* empty */
#endif
#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
@@ -544,9 +560,9 @@ static const yytype_int8 yytranslate[] =
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
static const yytype_uint8 yyrline[] =
{
0, 81, 81, 86, 89, 94, 97, 102, 105, 110,
113, 116, 121, 124, 127, 132, 135, 138, 144, 149,
152, 155, 158, 163, 166
0, 85, 85, 90, 93, 98, 101, 106, 109, 114,
117, 120, 125, 128, 131, 136, 139, 142, 148, 153,
156, 159, 162, 167, 170
};
#endif
@@ -629,7 +645,7 @@ static const yytype_int8 yypgoto[] =
/* YYDEFGOTO[NTERM-NUM]. */
static const yytype_int8 yydefgoto[] =
{
-1, 6, 7, 8, 9, 10, 11, 12, 13, 14
0, 6, 7, 8, 9, 10, 11, 12, 13, 14
};
/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
@@ -754,8 +770,8 @@ yy_symbol_value_print (FILE *yyo,
yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep, yyscan_t yyscanner)
{
FILE *yyoutput = yyo;
YYUSE (yyoutput);
YYUSE (yyscanner);
YY_USE (yyoutput);
YY_USE (yyscanner);
if (!yyvaluep)
return;
# ifdef YYPRINT
@@ -763,7 +779,7 @@ yy_symbol_value_print (FILE *yyo,
YYPRINT (yyo, yytoknum[yykind], *yyvaluep);
# endif
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
YYUSE (yykind);
YY_USE (yykind);
YY_IGNORE_MAYBE_UNINITIALIZED_END
}
@@ -1144,14 +1160,14 @@ static void
yydestruct (const char *yymsg,
yysymbol_kind_t yykind, YYSTYPE *yyvaluep, yyscan_t yyscanner)
{
YYUSE (yyvaluep);
YYUSE (yyscanner);
YY_USE (yyvaluep);
YY_USE (yyscanner);
if (!yymsg)
yymsg = "Deleting";
YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp);
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
YYUSE (yykind);
YY_USE (yykind);
YY_IGNORE_MAYBE_UNINITIALIZED_END
}
@@ -1421,194 +1437,194 @@ yyreduce:
switch (yyn)
{
case 2: /* start: exp */
#line 81 "cmExprParser.y"
#line 85 "cmExprParser.y"
{
cmExpr_yyget_extra(yyscanner)->SetResult((yyvsp[0].Number));
}
#line 1429 "cmExprParser.cxx"
break;
case 3: /* exp: bitwiseor */
#line 86 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
}
#line 1437 "cmExprParser.cxx"
break;
case 4: /* exp: exp exp_OR bitwiseor */
#line 89 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) | (yyvsp[0].Number);
}
#line 1445 "cmExprParser.cxx"
break;
case 5: /* bitwiseor: bitwisexor */
#line 94 "cmExprParser.y"
{
case 3: /* exp: bitwiseor */
#line 90 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
}
#line 1453 "cmExprParser.cxx"
break;
case 6: /* bitwiseor: bitwiseor exp_XOR bitwisexor */
#line 97 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) ^ (yyvsp[0].Number);
case 4: /* exp: exp exp_OR bitwiseor */
#line 93 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) | (yyvsp[0].Number);
}
#line 1461 "cmExprParser.cxx"
break;
case 7: /* bitwisexor: bitwiseand */
#line 102 "cmExprParser.y"
case 5: /* bitwiseor: bitwisexor */
#line 98 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
}
#line 1469 "cmExprParser.cxx"
break;
case 8: /* bitwisexor: bitwisexor exp_AND bitwiseand */
#line 105 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) & (yyvsp[0].Number);
case 6: /* bitwiseor: bitwiseor exp_XOR bitwisexor */
#line 101 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) ^ (yyvsp[0].Number);
}
#line 1477 "cmExprParser.cxx"
break;
case 9: /* bitwiseand: shift */
#line 110 "cmExprParser.y"
{
case 7: /* bitwisexor: bitwiseand */
#line 106 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
}
#line 1485 "cmExprParser.cxx"
break;
case 10: /* bitwiseand: bitwiseand exp_SHIFTLEFT shift */
#line 113 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) << (yyvsp[0].Number);
case 8: /* bitwisexor: bitwisexor exp_AND bitwiseand */
#line 109 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) & (yyvsp[0].Number);
}
#line 1493 "cmExprParser.cxx"
break;
case 11: /* bitwiseand: bitwiseand exp_SHIFTRIGHT shift */
#line 116 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) >> (yyvsp[0].Number);
case 9: /* bitwiseand: shift */
#line 114 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
}
#line 1501 "cmExprParser.cxx"
break;
case 12: /* shift: term */
#line 121 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
case 10: /* bitwiseand: bitwiseand exp_SHIFTLEFT shift */
#line 117 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) << (yyvsp[0].Number);
}
#line 1509 "cmExprParser.cxx"
break;
case 13: /* shift: shift exp_PLUS term */
#line 124 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) + (yyvsp[0].Number);
case 11: /* bitwiseand: bitwiseand exp_SHIFTRIGHT shift */
#line 120 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) >> (yyvsp[0].Number);
}
#line 1517 "cmExprParser.cxx"
break;
case 14: /* shift: shift exp_MINUS term */
#line 127 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) - (yyvsp[0].Number);
case 12: /* shift: term */
#line 125 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
}
#line 1525 "cmExprParser.cxx"
break;
case 15: /* term: unary */
#line 132 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
case 13: /* shift: shift exp_PLUS term */
#line 128 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) + (yyvsp[0].Number);
}
#line 1533 "cmExprParser.cxx"
break;
case 16: /* term: term exp_TIMES unary */
#line 135 "cmExprParser.y"
case 14: /* shift: shift exp_MINUS term */
#line 131 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) * (yyvsp[0].Number);
(yyval.Number) = (yyvsp[-2].Number) - (yyvsp[0].Number);
}
#line 1541 "cmExprParser.cxx"
break;
case 15: /* term: unary */
#line 136 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
}
#line 1549 "cmExprParser.cxx"
break;
case 16: /* term: term exp_TIMES unary */
#line 139 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) * (yyvsp[0].Number);
}
#line 1557 "cmExprParser.cxx"
break;
case 17: /* term: term exp_DIVIDE unary */
#line 138 "cmExprParser.y"
#line 142 "cmExprParser.y"
{
if (yyvsp[0].Number == 0) {
throw std::overflow_error("divide by zero");
}
(yyval.Number) = (yyvsp[-2].Number) / (yyvsp[0].Number);
}
#line 1552 "cmExprParser.cxx"
break;
case 18: /* term: term exp_MOD unary */
#line 144 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) % (yyvsp[0].Number);
}
#line 1560 "cmExprParser.cxx"
break;
case 19: /* unary: factor */
#line 149 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
}
#line 1568 "cmExprParser.cxx"
break;
case 20: /* unary: exp_PLUS unary */
#line 152 "cmExprParser.y"
{
(yyval.Number) = + (yyvsp[0].Number);
case 18: /* term: term exp_MOD unary */
#line 148 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) % (yyvsp[0].Number);
}
#line 1576 "cmExprParser.cxx"
break;
case 21: /* unary: exp_MINUS unary */
#line 155 "cmExprParser.y"
{
(yyval.Number) = - (yyvsp[0].Number);
case 19: /* unary: factor */
#line 153 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
}
#line 1584 "cmExprParser.cxx"
break;
case 22: /* unary: exp_NOT unary */
#line 158 "cmExprParser.y"
{
(yyval.Number) = ~ (yyvsp[0].Number);
case 20: /* unary: exp_PLUS unary */
#line 156 "cmExprParser.y"
{
(yyval.Number) = + (yyvsp[0].Number);
}
#line 1592 "cmExprParser.cxx"
break;
case 23: /* factor: exp_NUMBER */
#line 163 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
case 21: /* unary: exp_MINUS unary */
#line 159 "cmExprParser.y"
{
(yyval.Number) = - (yyvsp[0].Number);
}
#line 1600 "cmExprParser.cxx"
break;
case 24: /* factor: exp_OPENPARENT exp exp_CLOSEPARENT */
#line 166 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-1].Number);
case 22: /* unary: exp_NOT unary */
#line 162 "cmExprParser.y"
{
(yyval.Number) = ~ (yyvsp[0].Number);
}
#line 1608 "cmExprParser.cxx"
break;
case 23: /* factor: exp_NUMBER */
#line 167 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
}
#line 1616 "cmExprParser.cxx"
break;
#line 1612 "cmExprParser.cxx"
case 24: /* factor: exp_OPENPARENT exp exp_CLOSEPARENT */
#line 170 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-1].Number);
}
#line 1624 "cmExprParser.cxx"
break;
#line 1628 "cmExprParser.cxx"
default: break;
}
@@ -1833,7 +1849,7 @@ yyreturn:
return yyresult;
}
#line 171 "cmExprParser.y"
#line 175 "cmExprParser.y"
/* End of grammar */
+4
View File
@@ -44,6 +44,10 @@ static void cmExpr_yyerror(yyscan_t yyscanner, const char* message);
# pragma clang diagnostic ignored "-Wused-but-marked-unused"
# endif
#endif
#if defined(__NVCOMPILER)
# pragma diag_suppress 550 /* variable set but never used */
#endif
%}
/* Generate a reentrant parser object. */
+2 -2
View File
@@ -1,8 +1,8 @@
/* A Bison parser, made by GNU Bison 3.7.4. */
/* A Bison parser, made by GNU Bison 3.7.5. */
/* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation,
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
Inc.
This program is free software: you can redistribute it and/or modify
+49 -37
View File
@@ -1,8 +1,8 @@
/* A Bison parser, made by GNU Bison 3.7.4. */
/* A Bison parser, made by GNU Bison 3.7.5. */
/* Bison implementation for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation,
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
Inc.
This program is free software: you can redistribute it and/or modify
@@ -46,10 +46,10 @@
USER NAME SPACE" below. */
/* Identify Bison output, and Bison version. */
#define YYBISON 30704
#define YYBISON 30705
/* Bison version string. */
#define YYBISON_VERSION "3.7.4"
#define YYBISON_VERSION "3.7.5"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -259,6 +259,18 @@ typedef int_least16_t yytype_int16;
typedef short yytype_int16;
#endif
/* Work around bug in HP-UX 11.23, which defines these macros
incorrectly for preprocessor constants. This workaround can likely
be removed in 2023, as HPE has promised support for HP-UX 11.23
(aka HP-UX 11i v2) only through the end of 2022; see Table 2 of
<https://h20195.www2.hpe.com/V2/getpdf.aspx/4AA4-7673ENW.pdf>. */
#ifdef __hpux
# undef UINT_LEAST8_MAX
# undef UINT_LEAST16_MAX
# define UINT_LEAST8_MAX 255
# define UINT_LEAST16_MAX 65535
#endif
#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__
typedef __UINT_LEAST8_TYPE__ yytype_uint8;
#elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \
@@ -356,9 +368,9 @@ typedef int yy_state_fast_t;
/* Suppress unused-variable warnings by "using" E. */
#if ! defined lint || defined __GNUC__
# define YYUSE(E) ((void) (E))
# define YY_USE(E) ((void) (E))
#else
# define YYUSE(E) /* empty */
# define YY_USE(E) /* empty */
#endif
#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
@@ -701,7 +713,7 @@ static const yytype_int8 yypgoto[] =
/* YYDEFGOTO[NTERM-NUM]. */
static const yytype_int8 yydefgoto[] =
{
-1, 1, 32, 33, 34, 35, 36, 37, 38, 39,
0, 1, 32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 44, 82
};
@@ -955,8 +967,8 @@ yy_symbol_value_print (FILE *yyo,
yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep, yyscan_t yyscanner)
{
FILE *yyoutput = yyo;
YYUSE (yyoutput);
YYUSE (yyscanner);
YY_USE (yyoutput);
YY_USE (yyscanner);
if (!yyvaluep)
return;
# ifdef YYPRINT
@@ -964,7 +976,7 @@ yy_symbol_value_print (FILE *yyo,
YYPRINT (yyo, yytoknum[yykind], *yyvaluep);
# endif
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
YYUSE (yykind);
YY_USE (yykind);
YY_IGNORE_MAYBE_UNINITIALIZED_END
}
@@ -1345,14 +1357,14 @@ static void
yydestruct (const char *yymsg,
yysymbol_kind_t yykind, YYSTYPE *yyvaluep, yyscan_t yyscanner)
{
YYUSE (yyvaluep);
YYUSE (yyscanner);
YY_USE (yyvaluep);
YY_USE (yyscanner);
if (!yymsg)
yymsg = "Deleting";
YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp);
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
YYUSE (yykind);
YY_USE (yykind);
YY_IGNORE_MAYBE_UNINITIALIZED_END
}
@@ -1627,7 +1639,7 @@ yyreduce:
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_SetInInterface(parser, true);
}
#line 1631 "cmFortranParser.cxx"
#line 1643 "cmFortranParser.cxx"
break;
case 5: /* stmt: USE WORD other EOSTMT */
@@ -1637,7 +1649,7 @@ yyreduce:
cmFortranParser_RuleUse(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
#line 1641 "cmFortranParser.cxx"
#line 1653 "cmFortranParser.cxx"
break;
case 6: /* stmt: MODULE WORD other EOSTMT */
@@ -1651,7 +1663,7 @@ yyreduce:
}
free((yyvsp[-2].string));
}
#line 1655 "cmFortranParser.cxx"
#line 1667 "cmFortranParser.cxx"
break;
case 7: /* stmt: SUBMODULE LPAREN WORD RPAREN WORD other EOSTMT */
@@ -1662,7 +1674,7 @@ yyreduce:
free((yyvsp[-4].string));
free((yyvsp[-2].string));
}
#line 1666 "cmFortranParser.cxx"
#line 1678 "cmFortranParser.cxx"
break;
case 8: /* stmt: SUBMODULE LPAREN WORD COLON WORD RPAREN WORD other EOSTMT */
@@ -1674,7 +1686,7 @@ yyreduce:
free((yyvsp[-4].string));
free((yyvsp[-2].string));
}
#line 1678 "cmFortranParser.cxx"
#line 1690 "cmFortranParser.cxx"
break;
case 9: /* stmt: INTERFACE WORD other EOSTMT */
@@ -1684,7 +1696,7 @@ yyreduce:
cmFortranParser_SetInInterface(parser, true);
free((yyvsp[-2].string));
}
#line 1688 "cmFortranParser.cxx"
#line 1700 "cmFortranParser.cxx"
break;
case 10: /* stmt: END INTERFACE other EOSTMT */
@@ -1693,7 +1705,7 @@ yyreduce:
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_SetInInterface(parser, false);
}
#line 1697 "cmFortranParser.cxx"
#line 1709 "cmFortranParser.cxx"
break;
case 11: /* stmt: USE DCOLON WORD other EOSTMT */
@@ -1703,7 +1715,7 @@ yyreduce:
cmFortranParser_RuleUse(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
#line 1707 "cmFortranParser.cxx"
#line 1719 "cmFortranParser.cxx"
break;
case 12: /* stmt: USE COMMA WORD DCOLON WORD other EOSTMT */
@@ -1716,7 +1728,7 @@ yyreduce:
free((yyvsp[-4].string));
free((yyvsp[-2].string));
}
#line 1720 "cmFortranParser.cxx"
#line 1732 "cmFortranParser.cxx"
break;
case 13: /* stmt: INCLUDE STRING other EOSTMT */
@@ -1726,7 +1738,7 @@ yyreduce:
cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
#line 1730 "cmFortranParser.cxx"
#line 1742 "cmFortranParser.cxx"
break;
case 14: /* stmt: CPP_LINE_DIRECTIVE STRING other EOSTMT */
@@ -1736,7 +1748,7 @@ yyreduce:
cmFortranParser_RuleLineDirective(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
#line 1740 "cmFortranParser.cxx"
#line 1752 "cmFortranParser.cxx"
break;
case 15: /* stmt: CPP_INCLUDE_ANGLE other EOSTMT */
@@ -1746,7 +1758,7 @@ yyreduce:
cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
#line 1750 "cmFortranParser.cxx"
#line 1762 "cmFortranParser.cxx"
break;
case 16: /* stmt: include STRING other EOSTMT */
@@ -1756,7 +1768,7 @@ yyreduce:
cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
#line 1760 "cmFortranParser.cxx"
#line 1772 "cmFortranParser.cxx"
break;
case 17: /* stmt: define WORD other EOSTMT */
@@ -1766,7 +1778,7 @@ yyreduce:
cmFortranParser_RuleDefine(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
#line 1770 "cmFortranParser.cxx"
#line 1782 "cmFortranParser.cxx"
break;
case 18: /* stmt: undef WORD other EOSTMT */
@@ -1776,7 +1788,7 @@ yyreduce:
cmFortranParser_RuleUndef(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
#line 1780 "cmFortranParser.cxx"
#line 1792 "cmFortranParser.cxx"
break;
case 19: /* stmt: ifdef WORD other EOSTMT */
@@ -1786,7 +1798,7 @@ yyreduce:
cmFortranParser_RuleIfdef(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
#line 1790 "cmFortranParser.cxx"
#line 1802 "cmFortranParser.cxx"
break;
case 20: /* stmt: ifndef WORD other EOSTMT */
@@ -1796,7 +1808,7 @@ yyreduce:
cmFortranParser_RuleIfndef(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
#line 1800 "cmFortranParser.cxx"
#line 1812 "cmFortranParser.cxx"
break;
case 21: /* stmt: if other EOSTMT */
@@ -1805,7 +1817,7 @@ yyreduce:
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleIf(parser);
}
#line 1809 "cmFortranParser.cxx"
#line 1821 "cmFortranParser.cxx"
break;
case 22: /* stmt: elif other EOSTMT */
@@ -1814,7 +1826,7 @@ yyreduce:
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleElif(parser);
}
#line 1818 "cmFortranParser.cxx"
#line 1830 "cmFortranParser.cxx"
break;
case 23: /* stmt: else other EOSTMT */
@@ -1823,7 +1835,7 @@ yyreduce:
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleElse(parser);
}
#line 1827 "cmFortranParser.cxx"
#line 1839 "cmFortranParser.cxx"
break;
case 24: /* stmt: endif other EOSTMT */
@@ -1832,23 +1844,23 @@ yyreduce:
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleEndif(parser);
}
#line 1836 "cmFortranParser.cxx"
#line 1848 "cmFortranParser.cxx"
break;
case 48: /* misc_code: WORD */
#line 229 "cmFortranParser.y"
{ free ((yyvsp[0].string)); }
#line 1842 "cmFortranParser.cxx"
#line 1854 "cmFortranParser.cxx"
break;
case 55: /* misc_code: STRING */
#line 236 "cmFortranParser.y"
{ free ((yyvsp[0].string)); }
#line 1848 "cmFortranParser.cxx"
#line 1860 "cmFortranParser.cxx"
break;
#line 1852 "cmFortranParser.cxx"
#line 1864 "cmFortranParser.cxx"
default: break;
}
+2 -2
View File
@@ -1,8 +1,8 @@
/* A Bison parser, made by GNU Bison 3.7.4. */
/* A Bison parser, made by GNU Bison 3.7.5. */
/* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation,
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
Inc.
This program is free software: you can redistribute it and/or modify
+8 -1
View File
@@ -40,7 +40,14 @@ They may be set by end users to point at LibUUID components.
#]=======================================================================]
#-----------------------------------------------------------------------------
if(CYGWIN)
if(MSYS)
# Note: on current version of MSYS2, linking to libuuid.dll.a doesn't
# import the right symbols sometimes. Fix this by linking directly
# to the DLL that provides the symbols, instead.
find_library(LibUUID_LIBRARY
NAMES msys-uuid-1.dll
)
elseif(CYGWIN)
# Note: on current version of Cygwin, linking to libuuid.dll.a doesn't
# import the right symbols sometimes. Fix this by linking directly
# to the DLL that provides the symbols, instead.
+7 -4
View File
@@ -112,7 +112,10 @@ int main(int argc, char** argv)
cmAddPluginPath();
#endif
#if QT_VERSION >= 0x050600
// HighDpiScaling is always enabled starting with Qt6, but will still issue a
// deprecation warning if you try to set the attribute for it
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) && \
QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
@@ -132,9 +135,9 @@ int main(int argc, char** argv)
translationsDir.cd(QString::fromLocal8Bit(".." CMAKE_DATA_DIR));
translationsDir.cd("i18n");
QTranslator translator;
QString transfile = QString("cmake_%1").arg(QLocale::system().name());
translator.load(transfile, translationsDir.path());
QApplication::installTranslator(&translator);
if (translator.load(QLocale(), "cmake", "_", translationsDir.path())) {
QApplication::installTranslator(&translator);
}
// app setup
QApplication::setApplicationName("CMakeSetup");
+4
View File
@@ -178,7 +178,11 @@ CMakeSetupDialog::CMakeSetupDialog()
&CMakeSetupDialog::doOutputErrorNext);
a->setShortcut(QKeySequence(Qt::Key_F8));
auto* s = new QShortcut(this);
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
s->setKey(QKeySequence(Qt::CTRL + Qt::Key_Period));
#else
s->setKey(QKeySequence(Qt::CTRL | Qt::Key_Period));
#endif
QObject::connect(s, &QShortcut::activated, this,
&CMakeSetupDialog::doOutputErrorNext); // in Eclipse
+11 -5
View File
@@ -13,6 +13,7 @@
#include "cmExternalMakefileProjectGenerator.h"
#include "cmGlobalGenerator.h"
#include "cmMessageMetadata.h"
#include "cmState.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -37,8 +38,8 @@ QCMake::QCMake(QObject* p)
cmSystemTools::SetRunCommandHideConsole(true);
cmSystemTools::SetMessageCallback(
[this](std::string const& msg, const char* title) {
this->messageCallback(msg, title);
[this](std::string const& msg, const cmMessageMetadata& md) {
this->messageCallback(msg, md.title);
});
cmSystemTools::SetStdoutCallback(
[this](std::string const& msg) { this->stdoutCallback(msg); });
@@ -160,7 +161,7 @@ void QCMake::setPreset(const QString& name, bool setBinary)
auto const& expandedPreset =
this->CMakePresetsFile.ConfigurePresets[presetName].Expanded;
if (expandedPreset) {
if (setBinary) {
if (setBinary && !expandedPreset->BinaryDir.empty()) {
QString binaryDir =
QString::fromLocal8Bit(expandedPreset->BinaryDir.data());
this->setBinaryDirectory(binaryDir);
@@ -334,7 +335,12 @@ void QCMake::setProperties(const QCMakePropertyList& newProps)
toremove.append(QString::fromLocal8Bit(key.c_str()));
} else {
prop = props[idx];
if (prop.Value.type() == QVariant::Bool) {
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
const bool isBool = prop.Value.type() == QVariant::Bool;
#else
const bool isBool = prop.Value.metaType() == QMetaType::fromType<bool>();
#endif
if (isBool) {
state->SetCacheEntryValue(key, prop.Value.toBool() ? "ON" : "OFF");
} else {
state->SetCacheEntryValue(key,
@@ -557,7 +563,7 @@ void QCMake::loadPresets()
preset.toolset = std::move(QString::fromLocal8Bit(p.Toolset.data()));
preset.setToolset = !p.ToolsetStrategy ||
p.ToolsetStrategy == cmCMakePresetsFile::ArchToolsetStrategy::Set;
preset.enabled = it.Expanded &&
preset.enabled = it.Expanded && it.Expanded->ConditionResult &&
std::find_if(this->AvailableGenerators.begin(),
this->AvailableGenerators.end(),
[&p](const cmake::GeneratorInfo& g) {
+30 -18
View File
@@ -2,11 +2,16 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmArchiveWrite.h"
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iostream>
#include <limits>
#include <sstream>
#include <string>
#include <thread>
#include <cm/algorithm>
#include <cm3p/archive.h>
#include <cm3p/archive_entry.h>
@@ -144,16 +149,36 @@ cmArchiveWrite::cmArchiveWrite(std::ostream& os, Compress c,
cm_archive_error_string(this->Archive));
return;
}
{
char sNumThreads[8];
snprintf(sNumThreads, sizeof(sNumThreads), "%d", numThreads);
sNumThreads[7] = '\0'; // for safety
#if ARCHIVE_VERSION_NUMBER >= 3004000
// Upstream fixed an issue with their integer parsing in 3.4.0
// which would cause spurious errors to be raised from `strtoull`.
if (numThreads < 1) {
int upperLimit = (numThreads == 0) ? std::numeric_limits<int>::max()
: std::abs(numThreads);
numThreads =
cm::clamp<int>(std::thread::hardware_concurrency(), 1, upperLimit);
}
# ifdef _AIX
// FIXME: Using more than 2 threads creates an empty archive.
// Enforce this limit pending further investigation.
numThreads = std::min(numThreads, 2);
# endif
std::string sNumThreads = std::to_string(numThreads);
if (archive_write_set_filter_option(this->Archive, "xz", "threads",
sNumThreads) != ARCHIVE_OK) {
sNumThreads.c_str()) !=
ARCHIVE_OK) {
this->Error = cmStrCat("archive_compressor_xz_options: ",
cm_archive_error_string(this->Archive));
return;
}
#endif
}
break;
@@ -425,16 +450,3 @@ bool cmArchiveWrite::AddData(const char* file, size_t size)
}
return true;
}
bool cmArchiveWrite::SetFilterOption(const char* module, const char* key,
const char* value)
{
if (archive_write_set_filter_option(this->Archive, module, key, value) !=
ARCHIVE_OK) {
this->Error = "archive_write_set_filter_option: ";
this->Error += cm_archive_error_string(this->Archive);
return false;
}
return true;
}
-3
View File
@@ -141,9 +141,6 @@ public:
this->Gname = "";
}
//! Set an option on a filter;
bool SetFilterOption(const char* module, const char* key, const char* value);
private:
bool Okay() const { return this->Error.empty(); }
bool AddPath(const char* path, size_t skip, const char* prefix,
+10 -3
View File
@@ -28,12 +28,14 @@ bool MainSignature(std::vector<std::string> const& args,
std::string configuration;
std::string project_name;
std::string target;
std::string parallel;
enum Doing
{
DoingNone,
DoingConfiguration,
DoingProjectName,
DoingTarget
DoingTarget,
DoingParallel
};
Doing doing = DoingNone;
for (unsigned int i = 1; i < args.size(); ++i) {
@@ -43,6 +45,8 @@ bool MainSignature(std::vector<std::string> const& args,
doing = DoingProjectName;
} else if (args[i] == "TARGET") {
doing = DoingTarget;
} else if (args[i] == "PARALLEL_LEVEL") {
doing = DoingParallel;
} else if (doing == DoingConfiguration) {
doing = DoingNone;
configuration = args[i];
@@ -52,6 +56,9 @@ bool MainSignature(std::vector<std::string> const& args,
} else if (doing == DoingTarget) {
doing = DoingNone;
target = args[i];
} else if (doing == DoingParallel) {
doing = DoingNone;
parallel = args[i];
} else {
status.SetError(cmStrCat("unknown argument \"", args[i], "\""));
return false;
@@ -77,7 +84,7 @@ bool MainSignature(std::vector<std::string> const& args,
}
std::string makecommand = mf.GetGlobalGenerator()->GenerateCMakeBuildCommand(
target, configuration, "", mf.IgnoreErrorsCMP0061());
target, configuration, parallel, "", mf.IgnoreErrorsCMP0061());
mf.AddDefinition(variable, makecommand);
@@ -104,7 +111,7 @@ bool TwoArgsSignature(std::vector<std::string> const& args,
}
std::string makecommand = mf.GetGlobalGenerator()->GenerateCMakeBuildCommand(
"", configType, "", mf.IgnoreErrorsCMP0061());
"", configType, "", "", mf.IgnoreErrorsCMP0061());
if (cacheValue) {
return true;
+3 -2
View File
@@ -18,6 +18,7 @@
#include "cmCMakePath.h"
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmProperty.h"
#include "cmRange.h"
#include "cmStringAlgorithms.h"
#include "cmSubcommandTable.h"
@@ -149,8 +150,8 @@ public:
bool getInputPath(const std::string& arg, cmExecutionStatus& status,
std::string& path)
{
const auto* def = status.GetMakefile().GetDefinition(arg);
if (def == nullptr) {
cmProp def = status.GetMakefile().GetDefinition(arg);
if (!def) {
status.SetError("undefined variable for input path.");
return false;
}
File diff suppressed because it is too large Load Diff
+25 -4
View File
@@ -2,8 +2,11 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#pragma once
#include "cmConfigure.h" // IWYU pragma: keep
#include <functional>
#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>
@@ -33,6 +36,10 @@ public:
INVALID_MACRO_EXPANSION,
BUILD_TEST_PRESETS_UNSUPPORTED,
INVALID_CONFIGURE_PRESET,
INSTALL_PREFIX_UNSUPPORTED,
INVALID_CONDITION,
CONDITION_UNSUPPORTED,
TOOLCHAIN_FILE_UNSUPPORTED,
};
enum class ArchToolsetStrategy
@@ -48,6 +55,8 @@ public:
std::string Value;
};
class Condition;
class Preset
{
public:
@@ -70,6 +79,9 @@ public:
std::string DisplayName;
std::string Description;
std::shared_ptr<Condition> ConditionEvaluator;
bool ConditionResult = true;
std::map<std::string, cm::optional<std::string>> Environment;
virtual ReadFileResult VisitPresetInherit(const Preset& parent) = 0;
@@ -78,7 +90,7 @@ public:
return ReadFileResult::READ_OK;
}
virtual ReadFileResult VisitPresetAfterInherit()
virtual ReadFileResult VisitPresetAfterInherit(int /* version */)
{
return ReadFileResult::READ_OK;
}
@@ -102,7 +114,9 @@ public:
cm::optional<ArchToolsetStrategy> ArchitectureStrategy;
std::string Toolset;
cm::optional<ArchToolsetStrategy> ToolsetStrategy;
std::string ToolchainFile;
std::string BinaryDir;
std::string InstallDir;
std::map<std::string, cm::optional<CacheVariable>> CacheVariables;
@@ -120,7 +134,7 @@ public:
ReadFileResult VisitPresetInherit(const Preset& parent) override;
ReadFileResult VisitPresetBeforeInherit() override;
ReadFileResult VisitPresetAfterInherit() override;
ReadFileResult VisitPresetAfterInherit(int version) override;
};
class BuildPreset : public Preset
@@ -146,7 +160,7 @@ public:
std::vector<std::string> NativeToolOptions;
ReadFileResult VisitPresetInherit(const Preset& parent) override;
ReadFileResult VisitPresetAfterInherit() override;
ReadFileResult VisitPresetAfterInherit(int /* version */) override;
};
class TestPreset : public Preset
@@ -273,7 +287,7 @@ public:
cm::optional<ExecutionOptions> Execution;
ReadFileResult VisitPresetInherit(const Preset& parent) override;
ReadFileResult VisitPresetAfterInherit() override;
ReadFileResult VisitPresetAfterInherit(int /* version */) override;
};
template <class T>
@@ -293,6 +307,13 @@ public:
std::vector<std::string> TestPresetOrder;
std::string SourceDir;
int Version;
int UserVersion;
int GetVersion(const Preset& preset) const
{
return preset.User ? this->UserVersion : this->Version;
}
static std::string GetFilename(const std::string& sourceDir);
static std::string GetUserFilename(const std::string& sourceDir);
+112
View File
@@ -0,0 +1,112 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#include <memory>
#include "cmCMakePresetsFile.h"
#define CHECK_OK(expr) \
{ \
auto _result = expr; \
if (_result != ReadFileResult::READ_OK) \
return _result; \
}
namespace cmCMakePresetsFileInternal {
enum class ExpandMacroResult
{
Ok,
Ignore,
Error,
};
using MacroExpander = std::function<ExpandMacroResult(
const std::string&, const std::string&, std::string&, int version)>;
}
class cmCMakePresetsFile::Condition
{
public:
virtual ~Condition() = default;
virtual bool Evaluate(
const std::vector<cmCMakePresetsFileInternal::MacroExpander>& expanders,
int version, cm::optional<bool>& out) const = 0;
virtual bool IsNull() const { return false; }
};
namespace cmCMakePresetsFileInternal {
class NullCondition : public cmCMakePresetsFile::Condition
{
bool Evaluate(const std::vector<MacroExpander>& /*expanders*/,
int /*version*/, cm::optional<bool>& out) const override
{
out = true;
return true;
}
bool IsNull() const override { return true; }
};
class ConstCondition : public cmCMakePresetsFile::Condition
{
public:
bool Evaluate(const std::vector<MacroExpander>& /*expanders*/,
int /*version*/, cm::optional<bool>& out) const override
{
out = this->Value;
return true;
}
bool Value;
};
class EqualsCondition : public cmCMakePresetsFile::Condition
{
public:
bool Evaluate(const std::vector<MacroExpander>& expanders, int version,
cm::optional<bool>& out) const override;
std::string Lhs;
std::string Rhs;
};
class InListCondition : public cmCMakePresetsFile::Condition
{
public:
bool Evaluate(const std::vector<MacroExpander>& expanders, int version,
cm::optional<bool>& out) const override;
std::string String;
std::vector<std::string> List;
};
class MatchesCondition : public cmCMakePresetsFile::Condition
{
public:
bool Evaluate(const std::vector<MacroExpander>& expanders, int version,
cm::optional<bool>& out) const override;
std::string String;
std::string Regex;
};
class AnyAllOfCondition : public cmCMakePresetsFile::Condition
{
public:
bool Evaluate(const std::vector<MacroExpander>& expanders, int version,
cm::optional<bool>& out) const override;
std::vector<std::unique_ptr<Condition>> Conditions;
bool StopValue;
};
class NotCondition : public cmCMakePresetsFile::Condition
{
public:
bool Evaluate(const std::vector<MacroExpander>& expanders, int version,
cm::optional<bool>& out) const override;
std::unique_ptr<Condition> SubCondition;
};
}
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -734,7 +734,7 @@ void CCONV cmSourceFileSetName2(void* arg, const char* name, const char* dir,
}
sf->SourceName = name;
std::string fname = sf->SourceName;
if (ext && strlen(ext)) {
if (cmNonempty(ext)) {
fname += ".";
fname += ext;
}
+47 -16
View File
@@ -4,7 +4,6 @@
#include <algorithm>
#include <cctype>
#include <cerrno>
#include <chrono>
#include <cstdio>
#include <cstdlib>
@@ -2070,6 +2069,17 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
}
i++;
this->Impl->TestDir = std::string(args[i]);
} else if (this->CheckArgument(arg, "--output-junit"_s)) {
if (i >= args.size() - 1) {
errormsg = "'--output-junit' requires an argument";
return false;
}
i++;
this->Impl->TestHandler.SetJUnitXMLFileName(std::string(args[i]));
// Turn test output compression off.
// This makes it easier to include test output in the resulting
// JUnit XML report.
this->Impl->CompressTestOutput = false;
}
cm::string_view noTestsPrefix = "--no-tests=";
@@ -2108,17 +2118,17 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
} else if (this->CheckArgument(arg, "-L"_s, "--label-regex") &&
i < args.size() - 1) {
i++;
this->GetTestHandler()->SetPersistentOption("LabelRegularExpression",
args[i].c_str());
this->GetMemCheckHandler()->SetPersistentOption("LabelRegularExpression",
args[i].c_str());
this->GetTestHandler()->AddPersistentMultiOption("LabelRegularExpression",
args[i]);
this->GetMemCheckHandler()->AddPersistentMultiOption(
"LabelRegularExpression", args[i]);
} else if (this->CheckArgument(arg, "-LE"_s, "--label-exclude") &&
i < args.size() - 1) {
i++;
this->GetTestHandler()->SetPersistentOption(
"ExcludeLabelRegularExpression", args[i].c_str());
this->GetMemCheckHandler()->SetPersistentOption(
"ExcludeLabelRegularExpression", args[i].c_str());
this->GetTestHandler()->AddPersistentMultiOption(
"ExcludeLabelRegularExpression", args[i]);
this->GetMemCheckHandler()->AddPersistentMultiOption(
"ExcludeLabelRegularExpression", args[i]);
}
else if (this->CheckArgument(arg, "-E"_s, "--exclude-regex") &&
@@ -2205,6 +2215,10 @@ bool cmCTest::ColoredOutputSupportedByConsole()
!clicolor_force.empty() && clicolor_force != "0") {
return true;
}
std::string clicolor;
if (cmSystemTools::GetEnv("CLICOLOR", clicolor) && clicolor == "0") {
return false;
}
return ConsoleIsNotDumb();
#endif
}
@@ -2221,7 +2235,7 @@ void cmCTest::HandleScriptArguments(size_t& i, std::vector<std::string>& args,
cmCTestScriptHandler* ch = this->GetScriptHandler();
// -SR is an internal argument, -SP should be ignored when it is passed
if (!SRArgumentSpecified) {
ch->AddConfigurationScript(args[i].c_str(), false);
ch->AddConfigurationScript(args[i], false);
}
}
@@ -2231,7 +2245,7 @@ void cmCTest::HandleScriptArguments(size_t& i, std::vector<std::string>& args,
this->Impl->RunConfigurationScript = true;
i++;
cmCTestScriptHandler* ch = this->GetScriptHandler();
ch->AddConfigurationScript(args[i].c_str(), true);
ch->AddConfigurationScript(args[i], true);
}
if (this->CheckArgument(arg, "-S"_s, "--script") && i < args.size() - 1) {
@@ -2240,7 +2254,7 @@ void cmCTest::HandleScriptArguments(size_t& i, std::vector<std::string>& args,
cmCTestScriptHandler* ch = this->GetScriptHandler();
// -SR is an internal argument, -S should be ignored when it is passed
if (!SRArgumentSpecified) {
ch->AddConfigurationScript(args[i].c_str(), true);
ch->AddConfigurationScript(args[i], true);
}
}
}
@@ -2268,6 +2282,15 @@ void cmCTest::SetPersistentOptionIfNotEmpty(const std::string& value,
}
}
void cmCTest::AddPersistentMultiOptionIfNotEmpty(const std::string& value,
const std::string& optionName)
{
if (!value.empty()) {
this->GetTestHandler()->AddPersistentMultiOption(optionName, value);
this->GetMemCheckHandler()->AddPersistentMultiOption(optionName, value);
}
}
bool cmCTest::SetArgsFromPreset(const std::string& presetName,
bool listPresets)
{
@@ -2310,6 +2333,13 @@ bool cmCTest::SetArgsFromPreset(const std::string& presetName,
return false;
}
if (!expandedPreset->ConditionResult) {
cmSystemTools::Error(cmStrCat("Cannot use disabled test preset in ",
workingDirectory, ": \"", presetName, '"'));
settingsFile.PrintTestPresetList();
return false;
}
auto configurePresetPair =
settingsFile.ConfigurePresets.find(expandedPreset->ConfigurePreset);
if (configurePresetPair == settingsFile.ConfigurePresets.end()) {
@@ -2412,7 +2442,7 @@ bool cmCTest::SetArgsFromPreset(const std::string& presetName,
if (expandedPreset->Filter->Include) {
this->SetPersistentOptionIfNotEmpty(
expandedPreset->Filter->Include->Name, "IncludeRegularExpression");
this->SetPersistentOptionIfNotEmpty(
this->AddPersistentMultiOptionIfNotEmpty(
expandedPreset->Filter->Include->Label, "LabelRegularExpression");
if (expandedPreset->Filter->Include->Index) {
@@ -2445,7 +2475,7 @@ bool cmCTest::SetArgsFromPreset(const std::string& presetName,
if (expandedPreset->Filter->Exclude) {
this->SetPersistentOptionIfNotEmpty(
expandedPreset->Filter->Exclude->Name, "ExcludeRegularExpression");
this->SetPersistentOptionIfNotEmpty(
this->AddPersistentMultiOptionIfNotEmpty(
expandedPreset->Filter->Exclude->Label,
"ExcludeLabelRegularExpression");
@@ -2826,9 +2856,10 @@ int cmCTest::ExecuteTests()
cmCTestLog(this, OUTPUT,
"Internal ctest changing into directory: " << workDir
<< std::endl);
if (cmSystemTools::ChangeDirectory(workDir) != 0) {
cmsys::Status status = cmSystemTools::ChangeDirectory(workDir);
if (!status) {
auto msg = "Failed to change working directory to \"" + workDir +
"\" : " + std::strerror(errno) + "\n";
"\" : " + status.GetString() + "\n";
cmCTestLog(this, ERROR_MESSAGE, msg);
return 1;
}
+2
View File
@@ -463,6 +463,8 @@ public:
private:
void SetPersistentOptionIfNotEmpty(const std::string& value,
const std::string& optionName);
void AddPersistentMultiOptionIfNotEmpty(const std::string& value,
const std::string& optionName);
int GenerateNotesFile(const std::string& files);
+85 -22
View File
@@ -17,10 +17,25 @@ struct cmCommandLineArgument
OneOrMore
};
enum class RequiresSeparator
{
Yes,
No
};
enum class ParseMode
{
Valid,
Invalid,
SyntaxError,
ValueError
};
std::string InvalidSyntaxMessage;
std::string InvalidValueMessage;
std::string Name;
Values Type;
RequiresSeparator SeparatorNeeded;
std::function<FunctionSignature> StoreCall;
template <typename FunctionType>
@@ -29,6 +44,19 @@ struct cmCommandLineArgument
, InvalidValueMessage(cmStrCat("Invalid value used with ", n))
, Name(std::move(n))
, Type(t)
, SeparatorNeeded(RequiresSeparator::Yes)
, StoreCall(std::forward<FunctionType>(func))
{
}
template <typename FunctionType>
cmCommandLineArgument(std::string n, Values t, RequiresSeparator s,
FunctionType&& func)
: InvalidSyntaxMessage(cmStrCat(" is invalid syntax for ", n))
, InvalidValueMessage(cmStrCat("Invalid value used with ", n))
, Name(std::move(n))
, Type(t)
, SeparatorNeeded(s)
, StoreCall(std::forward<FunctionType>(func))
{
}
@@ -40,14 +68,39 @@ struct cmCommandLineArgument
, InvalidValueMessage(std::move(failedMsg))
, Name(std::move(n))
, Type(t)
, SeparatorNeeded(RequiresSeparator::Yes)
, StoreCall(std::forward<FunctionType>(func))
{
}
template <typename FunctionType>
cmCommandLineArgument(std::string n, std::string failedMsg, Values t,
RequiresSeparator s, FunctionType&& func)
: InvalidSyntaxMessage(cmStrCat(" is invalid syntax for ", n))
, InvalidValueMessage(std::move(failedMsg))
, Name(std::move(n))
, Type(t)
, SeparatorNeeded(s)
, StoreCall(std::forward<FunctionType>(func))
{
}
bool matches(std::string const& input) const
{
return (this->Type == Values::Zero) ? (input == this->Name)
: cmHasPrefix(input, this->Name);
bool matched = false;
if (this->Type == Values::Zero) {
matched = (input == this->Name);
} else if (this->SeparatorNeeded == RequiresSeparator::No) {
matched = cmHasPrefix(input, this->Name);
} else if (cmHasPrefix(input, this->Name)) {
if (input.size() == this->Name.size()) {
matched = true;
} else {
matched =
(input[this->Name.size()] == '=' || input[this->Name.size()] == ' ');
}
}
return matched;
}
template <typename T, typename... CallState>
@@ -55,13 +108,6 @@ struct cmCommandLineArgument
std::vector<std::string> const& allArgs,
CallState&&... state) const
{
enum class ParseMode
{
Valid,
Invalid,
SyntaxError,
ValueError
};
ParseMode parseState = ParseMode::Valid;
if (this->Type == Values::Zero) {
@@ -95,19 +141,10 @@ struct cmCommandLineArgument
index = nextValueIndex;
}
} else {
// parse the string to get the value
auto possible_value = cm::string_view(input).substr(this->Name.size());
if (possible_value.empty()) {
parseState = ParseMode::ValueError;
} else if (possible_value[0] == '=') {
possible_value.remove_prefix(1);
if (possible_value.empty()) {
parseState = ParseMode::ValueError;
}
}
auto value = this->extract_single_value(input, parseState);
if (parseState == ParseMode::Valid) {
parseState = this->StoreCall(std::string(possible_value),
std::forward<CallState>(state)...)
parseState =
this->StoreCall(value, std::forward<CallState>(state)...)
? ParseMode::Valid
: ParseMode::Invalid;
}
@@ -145,7 +182,13 @@ struct cmCommandLineArgument
index = (nextValueIndex - 1);
}
} else {
parseState = ParseMode::SyntaxError;
auto value = this->extract_single_value(input, parseState);
if (parseState == ParseMode::Valid) {
parseState =
this->StoreCall(value, std::forward<CallState>(state)...)
? ParseMode::Valid
: ParseMode::Invalid;
}
}
}
@@ -157,4 +200,24 @@ struct cmCommandLineArgument
}
return (parseState == ParseMode::Valid);
}
private:
std::string extract_single_value(std::string const& input,
ParseMode& parseState) const
{
// parse the string to get the value
auto possible_value = cm::string_view(input).substr(this->Name.size());
if (possible_value.empty()) {
parseState = ParseMode::ValueError;
} else if (possible_value[0] == '=') {
possible_value.remove_prefix(1);
if (possible_value.empty()) {
parseState = ParseMode::ValueError;
}
}
if (parseState == ParseMode::Valid && possible_value[0] == ' ') {
possible_value.remove_prefix(1);
}
return std::string(possible_value);
}
};
+1 -2
View File
@@ -241,8 +241,7 @@ std::string cmCommonTargetGenerator::GetManifests(const std::string& config)
manifests.reserve(manifest_srcs.size());
for (cmSourceFile const* manifest_src : manifest_srcs) {
manifests.push_back(this->LocalCommonGenerator->ConvertToOutputFormat(
this->LocalCommonGenerator->MaybeConvertToRelativePath(
this->LocalCommonGenerator->GetWorkingDirectory(),
this->LocalCommonGenerator->MaybeRelativeToWorkDir(
manifest_src->GetFullPath()),
cmOutputConverter::SHELL));
}
+19
View File
@@ -701,6 +701,10 @@ void cmComputeLinkInformation::AddItem(BT<std::string> const& item,
this->AddTargetItem(lib, tgt);
this->AddLibraryRuntimeInfo(lib.Value, tgt);
if (tgt && tgt->GetType() == cmStateEnums::SHARED_LIBRARY &&
this->Target->IsDLLPlatform()) {
this->AddRuntimeDLL(tgt);
}
}
} else {
// This is not a CMake target. Use the name given.
@@ -728,6 +732,13 @@ void cmComputeLinkInformation::AddItem(BT<std::string> const& item,
void cmComputeLinkInformation::AddSharedDepItem(BT<std::string> const& item,
const cmGeneratorTarget* tgt)
{
// Record dependencies on DLLs.
if (tgt && tgt->GetType() == cmStateEnums::SHARED_LIBRARY &&
this->Target->IsDLLPlatform() &&
this->SharedDependencyMode != SharedDepModeLink) {
this->AddRuntimeDLL(tgt);
}
// If dropping shared library dependencies, ignore them.
if (this->SharedDependencyMode == SharedDepModeNone) {
return;
@@ -799,6 +810,14 @@ void cmComputeLinkInformation::AddSharedDepItem(BT<std::string> const& item,
}
}
void cmComputeLinkInformation::AddRuntimeDLL(cmGeneratorTarget const* tgt)
{
if (std::find(this->RuntimeDLLs.begin(), this->RuntimeDLLs.end(), tgt) ==
this->RuntimeDLLs.end()) {
this->RuntimeDLLs.emplace_back(tgt);
}
}
void cmComputeLinkInformation::ComputeLinkTypeInfo()
{
// Check whether archives may actually be shared libraries.
+6
View File
@@ -64,6 +64,10 @@ public:
std::string GetRPathString(bool for_install) const;
std::string GetChrpathString() const;
std::set<cmGeneratorTarget const*> const& GetSharedLibrariesLinked() const;
std::vector<cmGeneratorTarget const*> const& GetRuntimeDLLs() const
{
return this->RuntimeDLLs;
}
std::string const& GetLibLinkFileFlag() const
{
@@ -81,6 +85,7 @@ private:
void AddItem(BT<std::string> const& item, const cmGeneratorTarget* tgt);
void AddSharedDepItem(BT<std::string> const& item,
cmGeneratorTarget const* tgt);
void AddRuntimeDLL(cmGeneratorTarget const* tgt);
// Output information.
ItemVector Items;
@@ -89,6 +94,7 @@ private:
std::vector<std::string> FrameworkPaths;
std::vector<std::string> RuntimeSearchPath;
std::set<cmGeneratorTarget const*> SharedLibrariesLinked;
std::vector<cmGeneratorTarget const*> RuntimeDLLs;
// Context information.
cmGeneratorTarget const* const Target;
+2 -2
View File
@@ -654,10 +654,10 @@ bool cmConditionEvaluator::HandleLevel2(cmArgumentList& newArgs,
if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
this->IsKeyword(keyIS_NEWER_THAN, *argP1)) {
int fileIsNewer = 0;
bool success = cmSystemTools::FileTimeCompare(
cmsys::Status ftcStatus = cmSystemTools::FileTimeCompare(
arg->GetValue(), (argP2)->GetValue(), &fileIsNewer);
this->HandleBinaryOp(
(!success || fileIsNewer == 1 || fileIsNewer == 0), reducible, arg,
(!ftcStatus || fileIsNewer == 1 || fileIsNewer == 0), reducible, arg,
newArgs, argP1, argP2);
}
+18 -5
View File
@@ -8,6 +8,7 @@
#include <sstream>
#include <utility>
#include <cm/string_view>
#include <cmext/string_view>
#include "cmsys/Directory.hxx"
@@ -217,6 +218,7 @@ std::string const kCMAKE_POSITION_INDEPENDENT_CODE =
std::string const kCMAKE_SYSROOT = "CMAKE_SYSROOT";
std::string const kCMAKE_SYSROOT_COMPILE = "CMAKE_SYSROOT_COMPILE";
std::string const kCMAKE_SYSROOT_LINK = "CMAKE_SYSROOT_LINK";
std::string const kCMAKE_ARMClang_CMP0123 = "CMAKE_ARMClang_CMP0123";
std::string const kCMAKE_TRY_COMPILE_OSX_ARCHITECTURES =
"CMAKE_TRY_COMPILE_OSX_ARCHITECTURES";
std::string const kCMAKE_TRY_COMPILE_PLATFORM_VARIABLES =
@@ -552,6 +554,13 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
fprintf(fout, "cmake_policy(SET CMP0104 OLD)\n");
}
/* Set ARMClang cpu/arch policy to match outer project. */
if (cmProp cmp0123 =
this->Makefile->GetDefinition(kCMAKE_ARMClang_CMP0123)) {
fprintf(fout, "cmake_policy(SET CMP0123 %s)\n",
*cmp0123 == "NEW"_s ? "NEW" : "OLD");
}
std::string projectLangs;
for (std::string const& li : testLangs) {
projectLangs += " " + li;
@@ -1015,17 +1024,21 @@ void cmCoreTryCompile::CleanupFiles(std::string const& binDir)
// cannot delete them immediately. Try a few times.
cmSystemTools::WindowsFileRetry retry =
cmSystemTools::GetWindowsFileRetry();
while (!cmSystemTools::RemoveFile(fullPath) && --retry.Count &&
cmSystemTools::FileExists(fullPath)) {
cmsys::Status status;
while (!((status = cmSystemTools::RemoveFile(fullPath))) &&
--retry.Count && cmSystemTools::FileExists(fullPath)) {
cmSystemTools::Delay(retry.Delay);
}
if (retry.Count == 0)
#else
if (!cmSystemTools::RemoveFile(fullPath))
cmsys::Status status = cmSystemTools::RemoveFile(fullPath);
if (!status)
#endif
{
std::string m = "Remove failed on file: " + fullPath;
cmSystemTools::ReportLastSystemError(m.c_str());
this->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
cmStrCat("The file:\n ", fullPath,
"\ncould not be removed:\n ", status.GetString()));
}
}
}
+8 -3
View File
@@ -90,10 +90,15 @@ bool cmCreateTestSourceList(std::vector<std::string> const& args,
std::replace(func_name.begin(), func_name.end(), ' ', '_');
std::replace(func_name.begin(), func_name.end(), '/', '_');
std::replace(func_name.begin(), func_name.end(), ':', '_');
bool already_declared =
std::find(tests_func_name.begin(), tests_func_name.end(), func_name) !=
tests_func_name.end();
tests_func_name.push_back(func_name);
forwardDeclareCode += "int ";
forwardDeclareCode += func_name;
forwardDeclareCode += "(int, char*[]);\n";
if (!already_declared) {
forwardDeclareCode += "int ";
forwardDeclareCode += func_name;
forwardDeclareCode += "(int, char*[]);\n";
}
}
std::string functionMapCode;
+47 -8
View File
@@ -139,11 +139,21 @@ std::vector<std::string> EvaluateOutputs(std::vector<std::string> const& paths,
}
return outputs;
}
std::string EvaluateDepfile(std::string const& path,
cmGeneratorExpression const& ge,
cmLocalGenerator* lg, std::string const& config)
{
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(path);
return cge->Evaluate(lg, config);
}
}
cmCustomCommandGenerator::cmCustomCommandGenerator(
cmCustomCommand const& cc, std::string config, cmLocalGenerator* lg,
bool transformDepfile, cm::optional<std::string> crossConfig)
bool transformDepfile, cm::optional<std::string> crossConfig,
std::function<std::string(const std::string&, const std::string&)>
computeInternalDepfile)
: CC(&cc)
, OutputConfig(crossConfig ? *crossConfig : config)
, CommandConfig(std::move(config))
@@ -151,7 +161,15 @@ cmCustomCommandGenerator::cmCustomCommandGenerator(
, OldStyle(cc.GetEscapeOldStyle())
, MakeVars(cc.GetEscapeAllowMakeVars())
, EmulatorsWithArguments(cc.GetCommandLines().size())
, ComputeInternalDepfile(std::move(computeInternalDepfile))
{
if (!this->ComputeInternalDepfile) {
this->ComputeInternalDepfile =
[this](const std::string& cfg, const std::string& file) -> std::string {
return this->GetInternalDepfileName(cfg, file);
};
}
cmGeneratorExpression ge(cc.GetBacktrace());
const cmCustomCommandLines& cmdlines = this->CC->GetCommandLines();
@@ -208,6 +226,9 @@ cmCustomCommandGenerator::cmCustomCommandGenerator(
case cmDepfileFormat::VsTlog:
argv.emplace_back("vstlog");
break;
case cmDepfileFormat::MakeDepfile:
argv.emplace_back("makedepfile");
break;
}
argv.push_back(this->LG->GetSourceDirectory());
argv.push_back(this->LG->GetCurrentSourceDirectory());
@@ -381,9 +402,20 @@ void cmCustomCommandGenerator::AppendArguments(unsigned int c,
}
}
std::string cmCustomCommandGenerator::GetDepfile() const
{
const auto& depfile = this->CC->GetDepfile();
if (depfile.empty()) {
return "";
}
cmGeneratorExpression ge(this->CC->GetBacktrace());
return EvaluateDepfile(depfile, ge, this->LG, this->OutputConfig);
}
std::string cmCustomCommandGenerator::GetFullDepfile() const
{
std::string depfile = this->CC->GetDepfile();
std::string depfile = this->GetDepfile();
if (depfile.empty()) {
return "";
}
@@ -394,17 +426,14 @@ std::string cmCustomCommandGenerator::GetFullDepfile() const
return cmSystemTools::CollapseFullPath(depfile);
}
std::string cmCustomCommandGenerator::GetInternalDepfile() const
std::string cmCustomCommandGenerator::GetInternalDepfileName(
const std::string& /*config*/, const std::string& depfile)
{
std::string depfile = this->GetFullDepfile();
if (depfile.empty()) {
return "";
}
cmCryptoHash hash(cmCryptoHash::AlgoSHA256);
std::string extension;
switch (*this->LG->GetGlobalGenerator()->DepfileFormat()) {
case cmDepfileFormat::GccDepfile:
case cmDepfileFormat::MakeDepfile:
extension = ".d";
break;
case cmDepfileFormat::VsTlog:
@@ -415,6 +444,16 @@ std::string cmCustomCommandGenerator::GetInternalDepfile() const
hash.HashString(depfile), extension);
}
std::string cmCustomCommandGenerator::GetInternalDepfile() const
{
std::string depfile = this->GetFullDepfile();
if (depfile.empty()) {
return "";
}
return this->ComputeInternalDepfile(this->OutputConfig, depfile);
}
const char* cmCustomCommandGenerator::GetComment() const
{
return this->CC->GetComment();
+11 -3
View File
@@ -4,6 +4,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <functional>
#include <set>
#include <string>
#include <utility>
@@ -19,6 +20,8 @@ class cmLocalGenerator;
class cmCustomCommandGenerator
{
std::string GetInternalDepfileName(const std::string&, const std::string&);
cmCustomCommand const* CC;
std::string OutputConfig;
std::string CommandConfig;
@@ -32,15 +35,19 @@ class cmCustomCommandGenerator
std::vector<std::string> Depends;
std::string WorkingDirectory;
std::set<BT<std::pair<std::string, bool>>> Utilities;
std::function<std::string(const std::string&, const std::string&)>
ComputeInternalDepfile;
void FillEmulatorsWithArguments();
std::vector<std::string> GetCrossCompilingEmulator(unsigned int c) const;
const char* GetArgv0Location(unsigned int c) const;
public:
cmCustomCommandGenerator(cmCustomCommand const& cc, std::string config,
cmLocalGenerator* lg, bool transformDepfile = true,
cm::optional<std::string> crossConfig = {});
cmCustomCommandGenerator(
cmCustomCommand const& cc, std::string config, cmLocalGenerator* lg,
bool transformDepfile = true, cm::optional<std::string> crossConfig = {},
std::function<std::string(const std::string&, const std::string&)>
computeInternalDepfile = {});
cmCustomCommandGenerator(const cmCustomCommandGenerator&) = delete;
cmCustomCommandGenerator(cmCustomCommandGenerator&&) = default;
cmCustomCommandGenerator& operator=(const cmCustomCommandGenerator&) =
@@ -57,6 +64,7 @@ public:
std::vector<std::string> const& GetDepends() const;
std::set<BT<std::pair<std::string, bool>>> const& GetUtilities() const;
bool HasOnlyEmptyCommandLines() const;
std::string GetDepfile() const;
std::string GetFullDepfile() const;
std::string GetInternalDepfile() const;
+1 -2
View File
@@ -229,11 +229,10 @@ bool cmDepends::CheckDependencies(std::istream& internalDepends,
void cmDepends::SetIncludePathFromLanguage(const std::string& lang)
{
// Look for the new per "TARGET_" variant first:
cmProp includePath = nullptr;
std::string includePathVar =
cmStrCat("CMAKE_", lang, "_TARGET_INCLUDE_PATH");
cmMakefile* mf = this->LocalGenerator->GetMakefile();
includePath = mf->GetDefinition(includePathVar);
cmProp includePath = mf->GetDefinition(includePathVar);
if (includePath) {
cmExpandList(*includePath, this->IncludePath);
} else {
+2 -5
View File
@@ -90,13 +90,10 @@ bool cmDependsC::WriteDependencies(const std::set<std::string>& sources,
std::set<std::string> dependencies;
bool haveDeps = false;
std::string binDir = this->LocalGenerator->GetBinaryDirectory();
// Compute a path to the object file to write to the internal depend file.
// Any existing content of the internal depend file has already been
// loaded in ValidDeps with this path as a key.
std::string obj_i =
this->LocalGenerator->MaybeConvertToRelativePath(binDir, obj);
std::string obj_i = this->LocalGenerator->MaybeRelativeToTopBinDir(obj);
if (this->ValidDeps != nullptr) {
auto const tmpIt = this->ValidDeps->find(obj_i);
@@ -228,7 +225,7 @@ bool cmDependsC::WriteDependencies(const std::set<std::string>& sources,
}
for (std::string const& dep : dependencies) {
std::string dependee = this->LocalGenerator->ConvertToMakefilePath(
this->LocalGenerator->MaybeConvertToRelativePath(binDir, dep));
this->LocalGenerator->MaybeRelativeToTopBinDir(dep));
if (supportLongLineDepend) {
makeDepends << ' ' << lineContinue << ' ' << dependee;
} else {
+6 -8
View File
@@ -190,21 +190,19 @@ void cmDependsCompiler::WriteDependencies(
bool supportLongLineDepend = static_cast<cmGlobalUnixMakefileGenerator3*>(
this->LocalGenerator->GetGlobalGenerator())
->SupportsLongLineDependencies();
const auto& binDir = this->LocalGenerator->GetBinaryDirectory();
cmDepends::DependencyMap makeDependencies(dependencies);
std::unordered_set<cm::string_view> phonyTargets;
// external dependencies file
for (auto& node : makeDependencies) {
auto target = this->LocalGenerator->ConvertToMakefilePath(
this->LocalGenerator->MaybeConvertToRelativePath(binDir, node.first));
this->LocalGenerator->MaybeRelativeToTopBinDir(node.first));
auto& deps = node.second;
std::transform(
deps.cbegin(), deps.cend(), deps.begin(),
[this, &binDir](const std::string& dep) {
return this->LocalGenerator->ConvertToMakefilePath(
this->LocalGenerator->MaybeConvertToRelativePath(binDir, dep));
});
std::transform(deps.cbegin(), deps.cend(), deps.begin(),
[this](const std::string& dep) {
return this->LocalGenerator->ConvertToMakefilePath(
this->LocalGenerator->MaybeRelativeToTopBinDir(dep));
});
bool first_dep = true;
if (supportLongLineDepend) {
+10 -25
View File
@@ -17,8 +17,6 @@
#include "cmMakefile.h"
#include "cmOutputConverter.h"
#include "cmProperty.h"
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -192,8 +190,6 @@ bool cmDependsFortran::Finalize(std::ostream& makeDepends,
cmGeneratedFileStream fcStream(fcName);
fcStream << "# Remove fortran modules provided by this target.\n";
fcStream << "FILE(REMOVE";
std::string currentBinDir =
this->LocalGenerator->GetCurrentBinaryDirectory();
for (std::string const& i : provides) {
std::string mod_upper = cmStrCat(mod_dir, '/');
std::string mod_lower = cmStrCat(mod_dir, '/');
@@ -201,13 +197,13 @@ bool cmDependsFortran::Finalize(std::ostream& makeDepends,
std::string stamp = cmStrCat(stamp_dir, '/', i, ".stamp");
fcStream << "\n"
" \""
<< this->MaybeConvertToRelativePath(currentBinDir, mod_lower)
<< this->LocalGenerator->MaybeRelativeToCurBinDir(mod_lower)
<< "\"\n"
" \""
<< this->MaybeConvertToRelativePath(currentBinDir, mod_upper)
<< this->LocalGenerator->MaybeRelativeToCurBinDir(mod_upper)
<< "\"\n"
" \""
<< this->MaybeConvertToRelativePath(currentBinDir, stamp)
<< this->LocalGenerator->MaybeRelativeToCurBinDir(stamp)
<< "\"\n";
}
fcStream << " )\n";
@@ -317,8 +313,7 @@ bool cmDependsFortran::WriteDependenciesReal(std::string const& obj,
std::string const& src = info.Source;
// Write the include dependencies to the output stream.
std::string binDir = this->LocalGenerator->GetBinaryDirectory();
std::string obj_i = this->MaybeConvertToRelativePath(binDir, obj);
std::string obj_i = this->LocalGenerator->MaybeRelativeToTopBinDir(obj);
std::string obj_m = cmSystemTools::ConvertToOutputPath(obj_i);
internalDepends << obj_i << "\n " << src << '\n';
if (!info.Includes.empty()) {
@@ -333,7 +328,7 @@ bool cmDependsFortran::WriteDependenciesReal(std::string const& obj,
}
for (std::string const& i : info.Includes) {
std::string dependee = cmSystemTools::ConvertToOutputPath(
this->MaybeConvertToRelativePath(binDir, i));
this->LocalGenerator->MaybeRelativeToTopBinDir(i));
if (supportLongLineDepend) {
makeDepends << ' ' << lineContinue << ' ' << dependee;
} else {
@@ -360,7 +355,7 @@ bool cmDependsFortran::WriteDependenciesReal(std::string const& obj,
if (!required->second.empty()) {
// This module is known. Depend on its timestamp file.
std::string stampFile = cmSystemTools::ConvertToOutputPath(
this->MaybeConvertToRelativePath(binDir, required->second));
this->LocalGenerator->MaybeRelativeToTopBinDir(required->second));
makeDepends << obj_m << ": " << stampFile << '\n';
} else {
// This module is not known to CMake. Try to locate it where
@@ -368,7 +363,7 @@ bool cmDependsFortran::WriteDependenciesReal(std::string const& obj,
std::string module;
if (this->FindModule(i, module)) {
module = cmSystemTools::ConvertToOutputPath(
this->MaybeConvertToRelativePath(binDir, module));
this->LocalGenerator->MaybeRelativeToTopBinDir(module));
makeDepends << obj_m << ": " << module << '\n';
}
}
@@ -387,10 +382,10 @@ bool cmDependsFortran::WriteDependenciesReal(std::string const& obj,
// try various cases for the real mod file name.
std::string modFile = cmStrCat(mod_dir, '/', i);
modFile = this->LocalGenerator->ConvertToOutputFormat(
this->MaybeConvertToRelativePath(binDir, modFile),
this->LocalGenerator->MaybeRelativeToTopBinDir(modFile),
cmOutputConverter::SHELL);
std::string stampFile = cmStrCat(stamp_dir, '/', i, ".stamp");
stampFile = this->MaybeConvertToRelativePath(binDir, stampFile);
stampFile = this->LocalGenerator->MaybeRelativeToTopBinDir(stampFile);
std::string const stampFileForShell =
this->LocalGenerator->ConvertToOutputFormat(stampFile,
cmOutputConverter::SHELL);
@@ -425,7 +420,7 @@ bool cmDependsFortran::WriteDependenciesReal(std::string const& obj,
// the target finishes building.
std::string driver = cmStrCat(this->TargetDirectory, "/build");
driver = cmSystemTools::ConvertToOutputPath(
this->MaybeConvertToRelativePath(binDir, driver));
this->LocalGenerator->MaybeRelativeToTopBinDir(driver));
makeDepends << driver << ": " << obj_m << ".provides.build\n";
}
@@ -681,13 +676,3 @@ bool cmDependsFortran::ModulesDiffer(const std::string& modFile,
// content.
return cmFortranStreamsDiffer(finModFile, finStampFile);
}
std::string cmDependsFortran::MaybeConvertToRelativePath(
std::string const& base, std::string const& path)
{
if (!this->LocalGenerator->GetStateSnapshot().GetDirectory().ContainsBoth(
base, path)) {
return path;
}
return cmSystemTools::ForceToRelativePath(base, path);
}
-4
View File
@@ -85,8 +85,4 @@ protected:
// Internal implementation details.
std::unique_ptr<cmDependsFortranInternals> Internal;
private:
std::string MaybeConvertToRelativePath(std::string const& base,
std::string const& path);
};
+3 -3
View File
@@ -924,13 +924,13 @@ void cmExportFileGenerator::GeneratePolicyHeaderCode(std::ostream& os)
// Isolate the file policy level.
// Support CMake versions as far back as 2.6 but also support using NEW
// policy settings for up to CMake 3.18 (this upper limit may be reviewed
// policy settings for up to CMake 3.19 (this upper limit may be reviewed
// and increased from time to time). This reduces the opportunity for CMake
// warnings when an older export file is later used with newer CMake
// versions.
/* clang-format off */
os << "cmake_policy(PUSH)\n"
<< "cmake_policy(VERSION 2.6...3.18)\n";
<< "cmake_policy(VERSION 2.6...3.19)\n";
/* clang-format on */
}
@@ -1229,7 +1229,7 @@ bool cmExportFileGenerator::PopulateExportProperties(
return false;
}
cmProp propertyValue = targetProperties.GetPropertyValue(prop);
if (propertyValue == nullptr) {
if (!propertyValue) {
// Asked to export a property that isn't defined on the target. Do not
// consider this an error, there's just nothing to export.
continue;
+7 -7
View File
@@ -248,17 +248,17 @@ void cmExtraEclipseCDT4Generator::AddEnvVar(std::ostream& out,
// now we have both, decide which one to use
std::string valueToUse;
if (!envVarSet && cacheValue == nullptr) {
if (!envVarSet && !cacheValue) {
// nothing known, do nothing
valueToUse.clear();
} else if (envVarSet && cacheValue == nullptr) {
} else if (envVarSet && !cacheValue) {
// 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, cacheEntryName.c_str(),
cmStateEnums::STRING, true);
mf->GetCMakeInstance()->SaveCache(lg.GetBinaryDirectory());
} else if (!envVarSet && cacheValue != nullptr) {
} else if (!envVarSet && cacheValue) {
// It is already in the cache, but not in the env, so use it from the cache
valueToUse = *cacheValue;
} else {
@@ -655,7 +655,7 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
xml.EndElement(); // extension
} else {
std::string systemName = mf->GetSafeDefinition("CMAKE_SYSTEM_NAME");
if (systemName == "CYGWIN") {
if (systemName == "CYGWIN" || systemName == "MSYS") {
xml.StartElement("extension");
xml.Attribute("id", "org.eclipse.cdt.core.Cygwin_PE");
xml.Attribute("point", "org.eclipse.cdt.core.BinaryParser");
@@ -916,8 +916,8 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
// and UTILITY targets
for (const auto& lgen : this->GlobalGenerator->GetLocalGenerators()) {
const auto& targets = lgen->GetGeneratorTargets();
std::string subdir = lgen->MaybeConvertToRelativePath(
this->HomeOutputDirectory, lgen->GetCurrentBinaryDirectory());
std::string subdir =
lgen->MaybeRelativeToTopBinDir(lgen->GetCurrentBinaryDirectory());
if (subdir == ".") {
subdir.clear();
}
@@ -1097,7 +1097,7 @@ void cmExtraEclipseCDT4Generator::AppendStorageScanners(
compiler = "gcc";
}
// the following right now hardcodes gcc behaviour :-/
// the following right now hardcodes gcc behavior :-/
std::string compilerArgs =
"-E -P -v -dD ${plugin_state_location}/${specs_file}";
if (!arg1.empty()) {
+1 -1
View File
@@ -130,7 +130,7 @@ void cmExtraKateGenerator::WriteTargets(const cmLocalGenerator& lg,
if (targetName == "edit_cache") {
cmProp editCommand =
localGen->GetMakefile()->GetDefinition("CMAKE_EDIT_COMMAND");
if (editCommand == nullptr ||
if (!editCommand ||
strstr(editCommand->c_str(), "ccmake") != nullptr) {
insertTarget = false;
}
+2 -1
View File
@@ -435,7 +435,8 @@ std::string cmExtraSublimeTextGenerator::ComputeIncludes(
lg->GetIncludeDirectories(includes, target, language, config);
std::string includesString =
lg->GetIncludeFlags(includes, target, language, true, false, config);
lg->GetIncludeFlags(includes, target, language, config, false,
cmLocalGenerator::IncludePathStyle::Absolute);
return includesString;
}
+1 -1
View File
@@ -686,7 +686,7 @@ std::string cmFileAPI::NoSupportedVersion(
// The "codemodel" object kind.
static unsigned int const CodeModelV2Minor = 2;
static unsigned int const CodeModelV2Minor = 3;
void cmFileAPI::BuildClientRequestCodeModel(
ClientRequest& r, std::vector<RequestVersion> const& versions)
+392 -91
View File
@@ -20,11 +20,16 @@
#include <cm3p/json/value.h>
#include "cmCryptoHash.h"
#include "cmExportSet.h"
#include "cmFileAPI.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmInstallDirectoryGenerator.h"
#include "cmInstallExportGenerator.h"
#include "cmInstallFilesGenerator.h"
#include "cmInstallGenerator.h"
#include "cmInstallScriptGenerator.h"
#include "cmInstallSubdirectoryGenerator.h"
#include "cmInstallTargetGenerator.h"
#include "cmLinkLineComputer.h"
@@ -42,103 +47,17 @@
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTargetDepend.h"
#include "cmTargetExport.h"
#include "cmake.h"
namespace {
class Codemodel
{
cmFileAPI& FileAPI;
unsigned long Version;
Json::Value DumpPaths();
Json::Value DumpConfigurations();
Json::Value DumpConfiguration(std::string const& config);
public:
Codemodel(cmFileAPI& fileAPI, unsigned long version);
Json::Value Dump();
};
class CodemodelConfig
{
cmFileAPI& FileAPI;
unsigned long Version;
std::string const& Config;
std::string TopSource;
std::string TopBuild;
struct Directory
{
cmStateSnapshot Snapshot;
cmLocalGenerator const* LocalGenerator = nullptr;
Json::Value TargetIndexes = Json::arrayValue;
Json::ArrayIndex ProjectIndex;
bool HasInstallRule = false;
};
std::map<cmStateSnapshot, Json::ArrayIndex, cmStateSnapshot::StrictWeakOrder>
DirectoryMap;
std::vector<Directory> Directories;
struct Project
{
cmStateSnapshot Snapshot;
static const Json::ArrayIndex NoParentIndex =
static_cast<Json::ArrayIndex>(-1);
Json::ArrayIndex ParentIndex = NoParentIndex;
Json::Value ChildIndexes = Json::arrayValue;
Json::Value DirectoryIndexes = Json::arrayValue;
Json::Value TargetIndexes = Json::arrayValue;
};
std::map<cmStateSnapshot, Json::ArrayIndex, cmStateSnapshot::StrictWeakOrder>
ProjectMap;
std::vector<Project> Projects;
void ProcessDirectories();
Json::ArrayIndex GetDirectoryIndex(cmLocalGenerator const* lg);
Json::ArrayIndex GetDirectoryIndex(cmStateSnapshot s);
Json::ArrayIndex AddProject(cmStateSnapshot s);
Json::Value DumpTargets();
Json::Value DumpTarget(cmGeneratorTarget* gt, Json::ArrayIndex ti);
Json::Value DumpDirectories();
Json::Value DumpDirectory(Directory& d);
Json::Value DumpProjects();
Json::Value DumpProject(Project& p);
Json::Value DumpMinimumCMakeVersion(cmStateSnapshot s);
public:
CodemodelConfig(cmFileAPI& fileAPI, unsigned long version,
std::string const& config);
Json::Value Dump();
};
using TargetIndexMapType =
std::unordered_map<cmGeneratorTarget const*, Json::ArrayIndex>;
std::string RelativeIfUnder(std::string const& top, std::string const& in)
{
std::string out;
if (in == top) {
out = ".";
} else if (cmSystemTools::IsSubDirectory(in, top)) {
out = in.substr(top.size() + 1);
} else {
out = in;
}
return out;
}
std::string TargetId(cmGeneratorTarget const* gt, std::string const& topBuild)
{
cmCryptoHash hasher(cmCryptoHash::AlgoSHA3_256);
std::string path = RelativeIfUnder(
topBuild, gt->GetLocalGenerator()->GetCurrentBinaryDirectory());
std::string hash = hasher.HashString(path);
hash.resize(20, '0');
return gt->GetName() + CMAKE_DIRECTORY_ID_SEP + hash;
return cmSystemTools::RelativeIfUnder(top, in);
}
class JBTIndex
@@ -290,6 +209,91 @@ Json::Value BacktraceData::Dump()
return backtraceGraph;
}
class Codemodel
{
cmFileAPI& FileAPI;
unsigned long Version;
Json::Value DumpPaths();
Json::Value DumpConfigurations();
Json::Value DumpConfiguration(std::string const& config);
public:
Codemodel(cmFileAPI& fileAPI, unsigned long version);
Json::Value Dump();
};
class CodemodelConfig
{
cmFileAPI& FileAPI;
unsigned long Version;
std::string const& Config;
std::string TopSource;
std::string TopBuild;
struct Directory
{
cmStateSnapshot Snapshot;
cmLocalGenerator const* LocalGenerator = nullptr;
Json::Value TargetIndexes = Json::arrayValue;
Json::ArrayIndex ProjectIndex;
bool HasInstallRule = false;
};
std::map<cmStateSnapshot, Json::ArrayIndex, cmStateSnapshot::StrictWeakOrder>
DirectoryMap;
std::vector<Directory> Directories;
struct Project
{
cmStateSnapshot Snapshot;
static const Json::ArrayIndex NoParentIndex =
static_cast<Json::ArrayIndex>(-1);
Json::ArrayIndex ParentIndex = NoParentIndex;
Json::Value ChildIndexes = Json::arrayValue;
Json::Value DirectoryIndexes = Json::arrayValue;
Json::Value TargetIndexes = Json::arrayValue;
};
std::map<cmStateSnapshot, Json::ArrayIndex, cmStateSnapshot::StrictWeakOrder>
ProjectMap;
std::vector<Project> Projects;
TargetIndexMapType TargetIndexMap;
void ProcessDirectories();
Json::ArrayIndex GetDirectoryIndex(cmLocalGenerator const* lg);
Json::ArrayIndex GetDirectoryIndex(cmStateSnapshot s);
Json::ArrayIndex AddProject(cmStateSnapshot s);
Json::Value DumpTargets();
Json::Value DumpTarget(cmGeneratorTarget* gt, Json::ArrayIndex ti);
Json::Value DumpDirectories();
Json::Value DumpDirectory(Directory& d);
Json::Value DumpDirectoryObject(Directory& d);
Json::Value DumpProjects();
Json::Value DumpProject(Project& p);
Json::Value DumpMinimumCMakeVersion(cmStateSnapshot s);
public:
CodemodelConfig(cmFileAPI& fileAPI, unsigned long version,
std::string const& config);
Json::Value Dump();
};
std::string TargetId(cmGeneratorTarget const* gt, std::string const& topBuild)
{
cmCryptoHash hasher(cmCryptoHash::AlgoSHA3_256);
std::string path = RelativeIfUnder(
topBuild, gt->GetLocalGenerator()->GetCurrentBinaryDirectory());
std::string hash = hasher.HashString(path);
hash.resize(20, '0');
return gt->GetName() + CMAKE_DIRECTORY_ID_SEP + hash;
}
struct CompileData
{
struct IncludeEntry
@@ -367,6 +371,31 @@ struct hash<CompileData>
} // namespace std
namespace {
class DirectoryObject
{
cmLocalGenerator const* LG = nullptr;
std::string const& Config;
TargetIndexMapType& TargetIndexMap;
std::string TopSource;
std::string TopBuild;
BacktraceData Backtraces;
void AddBacktrace(Json::Value& object, cmListFileBacktrace const& bt);
Json::Value DumpPaths();
Json::Value DumpInstallers();
Json::Value DumpInstaller(cmInstallGenerator* gen);
Json::Value DumpInstallerExportTargets(cmExportSet* exp);
Json::Value DumpInstallerPath(std::string const& top,
std::string const& fromPathIn,
std::string const& toPath);
public:
DirectoryObject(cmLocalGenerator const* lg, std::string const& config,
TargetIndexMapType& targetIndexMap);
Json::Value Dump();
};
class Target
{
cmGeneratorTarget* GT;
@@ -663,6 +692,8 @@ Json::Value CodemodelConfig::DumpTarget(cmGeneratorTarget* gt,
target["projectIndex"] = pi;
this->Projects[pi].TargetIndexes.append(ti);
this->TargetIndexMap[gt] = ti;
return target;
}
@@ -677,7 +708,7 @@ Json::Value CodemodelConfig::DumpDirectories()
Json::Value CodemodelConfig::DumpDirectory(Directory& d)
{
Json::Value directory = Json::objectValue;
Json::Value directory = this->DumpDirectoryObject(d);
std::string sourceDir = d.Snapshot.GetDirectory().GetCurrentSource();
directory["source"] = RelativeIfUnder(this->TopSource, sourceDir);
@@ -717,6 +748,31 @@ Json::Value CodemodelConfig::DumpDirectory(Directory& d)
return directory;
}
Json::Value CodemodelConfig::DumpDirectoryObject(Directory& d)
{
std::string prefix = "directory";
std::string sourceDirRel = RelativeIfUnder(
this->TopSource, d.Snapshot.GetDirectory().GetCurrentSource());
std::string buildDirRel = RelativeIfUnder(
this->TopBuild, d.Snapshot.GetDirectory().GetCurrentBinary());
if (!cmSystemTools::FileIsFullPath(buildDirRel)) {
prefix = cmStrCat(prefix, '-', buildDirRel);
} else if (!cmSystemTools::FileIsFullPath(sourceDirRel)) {
prefix = cmStrCat(prefix, '-', sourceDirRel);
}
for (char& c : prefix) {
if (c == '/' || c == '\\') {
c = '.';
}
}
if (!this->Config.empty()) {
prefix += "-" + this->Config;
}
DirectoryObject dir(d.LocalGenerator, this->Config, this->TargetIndexMap);
return this->FileAPI.MaybeJsonFile(dir.Dump(), prefix);
}
Json::Value CodemodelConfig::DumpProjects()
{
Json::Value projects = Json::arrayValue;
@@ -760,6 +816,251 @@ Json::Value CodemodelConfig::DumpMinimumCMakeVersion(cmStateSnapshot s)
return minimumCMakeVersion;
}
DirectoryObject::DirectoryObject(cmLocalGenerator const* lg,
std::string const& config,
TargetIndexMapType& targetIndexMap)
: LG(lg)
, Config(config)
, TargetIndexMap(targetIndexMap)
, TopSource(lg->GetGlobalGenerator()->GetCMakeInstance()->GetHomeDirectory())
, TopBuild(
lg->GetGlobalGenerator()->GetCMakeInstance()->GetHomeOutputDirectory())
, Backtraces(this->TopSource)
{
}
Json::Value DirectoryObject::Dump()
{
Json::Value directoryObject = Json::objectValue;
directoryObject["paths"] = this->DumpPaths();
directoryObject["installers"] = this->DumpInstallers();
directoryObject["backtraceGraph"] = this->Backtraces.Dump();
return directoryObject;
}
void DirectoryObject::AddBacktrace(Json::Value& object,
cmListFileBacktrace const& bt)
{
if (JBTIndex backtrace = this->Backtraces.Add(bt)) {
object["backtrace"] = backtrace.Index;
}
}
Json::Value DirectoryObject::DumpPaths()
{
Json::Value paths = Json::objectValue;
std::string const& sourceDir = this->LG->GetCurrentSourceDirectory();
paths["source"] = RelativeIfUnder(this->TopSource, sourceDir);
std::string const& buildDir = this->LG->GetCurrentBinaryDirectory();
paths["build"] = RelativeIfUnder(this->TopBuild, buildDir);
return paths;
}
Json::Value DirectoryObject::DumpInstallers()
{
Json::Value installers = Json::arrayValue;
for (const auto& gen : this->LG->GetMakefile()->GetInstallGenerators()) {
Json::Value installer = this->DumpInstaller(gen.get());
if (!installer.empty()) {
installers.append(std::move(installer)); // NOLINT(*)
}
}
return installers;
}
Json::Value DirectoryObject::DumpInstaller(cmInstallGenerator* gen)
{
Json::Value installer = Json::objectValue;
// Exclude subdirectory installers. They are implementation details.
if (dynamic_cast<cmInstallSubdirectoryGenerator*>(gen)) {
return installer;
}
// Exclude installers not used in this configuration.
if (!gen->InstallsForConfig(this->Config)) {
return installer;
}
// Add fields specific to each kind of install generator.
if (auto* installTarget = dynamic_cast<cmInstallTargetGenerator*>(gen)) {
cmInstallTargetGenerator::Files const& files =
installTarget->GetFiles(this->Config);
if (files.From.empty()) {
return installer;
}
installer["type"] = "target";
installer["destination"] = installTarget->GetDestination(this->Config);
installer["targetId"] =
TargetId(installTarget->GetTarget(), this->TopBuild);
installer["targetIndex"] =
this->TargetIndexMap[installTarget->GetTarget()];
std::string fromDir = files.FromDir;
if (!fromDir.empty()) {
fromDir.push_back('/');
}
std::string toDir = files.ToDir;
if (!toDir.empty()) {
toDir.push_back('/');
}
Json::Value paths = Json::arrayValue;
for (size_t i = 0; i < files.From.size(); ++i) {
std::string const& fromPath = cmStrCat(fromDir, files.From[i]);
std::string const& toPath = cmStrCat(toDir, files.To[i]);
paths.append(this->DumpInstallerPath(this->TopBuild, fromPath, toPath));
}
installer["paths"] = std::move(paths);
if (installTarget->GetOptional()) {
installer["isOptional"] = true;
}
if (installTarget->IsImportLibrary()) {
installer["targetIsImportLibrary"] = true;
}
switch (files.NamelinkMode) {
case cmInstallTargetGenerator::NamelinkModeNone:
break;
case cmInstallTargetGenerator::NamelinkModeOnly:
installer["targetInstallNamelink"] = "only";
break;
case cmInstallTargetGenerator::NamelinkModeSkip:
installer["targetInstallNamelink"] = "skip";
break;
}
// FIXME: Parse FilePermissions to provide structured information.
// FIXME: Thread EXPORT name through from install() call.
} else if (auto* installFiles =
dynamic_cast<cmInstallFilesGenerator*>(gen)) {
std::vector<std::string> const& files =
installFiles->GetFiles(this->Config);
if (files.empty()) {
return installer;
}
installer["type"] = "file";
installer["destination"] = installFiles->GetDestination(this->Config);
Json::Value paths = Json::arrayValue;
std::string const& rename = installFiles->GetRename(this->Config);
if (!rename.empty() && files.size() == 1) {
paths.append(this->DumpInstallerPath(this->TopSource, files[0], rename));
} else {
for (std::string const& file : installFiles->GetFiles(this->Config)) {
paths.append(RelativeIfUnder(this->TopSource, file));
}
}
installer["paths"] = std::move(paths);
if (installFiles->GetOptional()) {
installer["isOptional"] = true;
}
// FIXME: Parse FilePermissions to provide structured information.
} else if (auto* installDir =
dynamic_cast<cmInstallDirectoryGenerator*>(gen)) {
std::vector<std::string> const& dirs =
installDir->GetDirectories(this->Config);
if (dirs.empty()) {
return installer;
}
installer["type"] = "directory";
installer["destination"] = installDir->GetDestination(this->Config);
Json::Value paths = Json::arrayValue;
for (std::string const& dir : dirs) {
if (cmHasLiteralSuffix(dir, "/")) {
paths.append(this->DumpInstallerPath(
this->TopSource, dir.substr(0, dir.size() - 1), "."));
} else {
paths.append(this->DumpInstallerPath(
this->TopSource, dir, cmSystemTools::GetFilenameName(dir)));
}
}
installer["paths"] = std::move(paths);
if (installDir->GetOptional()) {
installer["isOptional"] = true;
}
// FIXME: Parse FilePermissions, DirPermissions, and LiteralArguments.
// to provide structured information.
} else if (auto* installExport =
dynamic_cast<cmInstallExportGenerator*>(gen)) {
installer["type"] = "export";
installer["destination"] = installExport->GetDestination();
cmExportSet* exportSet = installExport->GetExportSet();
installer["exportName"] = exportSet->GetName();
installer["exportTargets"] = this->DumpInstallerExportTargets(exportSet);
Json::Value paths = Json::arrayValue;
paths.append(
RelativeIfUnder(this->TopBuild, installExport->GetMainImportFile()));
installer["paths"] = std::move(paths);
} else if (auto* installScript =
dynamic_cast<cmInstallScriptGenerator*>(gen)) {
if (installScript->IsCode()) {
installer["type"] = "code";
} else {
installer["type"] = "script";
installer["scriptFile"] = RelativeIfUnder(
this->TopSource, installScript->GetScript(this->Config));
}
}
// Add fields common to all install generators.
installer["component"] = gen->GetComponent();
if (gen->GetExcludeFromAll()) {
installer["isExcludeFromAll"] = true;
}
if (gen->GetAllComponentsFlag()) {
installer["isForAllComponents"] = true;
}
this->AddBacktrace(installer, gen->GetBacktrace());
return installer;
}
Json::Value DirectoryObject::DumpInstallerExportTargets(cmExportSet* exp)
{
Json::Value targets = Json::arrayValue;
for (auto const& targetExport : exp->GetTargetExports()) {
Json::Value target = Json::objectValue;
target["id"] = TargetId(targetExport->Target, this->TopBuild);
target["index"] = this->TargetIndexMap[targetExport->Target];
targets.append(std::move(target)); // NOLINT(*)
}
return targets;
}
Json::Value DirectoryObject::DumpInstallerPath(std::string const& top,
std::string const& fromPathIn,
std::string const& toPath)
{
Json::Value installPath;
std::string fromPath = RelativeIfUnder(top, fromPathIn);
// If toPath is the last component of fromPath, use just fromPath.
if (toPath.find_first_of('/') == std::string::npos &&
cmHasSuffix(fromPath, toPath) &&
(fromPath.size() == toPath.size() ||
fromPath[fromPath.size() - toPath.size() - 1] == '/')) {
installPath = fromPath;
} else {
installPath = Json::objectValue;
installPath["from"] = fromPath;
installPath["to"] = toPath;
}
return installPath;
}
Target::Target(cmGeneratorTarget* gt, std::string const& config)
: GT(gt)
, Config(config)
+169 -18
View File
@@ -1246,9 +1246,12 @@ bool HandleRealPathCommand(std::vector<std::string> const& args,
struct Arguments
{
std::string BaseDirectory;
bool ExpandTilde = false;
};
static auto const parser = cmArgumentParser<Arguments>{}.Bind(
"BASE_DIRECTORY"_s, &Arguments::BaseDirectory);
static auto const parser =
cmArgumentParser<Arguments>{}
.Bind("BASE_DIRECTORY"_s, &Arguments::BaseDirectory)
.Bind("EXPAND_TILDE"_s, &Arguments::ExpandTilde);
std::vector<std::string> unparsedArguments;
std::vector<std::string> keywordsMissingValue;
@@ -1270,7 +1273,21 @@ bool HandleRealPathCommand(std::vector<std::string> const& args,
arguments.BaseDirectory = status.GetMakefile().GetCurrentSourceDirectory();
}
cmCMakePath path(args[1]);
auto input = args[1];
if (arguments.ExpandTilde && !input.empty()) {
if (input[0] == '~' && (input.length() == 1 || input[1] == '/')) {
std::string home;
if (
#if defined(_WIN32) && !defined(__CYGWIN__)
cmSystemTools::GetEnv("USERPROFILE", home) ||
#endif
cmSystemTools::GetEnv("HOME", home)) {
input.replace(0, 1, home);
}
}
}
cmCMakePath path(input, cmCMakePath::auto_format);
path = path.Absolute(arguments.BaseDirectory).Normal();
auto realPath = cmSystemTools::GetRealPath(path.GenericString());
@@ -1313,8 +1330,9 @@ bool HandleRelativePathCommand(std::vector<std::string> const& args,
bool HandleRename(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
if (args.size() != 3) {
status.SetError("RENAME given incorrect number of arguments.");
if (args.size() < 3) {
status.SetError("RENAME must be called with at least two additional "
"arguments");
return false;
}
@@ -1330,21 +1348,148 @@ bool HandleRename(std::vector<std::string> const& args,
cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', args[2]);
}
if (!cmSystemTools::RenameFile(oldname, newname)) {
std::string err = cmSystemTools::GetLastSystemError();
status.SetError(cmStrCat("RENAME failed to rename\n ", oldname,
"\nto\n ", newname, "\nbecause: ", err, "\n"));
struct Arguments
{
bool NoReplace = false;
std::string Result;
};
static auto const parser = cmArgumentParser<Arguments>{}
.Bind("NO_REPLACE"_s, &Arguments::NoReplace)
.Bind("RESULT"_s, &Arguments::Result);
std::vector<std::string> unconsumedArgs;
Arguments const arguments =
parser.Parse(cmMakeRange(args).advance(3), &unconsumedArgs);
if (!unconsumedArgs.empty()) {
status.SetError("RENAME unknown argument:\n " + unconsumedArgs.front());
return false;
}
return true;
std::string err;
switch (cmSystemTools::RenameFile(oldname, newname,
arguments.NoReplace
? cmSystemTools::Replace::No
: cmSystemTools::Replace::Yes,
&err)) {
case cmSystemTools::RenameResult::Success:
if (!arguments.Result.empty()) {
status.GetMakefile().AddDefinition(arguments.Result, "0");
}
return true;
case cmSystemTools::RenameResult::NoReplace:
if (!arguments.Result.empty()) {
err = "NO_REPLACE";
} else {
err = "path not replaced";
}
CM_FALLTHROUGH;
case cmSystemTools::RenameResult::Failure:
if (!arguments.Result.empty()) {
status.GetMakefile().AddDefinition(arguments.Result, err);
return true;
}
break;
}
status.SetError(cmStrCat("RENAME failed to rename\n ", oldname, "\nto\n ",
newname, "\nbecause: ", err, "\n"));
return false;
}
bool HandleCopyFile(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
if (args.size() < 3) {
status.SetError("COPY_FILE must be called with at least two additional "
"arguments");
return false;
}
// Compute full path for old and new names.
std::string oldname = args[1];
if (!cmsys::SystemTools::FileIsFullPath(oldname)) {
oldname =
cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', args[1]);
}
std::string newname = args[2];
if (!cmsys::SystemTools::FileIsFullPath(newname)) {
newname =
cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', args[2]);
}
struct Arguments
{
bool OnlyIfDifferent = false;
std::string Result;
};
static auto const parser =
cmArgumentParser<Arguments>{}
.Bind("ONLY_IF_DIFFERENT"_s, &Arguments::OnlyIfDifferent)
.Bind("RESULT"_s, &Arguments::Result);
std::vector<std::string> unconsumedArgs;
Arguments const arguments =
parser.Parse(cmMakeRange(args).advance(3), &unconsumedArgs);
if (!unconsumedArgs.empty()) {
status.SetError("COPY_FILE unknown argument:\n " +
unconsumedArgs.front());
return false;
}
bool result = true;
if (cmsys::SystemTools::FileIsDirectory(oldname)) {
if (!arguments.Result.empty()) {
status.GetMakefile().AddDefinition(arguments.Result,
"cannot copy a directory");
} else {
status.SetError(
cmStrCat("COPY_FILE cannot copy a directory\n ", oldname));
result = false;
}
return result;
}
if (cmsys::SystemTools::FileIsDirectory(newname)) {
if (!arguments.Result.empty()) {
status.GetMakefile().AddDefinition(arguments.Result,
"cannot copy to a directory");
} else {
status.SetError(
cmStrCat("COPY_FILE cannot copy to a directory\n ", newname));
result = false;
}
return result;
}
cmSystemTools::CopyWhen when;
if (arguments.OnlyIfDifferent) {
when = cmSystemTools::CopyWhen::OnlyIfDifferent;
} else {
when = cmSystemTools::CopyWhen::Always;
}
std::string err;
if (cmSystemTools::CopySingleFile(oldname, newname, when, &err) ==
cmSystemTools::CopyResult::Success) {
if (!arguments.Result.empty()) {
status.GetMakefile().AddDefinition(arguments.Result, "0");
}
} else {
if (!arguments.Result.empty()) {
status.GetMakefile().AddDefinition(arguments.Result, err);
} else {
status.SetError(cmStrCat("COPY_FILE failed to copy\n ", oldname,
"\nto\n ", newname, "\nbecause: ", err, "\n"));
result = false;
}
}
return result;
}
bool HandleRemoveImpl(std::vector<std::string> const& args, bool recurse,
cmExecutionStatus& status)
{
std::string message;
for (std::string const& arg :
cmMakeRange(args).advance(1)) // Get rid of subcommand
{
@@ -2818,16 +2963,21 @@ bool HandleCreateLinkCommand(std::vector<std::string> const& args,
// Check if the command requires a symbolic link.
if (arguments.Symbolic) {
completed = cmSystemTools::CreateSymlink(fileName, newFileName, &result);
completed = static_cast<bool>(
cmSystemTools::CreateSymlink(fileName, newFileName, &result));
} else {
completed = cmSystemTools::CreateLink(fileName, newFileName, &result);
completed = static_cast<bool>(
cmSystemTools::CreateLink(fileName, newFileName, &result));
}
// Check if copy-on-error is enabled in the arguments.
if (!completed && arguments.CopyOnError) {
completed = cmsys::SystemTools::CopyFileAlways(fileName, newFileName);
if (!completed) {
result = "Copy failed: " + cmSystemTools::GetLastSystemError();
cmsys::Status copied =
cmsys::SystemTools::CopyFileAlways(fileName, newFileName);
if (copied) {
completed = true;
} else {
result = "Copy failed: " + copied.GetString();
}
}
@@ -3569,6 +3719,7 @@ bool cmFileCommand(std::vector<std::string> const& args,
{ "GLOB_RECURSE"_s, HandleGlobRecurseCommand },
{ "MAKE_DIRECTORY"_s, HandleMakeDirectoryCommand },
{ "RENAME"_s, HandleRename },
{ "COPY_FILE"_s, HandleCopyFile },
{ "REMOVE"_s, HandleRemove },
{ "REMOVE_RECURSE"_s, HandleRemoveRecurse },
{ "COPY"_s, HandleCopyCommand },
+93 -9
View File
@@ -9,7 +9,10 @@
#include <cmext/algorithm>
#include "cmCMakePath.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
#include "cmProperty.h"
#include "cmRange.h"
#include "cmSearchPath.h"
@@ -17,11 +20,13 @@
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmake.h"
class cmExecutionStatus;
cmFindBase::cmFindBase(cmExecutionStatus& status)
cmFindBase::cmFindBase(std::string findCommandName, cmExecutionStatus& status)
: cmFindCommon(status)
, FindCommandName(std::move(findCommandName))
{
}
@@ -299,27 +304,106 @@ bool cmFindBase::CheckForVariableInCache()
cmProp cacheEntry = state->GetCacheEntryValue(this->VariableName);
bool found = !cmIsNOTFOUND(*cacheValue);
bool cached = cacheEntry != nullptr;
auto cacheType = cached ? state->GetCacheEntryType(this->VariableName)
: cmStateEnums::UNINITIALIZED;
if (cached && cacheType != cmStateEnums::UNINITIALIZED) {
this->VariableType = cacheType;
if (const auto* hs =
state->GetCacheEntryProperty(this->VariableName, "HELPSTRING")) {
this->VariableDocumentation = *hs;
}
}
if (found) {
// If the user specifies the entry on the command line without a
// type we should add the type and docstring but keep the
// original value. Tell the subclass implementations to do
// this.
if (cached &&
state->GetCacheEntryType(this->VariableName) ==
cmStateEnums::UNINITIALIZED) {
if (cached && cacheType == cmStateEnums::UNINITIALIZED) {
this->AlreadyInCacheWithoutMetaInfo = true;
}
return true;
}
if (cached) {
cmProp hs =
state->GetCacheEntryProperty(this->VariableName, "HELPSTRING");
this->VariableDocumentation = hs ? *hs : "(none)";
}
}
return false;
}
void cmFindBase::NormalizeFindResult()
{
if (this->Makefile->GetPolicyStatus(cmPolicies::CMP0125) ==
cmPolicies::NEW) {
// ensure the path returned by find_* command is absolute
const auto* existingValue =
this->Makefile->GetDefinition(this->VariableName);
std::string value;
if (!existingValue->empty()) {
value =
cmCMakePath(*existingValue, cmCMakePath::auto_format)
.Absolute(cmCMakePath(
this->Makefile->GetCMakeInstance()->GetCMakeWorkingDirectory()))
.Normal()
.GenericString();
// value = cmSystemTools::CollapseFullPath(*existingValue);
if (!cmSystemTools::FileExists(value, false)) {
value = *existingValue;
}
}
// If the user specifies the entry on the command line without a
// type we should add the type and docstring but keep the original
// value.
if (value != *existingValue || this->AlreadyInCacheWithoutMetaInfo) {
this->Makefile->GetCMakeInstance()->AddCacheEntry(
this->VariableName, value.c_str(), this->VariableDocumentation.c_str(),
this->VariableType);
// if there was a definition then remove it
// This is required to ensure same behavior as
// cmMakefile::AddCacheDefinition.
// See #22038 for problems raised by this behavior.
this->Makefile->RemoveDefinition(this->VariableName);
}
} else {
// If the user specifies the entry on the command line without a
// type we should add the type and docstring but keep the original
// value.
if (this->AlreadyInCacheWithoutMetaInfo) {
this->Makefile->AddCacheDefinition(this->VariableName, "",
this->VariableDocumentation.c_str(),
this->VariableType);
}
}
}
void cmFindBase::StoreFindResult(const std::string& value)
{
bool force =
this->Makefile->GetPolicyStatus(cmPolicies::CMP0125) == cmPolicies::NEW;
if (!value.empty()) {
this->Makefile->AddCacheDefinition(this->VariableName, value,
this->VariableDocumentation.c_str(),
this->VariableType, force);
return;
}
this->Makefile->AddCacheDefinition(
this->VariableName, cmStrCat(this->VariableName, "-NOTFOUND"),
this->VariableDocumentation.c_str(), this->VariableType, force);
if (this->Required) {
this->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
cmStrCat("Could not find ", this->VariableName, " using the following ",
(this->FindCommandName == "find_file" ||
this->FindCommandName == "find_path"
? "files"
: "names"),
": ", cmJoin(this->Names, ", ")));
cmSystemTools::SetFatalErrorOccured();
}
}
cmFindBaseDebugState::cmFindBaseDebugState(std::string commandName,
cmFindBase const* findBase)
: FindCommand(findBase)
+9 -1
View File
@@ -9,6 +9,7 @@
#include <vector>
#include "cmFindCommon.h"
#include "cmStateTypes.h"
class cmExecutionStatus;
@@ -21,7 +22,7 @@ class cmExecutionStatus;
class cmFindBase : public cmFindCommon
{
public:
cmFindBase(cmExecutionStatus& status);
cmFindBase(std::string findCommandName, cmExecutionStatus& status);
virtual ~cmFindBase() = default;
/**
@@ -39,8 +40,15 @@ protected:
// if it has documentation in the cache
bool CheckForVariableInCache();
void NormalizeFindResult();
void StoreFindResult(const std::string& value);
// actual find command name
std::string FindCommandName;
// use by command during find
std::string VariableDocumentation;
cmStateEnums::CacheEntryType VariableType = cmStateEnums::UNINITIALIZED;
std::string VariableName;
std::vector<std::string> Names;
bool NamesPerDir = false;
+4 -1
View File
@@ -2,12 +2,15 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmFindFileCommand.h"
#include "cmStateTypes.h"
class cmExecutionStatus;
cmFindFileCommand::cmFindFileCommand(cmExecutionStatus& status)
: cmFindPathCommand(status)
: cmFindPathCommand("find_file", status)
{
this->IncludeFileInPath = true;
this->VariableType = cmStateEnums::FILEPATH;
}
bool cmFindFile(std::vector<std::string> const& args,
+14 -35
View File
@@ -12,7 +12,6 @@
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmProperty.h"
#include "cmState.h"
#include "cmStateTypes.h"
@@ -22,30 +21,26 @@
class cmExecutionStatus;
cmFindLibraryCommand::cmFindLibraryCommand(cmExecutionStatus& status)
: cmFindBase(status)
: cmFindBase("find_library", status)
{
this->EnvironmentPath = "LIB";
this->NamesPerDirAllowed = true;
this->VariableDocumentation = "Path to a library.";
this->VariableType = cmStateEnums::FILEPATH;
}
// cmFindLibraryCommand
bool cmFindLibraryCommand::InitialPass(std::vector<std::string> const& argsIn)
{
this->DebugMode = this->ComputeIfDebugModeWanted();
this->VariableDocumentation = "Path to a library.";
this->CMakePathName = "LIBRARY";
if (!this->ParseArguments(argsIn)) {
return false;
}
if (this->AlreadyInCache) {
// If the user specifies the entry on the command line without a
// type we should add the type and docstring but keep the original
// value.
if (this->AlreadyInCacheWithoutMetaInfo) {
this->Makefile->AddCacheDefinition(this->VariableName, "",
this->VariableDocumentation.c_str(),
cmStateEnums::FILEPATH);
}
this->NormalizeFindResult();
return true;
}
@@ -75,24 +70,7 @@ 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,
this->VariableDocumentation.c_str(),
cmStateEnums::FILEPATH);
return true;
}
std::string notfound = this->VariableName + "-NOTFOUND";
this->Makefile->AddCacheDefinition(this->VariableName, notfound,
this->VariableDocumentation.c_str(),
cmStateEnums::FILEPATH);
if (this->Required) {
this->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
"Could not find " + this->VariableName +
" using the following names: " + cmJoin(this->Names, ", "));
cmSystemTools::SetFatalErrorOccured();
}
this->StoreFindResult(library);
return true;
}
@@ -208,7 +186,8 @@ std::string cmFindLibraryCommand::FindLibrary()
struct cmFindLibraryHelper
{
cmFindLibraryHelper(cmMakefile* mf, cmFindBase const* findBase);
cmFindLibraryHelper(std::string debugName, cmMakefile* mf,
cmFindBase const* findBase);
// Context information.
cmMakefile* Makefile;
@@ -280,11 +259,11 @@ struct cmFindLibraryHelper
};
};
cmFindLibraryHelper::cmFindLibraryHelper(cmMakefile* mf,
cmFindLibraryHelper::cmFindLibraryHelper(std::string debugName, cmMakefile* mf,
cmFindBase const* base)
: Makefile(mf)
, DebugMode(base->DebugModeEnabled())
, DebugSearches("find_library", base)
, DebugSearches(std::move(debugName), base)
{
this->GG = this->Makefile->GetGlobalGenerator();
@@ -374,7 +353,7 @@ void cmFindLibraryHelper::AddName(std::string const& name)
regex += "(\\.[0-9]+\\.[0-9]+)?";
}
regex += "$";
entry.Regex.compile(regex.c_str());
entry.Regex.compile(regex);
this->Names.push_back(std::move(entry));
}
@@ -485,7 +464,7 @@ std::string cmFindLibraryCommand::FindNormalLibrary()
std::string cmFindLibraryCommand::FindNormalLibraryNamesPerDir()
{
// Search for all names in each directory.
cmFindLibraryHelper helper(this->Makefile, this);
cmFindLibraryHelper helper(this->FindCommandName, this->Makefile, this);
for (std::string const& n : this->Names) {
helper.AddName(n);
}
@@ -502,7 +481,7 @@ std::string cmFindLibraryCommand::FindNormalLibraryNamesPerDir()
std::string cmFindLibraryCommand::FindNormalLibraryDirsPerName()
{
// Search the entire path for each name.
cmFindLibraryHelper helper(this->Makefile, this);
cmFindLibraryHelper helper(this->FindCommandName, this->Makefile, this);
for (std::string const& n : this->Names) {
// Switch to searching for this name.
helper.SetName(n);
+16 -33
View File
@@ -2,70 +2,53 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmFindPathCommand.h"
#include <utility>
#include "cmsys/Glob.hxx"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
class cmExecutionStatus;
cmFindPathCommand::cmFindPathCommand(cmExecutionStatus& status)
: cmFindBase(status)
cmFindPathCommand::cmFindPathCommand(std::string findCommandName,
cmExecutionStatus& status)
: cmFindBase(std::move(findCommandName), status)
{
this->EnvironmentPath = "INCLUDE";
this->IncludeFileInPath = false;
this->VariableDocumentation = "Path to a file.";
this->VariableType = cmStateEnums::PATH;
}
cmFindPathCommand::cmFindPathCommand(cmExecutionStatus& status)
: cmFindPathCommand("find_path", status)
{
}
// cmFindPathCommand
bool cmFindPathCommand::InitialPass(std::vector<std::string> const& argsIn)
{
this->DebugMode = this->ComputeIfDebugModeWanted();
this->VariableDocumentation = "Path to a file.";
this->CMakePathName = "INCLUDE";
if (!this->ParseArguments(argsIn)) {
return false;
}
if (this->AlreadyInCache) {
// If the user specifies the entry on the command line without a
// type we should add the type and docstring but keep the original
// value.
if (this->AlreadyInCacheWithoutMetaInfo) {
this->Makefile->AddCacheDefinition(
this->VariableName, "", this->VariableDocumentation.c_str(),
(this->IncludeFileInPath ? cmStateEnums::FILEPATH
: cmStateEnums::PATH));
}
this->NormalizeFindResult();
return true;
}
std::string result = this->FindHeader();
if (!result.empty()) {
this->Makefile->AddCacheDefinition(
this->VariableName, result, this->VariableDocumentation.c_str(),
(this->IncludeFileInPath) ? cmStateEnums::FILEPATH : cmStateEnums::PATH);
return true;
}
this->Makefile->AddCacheDefinition(
this->VariableName, this->VariableName + "-NOTFOUND",
this->VariableDocumentation.c_str(),
(this->IncludeFileInPath) ? cmStateEnums::FILEPATH : cmStateEnums::PATH);
if (this->Required) {
this->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
"Could not find " + this->VariableName +
" using the following files: " + cmJoin(this->Names, ", "));
cmSystemTools::SetFatalErrorOccured();
}
this->StoreFindResult(result);
return true;
}
std::string cmFindPathCommand::FindHeader()
{
std::string debug_name = this->IncludeFileInPath ? "find_file" : "find_path";
cmFindBaseDebugState debug(debug_name, this);
cmFindBaseDebugState debug(this->FindCommandName, this);
std::string header;
if (this->SearchFrameworkFirst || this->SearchFrameworkOnly) {
header = this->FindFrameworkHeader(debug);
+1
View File
@@ -22,6 +22,7 @@ class cmFindPathCommand : public cmFindBase
{
public:
cmFindPathCommand(cmExecutionStatus& status);
cmFindPathCommand(std::string findCommandName, cmExecutionStatus& status);
bool InitialPass(std::vector<std::string> const& args);
+13 -32
View File
@@ -4,6 +4,7 @@
#include <algorithm>
#include <string>
#include <utility>
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -20,8 +21,9 @@ class cmExecutionStatus;
struct cmFindProgramHelper
{
cmFindProgramHelper(cmMakefile* makefile, cmFindBase const* base)
: DebugSearches("find_program", base)
cmFindProgramHelper(std::string debugName, cmMakefile* makefile,
cmFindBase const* base)
: DebugSearches(std::move(debugName), base)
, Makefile(makefile)
, PolicyCMP0109(makefile->GetPolicyStatus(cmPolicies::CMP0109))
{
@@ -145,52 +147,31 @@ struct cmFindProgramHelper
};
cmFindProgramCommand::cmFindProgramCommand(cmExecutionStatus& status)
: cmFindBase(status)
: cmFindBase("find_program", status)
{
this->NamesPerDirAllowed = true;
this->VariableDocumentation = "Path to a program.";
this->VariableType = cmStateEnums::FILEPATH;
}
// cmFindProgramCommand
bool cmFindProgramCommand::InitialPass(std::vector<std::string> const& argsIn)
{
this->DebugMode = this->ComputeIfDebugModeWanted();
this->VariableDocumentation = "Path to a program.";
this->CMakePathName = "PROGRAM";
// call cmFindBase::ParseArguments
if (!this->ParseArguments(argsIn)) {
return false;
}
if (this->AlreadyInCache) {
// If the user specifies the entry on the command line without a
// type we should add the type and docstring but keep the original
// value.
if (this->AlreadyInCacheWithoutMetaInfo) {
this->Makefile->AddCacheDefinition(this->VariableName, "",
this->VariableDocumentation.c_str(),
cmStateEnums::FILEPATH);
}
this->NormalizeFindResult();
return true;
}
std::string const result = this->FindProgram();
if (!result.empty()) {
// Save the value in the cache
this->Makefile->AddCacheDefinition(this->VariableName, result,
this->VariableDocumentation.c_str(),
cmStateEnums::FILEPATH);
return true;
}
this->Makefile->AddCacheDefinition(
this->VariableName, this->VariableName + "-NOTFOUND",
this->VariableDocumentation.c_str(), cmStateEnums::FILEPATH);
if (this->Required) {
this->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
"Could not find " + this->VariableName +
" using the following names: " + cmJoin(this->Names, ", "));
cmSystemTools::SetFatalErrorOccured();
}
this->StoreFindResult(result);
return true;
}
@@ -222,7 +203,7 @@ std::string cmFindProgramCommand::FindNormalProgram()
std::string cmFindProgramCommand::FindNormalProgramNamesPerDir()
{
// Search for all names in each directory.
cmFindProgramHelper helper(this->Makefile, this);
cmFindProgramHelper helper(this->FindCommandName, this->Makefile, this);
for (std::string const& n : this->Names) {
helper.AddName(n);
}
@@ -245,7 +226,7 @@ std::string cmFindProgramCommand::FindNormalProgramNamesPerDir()
std::string cmFindProgramCommand::FindNormalProgramDirsPerName()
{
// Search the entire path for each name.
cmFindProgramHelper helper(this->Makefile, this);
cmFindProgramHelper helper(this->FindCommandName, this->Makefile, this);
for (std::string const& n : this->Names) {
// Switch to searching for this name.
helper.SetName(n);
+27 -10
View File
@@ -17,6 +17,7 @@
#include <utility>
#include <cm/memory>
#include <cm/optional>
#include <cm/string_view>
#include <cmext/string_view>
@@ -25,7 +26,7 @@
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmProperty.h"
#include "cmPolicies.h"
#include "cmRange.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -113,9 +114,11 @@ bool cmForEachFunctionBlocker::ReplayItems(
// At end of for each execute recorded commands
// store the old value
std::string oldDef;
if (cmProp d = mf.GetDefinition(this->Args.front())) {
oldDef = *d;
cm::optional<std::string> oldDef;
if (mf.GetPolicyStatus(cmPolicies::CMP0124) != cmPolicies::NEW) {
oldDef = mf.GetSafeDefinition(this->Args.front());
} else if (mf.IsNormalDefinitionSet(this->Args.front())) {
oldDef = *mf.GetDefinition(this->Args.front());
}
auto restore = false;
@@ -131,9 +134,14 @@ bool cmForEachFunctionBlocker::ReplayItems(
}
if (restore) {
// restore the variable to its prior value
mf.AddDefinition(this->Args.front(), oldDef);
if (oldDef) {
// restore the variable to its prior value
mf.AddDefinition(this->Args.front(), *oldDef);
} else {
mf.RemoveDefinition(this->Args.front());
}
}
return true;
}
@@ -185,10 +193,15 @@ bool cmForEachFunctionBlocker::ReplayZipLists(
assert("Sanity check" && iterationVars.size() == values.size());
// Store old values for iteration variables
std::map<std::string, std::string> oldDefs;
std::map<std::string, cm::optional<std::string>> oldDefs;
for (auto i = 0u; i < values.size(); ++i) {
if (cmProp d = mf.GetDefinition(iterationVars[i])) {
oldDefs.emplace(iterationVars[i], *d);
const auto& varName = iterationVars[i];
if (mf.GetPolicyStatus(cmPolicies::CMP0124) != cmPolicies::NEW) {
oldDefs.emplace(varName, mf.GetSafeDefinition(varName));
} else if (mf.IsNormalDefinitionSet(varName)) {
oldDefs.emplace(varName, *mf.GetDefinition(varName));
} else {
oldDefs.emplace(varName, cm::nullopt);
}
}
@@ -226,7 +239,11 @@ bool cmForEachFunctionBlocker::ReplayZipLists(
// Restore the variables to its prior value
if (restore) {
for (auto const& p : oldDefs) {
mf.AddDefinition(p.first, p.second);
if (p.second) {
mf.AddDefinition(p.first, *p.second);
} else {
mf.RemoveDefinition(p.first);
}
}
}
return true;
+5
View File
@@ -42,6 +42,11 @@ cmGeneratedFileStream::cmGeneratedFileStream(std::string const& name,
#else
static_cast<void>(encoding);
#endif
if (encoding == codecvt::UTF8_WITH_BOM) {
// Write the BOM encoding header into the file
char magic[] = { char(0xEF), char(0xBB), char(0xBF) };
this->write(magic, 3);
}
}
cmGeneratedFileStream::~cmGeneratedFileStream()
+53 -2
View File
@@ -14,6 +14,7 @@
#include <utility>
#include <cm/iterator>
#include <cm/optional>
#include <cm/string_view>
#include <cm/vector>
#include <cmext/algorithm>
@@ -23,6 +24,7 @@
#include "cmsys/String.h"
#include "cmAlgorithms.h"
#include "cmComputeLinkInformation.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorExpressionContext.h"
#include "cmGeneratorExpressionDAGChecker.h"
@@ -1627,8 +1629,8 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode
type != cmStateEnums::OBJECT_LIBRARY) {
std::ostringstream e;
e << "Objects of target \"" << tgtName
<< "\" referenced but is not an allowed library types (EXECUTABLE, "
<< "STATIC, SHARED, MODULE, OBJECT).";
<< "\" referenced but is not one of the allowed target types "
<< "(EXECUTABLE, STATIC, SHARED, MODULE, OBJECT).";
reportError(context, content->GetOriginalExpression(), e.str());
return std::string();
}
@@ -1687,6 +1689,54 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode
}
} targetObjectsNode;
static const struct TargetRuntimeDllsNode : public cmGeneratorExpressionNode
{
TargetRuntimeDllsNode() {} // NOLINT(modernize-use-equals-default)
std::string Evaluate(
const std::vector<std::string>& parameters,
cmGeneratorExpressionContext* context,
const GeneratorExpressionContent* content,
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
{
std::string tgtName = parameters.front();
cmGeneratorTarget* gt = context->LG->FindGeneratorTargetToUse(tgtName);
if (!gt) {
std::ostringstream e;
e << "Objects of target \"" << tgtName
<< "\" referenced but no such target exists.";
reportError(context, content->GetOriginalExpression(), e.str());
return std::string();
}
cmStateEnums::TargetType type = gt->GetType();
if (type != cmStateEnums::EXECUTABLE &&
type != cmStateEnums::SHARED_LIBRARY &&
type != cmStateEnums::MODULE_LIBRARY) {
std::ostringstream e;
e << "Objects of target \"" << tgtName
<< "\" referenced but is not one of the allowed target types "
<< "(EXECUTABLE, SHARED, MODULE).";
reportError(context, content->GetOriginalExpression(), e.str());
return std::string();
}
if (auto* cli = gt->GetLinkInformation(context->Config)) {
std::vector<std::string> dllPaths;
auto const& dlls = cli->GetRuntimeDLLs();
for (auto const& dll : dlls) {
if (auto loc = dll->MaybeGetLocation(context->Config)) {
dllPaths.emplace_back(*loc);
}
}
return cmJoin(dllPaths, ";");
}
return "";
}
} targetRuntimeDllsNode;
static const struct CompileFeaturesNode : public cmGeneratorExpressionNode
{
CompileFeaturesNode() {} // NOLINT(modernize-use-equals-default)
@@ -2603,6 +2653,7 @@ const cmGeneratorExpressionNode* cmGeneratorExpressionNode::GetNode(
{ "TARGET_EXISTS", &targetExistsNode },
{ "TARGET_NAME_IF_EXISTS", &targetNameIfExistsNode },
{ "TARGET_GENEX_EVAL", &targetGenexEvalNode },
{ "TARGET_RUNTIME_DLLS", &targetRuntimeDllsNode },
{ "GENEX_EVAL", &genexEvalNode },
{ "BUILD_INTERFACE", &buildInterfaceNode },
{ "INSTALL_INTERFACE", &installInterfaceNode },
+45 -9
View File
@@ -52,6 +52,11 @@
class cmMessenger;
namespace {
const cmsys::RegularExpression FrameworkRegularExpression(
"^(.*/)?([^/]*)\\.framework/(.*)$");
}
template <>
cmProp cmTargetPropertyComputer::GetSources<cmGeneratorTarget>(
cmGeneratorTarget const* tgt, cmMessenger* /* messenger */,
@@ -970,7 +975,7 @@ cmProp cmGeneratorTarget::GetPropertyWithPairedLanguageSupport(
std::string const& lang, const char* suffix) const
{
cmProp propertyValue = this->Target->GetProperty(cmStrCat(lang, suffix));
if (propertyValue == nullptr) {
if (!propertyValue) {
// Check if we should use the value set by another language.
if (lang == "OBJC") {
propertyValue = this->GetPropertyWithPairedLanguageSupport("C", suffix);
@@ -1062,6 +1067,20 @@ const std::string& cmGeneratorTarget::GetLocation(
return location;
}
cm::optional<std::string> cmGeneratorTarget::MaybeGetLocation(
std::string const& config) const
{
cm::optional<std::string> location;
if (cmGeneratorTarget::ImportInfo const* imp = this->GetImportInfo(config)) {
if (!imp->Location.empty()) {
location = imp->Location;
}
} else {
location = this->GetFullPath(config, cmStateEnums::RuntimeBinaryArtifact);
}
return location;
}
std::vector<cmCustomCommand> const& cmGeneratorTarget::GetPreBuildCommands()
const
{
@@ -2243,8 +2262,16 @@ std::string cmGeneratorTarget::GetSOName(const std::string& config) const
return cmSystemTools::GetFilenameName(info->Location);
}
// Use the soname given if any.
if (this->IsFrameworkOnApple()) {
cmsys::RegularExpressionMatch match;
if (FrameworkRegularExpression.find(info->SOName.c_str(), match)) {
auto frameworkName = match.match(2);
auto fileName = match.match(3);
return cmStrCat(frameworkName, ".framework/", fileName);
}
}
if (cmHasLiteralPrefix(info->SOName, "@rpath/")) {
return info->SOName.substr(6);
return info->SOName.substr(cmStrLen("@rpath/"));
}
return info->SOName;
}
@@ -4701,21 +4728,20 @@ bool cmGeneratorTarget::ComputeCompileFeatures(
cmStrCat(cmSystemTools::UpperCase(config), '-', language.first);
BTs<std::string> const* standardToCopy =
this->GetLanguageStandardProperty(language.second, config);
if (standardToCopy != nullptr) {
if (standardToCopy) {
this->LanguageStandardMap[key] = *standardToCopy;
generatorTargetLanguageStandard = &this->LanguageStandardMap[key];
} else {
cmProp defaultStandard = this->Makefile->GetDefinition(
cmStrCat("CMAKE_", language.second, "_STANDARD_DEFAULT"));
if (defaultStandard != nullptr) {
if (defaultStandard) {
this->LanguageStandardMap[key] = BTs<std::string>(*defaultStandard);
generatorTargetLanguageStandard = &this->LanguageStandardMap[key];
}
}
// Custom updates for the CUDA standard.
if (generatorTargetLanguageStandard != nullptr &&
language.first == "CUDA") {
if (generatorTargetLanguageStandard && language.first == "CUDA") {
if (generatorTargetLanguageStandard->Value == "98") {
this->LanguageStandardMap[key].Value = "03";
}
@@ -6446,9 +6472,19 @@ std::string cmGeneratorTarget::GetDirectory(
const std::string& config, cmStateEnums::ArtifactType artifact) const
{
if (this->IsImported()) {
auto fullPath = this->Target->ImportedGetFullPath(config, artifact);
if (this->IsFrameworkOnApple()) {
cmsys::RegularExpressionMatch match;
if (FrameworkRegularExpression.find(fullPath.c_str(), match)) {
auto path = match.match(1);
if (!path.empty()) {
path.erase(path.length() - 1);
}
return path;
}
}
// Return the directory from which the target is imported.
return cmSystemTools::GetFilenamePath(
this->Target->ImportedGetFullPath(config, artifact));
return cmSystemTools::GetFilenamePath(fullPath);
}
if (OutputInfo const* info = this->GetOutputInfo(config)) {
// Return the directory in which the target will be built.
@@ -6757,7 +6793,7 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
return;
}
iface.Exists = true;
iface.Explicit = cmp0022NEW || explicitLibraries != nullptr;
iface.Explicit = cmp0022NEW || explicitLibraries;
if (explicitLibraries) {
// The interface libraries have been explicitly set.
+5
View File
@@ -14,6 +14,8 @@
#include <utility>
#include <vector>
#include <cm/optional>
#include "cmLinkItem.h"
#include "cmListFileCache.h"
#include "cmPolicies.h"
@@ -50,6 +52,9 @@ public:
bool CanCompileSources() const;
const std::string& GetLocation(const std::string& config) const;
/** Get the full path to the target's main artifact, if known. */
cm::optional<std::string> MaybeGetLocation(std::string const& config) const;
std::vector<cmCustomCommand> const& GetPreBuildCommands() const;
std::vector<cmCustomCommand> const& GetPreLinkCommands() const;
std::vector<cmCustomCommand> const& GetPostBuildCommands() const;
+3 -7
View File
@@ -159,13 +159,11 @@ void cmGhsMultiTargetGenerator::WriteTargetSpecifics(std::ostream& fout,
const std::string& config)
{
std::string outpath;
std::string rootpath = this->LocalGenerator->GetCurrentBinaryDirectory();
if (this->TagType != GhsMultiGpj::SUBPROJECT) {
// set target binary file destination
outpath = this->GeneratorTarget->GetDirectory(config);
outpath =
this->LocalGenerator->MaybeConvertToRelativePath(rootpath, outpath);
outpath = this->LocalGenerator->MaybeRelativeToCurBinDir(outpath);
/* clang-format off */
fout << " :binDirRelative=\"" << outpath << "\"\n"
" -o \"" << this->TargetNameReal << "\"\n";
@@ -369,7 +367,6 @@ void cmGhsMultiTargetGenerator::WriteCustomCommandsHelper(
// if the command specified a working directory use it.
std::string dir = this->LocalGenerator->GetCurrentBinaryDirectory();
std::string currentBinDir = dir;
std::string workingDir = ccg.GetWorkingDirectory();
if (!workingDir.empty()) {
dir = workingDir;
@@ -427,8 +424,7 @@ void cmGhsMultiTargetGenerator::WriteCustomCommandsHelper(
// working directory will be the start-output directory.
bool had_slash = cmd.find('/') != std::string::npos;
if (workingDir.empty()) {
cmd =
this->LocalGenerator->MaybeConvertToRelativePath(currentBinDir, cmd);
cmd = this->LocalGenerator->MaybeRelativeToCurBinDir(cmd);
}
bool has_slash = cmd.find('/') != std::string::npos;
if (had_slash && !has_slash) {
@@ -710,7 +706,7 @@ void cmGhsMultiTargetGenerator::WriteObjectLangOverride(
std::ostream& fout, const cmSourceFile* sourceFile)
{
cmProp rawLangProp = sourceFile->GetProperty("LANGUAGE");
if (nullptr != rawLangProp) {
if (rawLangProp) {
std::string sourceLangProp(*rawLangProp);
std::string const& extension = sourceFile->GetExtension();
if ("CXX" == sourceLangProp && ("c" == extension || "C" == extension)) {
+1 -1
View File
@@ -30,7 +30,7 @@ cmGlobalBorlandMakefileGenerator::cmGlobalBorlandMakefileGenerator(cmake* cm)
/*
* Borland Make does not support long line depend rule, as we have tested
* generate one source file includes 40000 header files, and generate
* depend.make in one line(use line continued tag), and error occured:
* depend.make in one line(use line continued tag), and error occurred:
* ** Fatal CMakeFiles\main.dir\depend.make 1224: Rule line too long **
* we disable long line dependencies rule generation for Borland make
*/
+9 -6
View File
@@ -2077,7 +2077,7 @@ bool cmGlobalGenerator::Open(const std::string& bindir,
std::string cmGlobalGenerator::GenerateCMakeBuildCommand(
const std::string& target, const std::string& config,
const std::string& native, bool ignoreErrors)
const std::string& parallel, const std::string& native, bool ignoreErrors)
{
std::string makeCommand = cmSystemTools::GetCMakeCommand();
makeCommand =
@@ -2087,6 +2087,11 @@ std::string cmGlobalGenerator::GenerateCMakeBuildCommand(
makeCommand += config;
makeCommand += "\"";
}
if (!parallel.empty()) {
makeCommand += " --parallel \"";
makeCommand += parallel;
makeCommand += "\"";
}
if (!target.empty()) {
makeCommand += " --target \"";
makeCommand += target;
@@ -2255,7 +2260,7 @@ bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root,
// Check whether the genex expansion of the property agrees in all
// configurations.
if (trueCount && falseCount) {
if (trueCount > 0 && falseCount > 0) {
std::ostringstream e;
e << "The EXCLUDE_FROM_ALL property of target \"" << target->GetName()
<< "\" varies by configuration. This is not supported by the \""
@@ -3022,10 +3027,8 @@ void cmGlobalGenerator::AddRuleHash(const std::vector<std::string>& outputs,
}
// Shorten the output name (in expected use case).
cmStateDirectory cmDir =
this->GetMakefiles()[0]->GetStateSnapshot().GetDirectory();
std::string fname = cmDir.ConvertToRelPathIfNotContained(
this->GetMakefiles()[0]->GetState()->GetBinaryDirectory(), outputs[0]);
std::string fname =
this->LocalGenerators[0]->MaybeRelativeToTopBinDir(outputs[0]);
// Associate the hash with this output.
this->RuleHashes[fname] = hash;
+5 -1
View File
@@ -249,9 +249,13 @@ public:
virtual void PrintBuildCommandAdvice(std::ostream& os, int jobs) const;
/** Generate a "cmake --build" call for a given target and config. */
/**
* Generate a "cmake --build" call for a given target, config and parallel
* level.
*/
std::string GenerateCMakeBuildCommand(const std::string& target,
const std::string& config,
const std::string& parallel,
const std::string& native,
bool ignoreErrors);
+4 -4
View File
@@ -375,7 +375,7 @@ void cmGlobalGhsMultiGenerator::WriteSubProjects(std::ostream& fout,
}
void cmGlobalGhsMultiGenerator::WriteProjectLine(
std::ostream& fout, cmGeneratorTarget const* target, cmLocalGenerator* root,
std::ostream& fout, cmGeneratorTarget const* target,
std::string& rootBinaryDir)
{
cmProp projName = target->GetProperty("GENERATOR_FILE_NAME");
@@ -383,7 +383,7 @@ void cmGlobalGhsMultiGenerator::WriteProjectLine(
if (projName && projType) {
cmLocalGenerator* lg = target->GetLocalGenerator();
std::string dir = lg->GetCurrentBinaryDirectory();
dir = root->MaybeConvertToRelativePath(rootBinaryDir, dir);
dir = cmSystemTools::ForceToRelativePath(rootBinaryDir, dir);
if (dir == ".") {
dir.clear();
} else {
@@ -433,7 +433,7 @@ void cmGlobalGhsMultiGenerator::WriteTargets(cmLocalGenerator* root)
target->GetName(), "] had a cycle.\n"));
} else {
for (auto& tgt : build) {
this->WriteProjectLine(fbld, tgt, root, rootBinaryDir);
this->WriteProjectLine(fbld, tgt, rootBinaryDir);
}
}
fbld.Close();
@@ -490,7 +490,7 @@ void cmGlobalGhsMultiGenerator::WriteAllTarget(
target->GetType() == cmStateEnums::SHARED_LIBRARY) {
continue;
}
this->WriteProjectLine(fbld, target, root, rootBinaryDir);
this->WriteProjectLine(fbld, target, rootBinaryDir);
}
}
fbld.Close();
+1 -1
View File
@@ -103,7 +103,7 @@ private:
void WriteSubProjects(std::ostream& fout, std::string& all_target);
void WriteTargets(cmLocalGenerator* root);
void WriteProjectLine(std::ostream& fout, cmGeneratorTarget const* target,
cmLocalGenerator* root, std::string& rootBinaryDir);
std::string& rootBinaryDir);
void WriteCustomRuleBOD(std::ostream& fout);
void WriteCustomTargetBOD(std::ostream& fout);
void WriteAllTarget(cmLocalGenerator* root,
+39
View File
@@ -2,7 +2,10 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGlobalNMakeMakefileGenerator.h"
#include "cmsys/RegularExpression.hxx"
#include "cmDocumentationEntry.h"
#include "cmDuration.h"
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
#include "cmState.h"
@@ -34,6 +37,42 @@ void cmGlobalNMakeMakefileGenerator::EnableLanguage(
this->cmGlobalUnixMakefileGenerator3::EnableLanguage(l, mf, optional);
}
bool cmGlobalNMakeMakefileGenerator::FindMakeProgram(cmMakefile* mf)
{
if (!this->cmGlobalGenerator::FindMakeProgram(mf)) {
return false;
}
if (cmProp nmakeCommand = mf->GetDefinition("CMAKE_MAKE_PROGRAM")) {
std::vector<std::string> command{ *nmakeCommand, "-?" };
std::string out;
std::string err;
if (!cmSystemTools::RunSingleCommand(command, &out, &err, nullptr, nullptr,
cmSystemTools::OUTPUT_NONE,
cmDuration(30))) {
mf->IssueMessage(MessageType::FATAL_ERROR,
cmStrCat("Running\n '", cmJoin(command, "' '"),
"'\n"
"failed with:\n ",
err));
cmSystemTools::SetFatalErrorOccured();
return false;
}
cmsys::RegularExpression regex(
"Program Maintenance Utility Version ([1-9][0-9.]+)");
if (regex.find(err)) {
this->NMakeVersion = regex.match(1);
this->CheckNMakeFeatures();
}
}
return true;
}
void cmGlobalNMakeMakefileGenerator::CheckNMakeFeatures()
{
this->NMakeSupportsUTF8 = !cmSystemTools::VersionCompare(
cmSystemTools::OP_LESS, this->NMakeVersion.c_str(), "9");
}
void cmGlobalNMakeMakefileGenerator::GetDocumentation(
cmDocumentationEntry& entry)
{
+6 -1
View File
@@ -31,7 +31,7 @@ public:
/** Get encoding used by generator for makefile files */
codecvt::Encoding GetMakefileEncoding() const override
{
return codecvt::ANSI;
return this->NMakeSupportsUTF8 ? codecvt::UTF8_WITH_BOM : codecvt::ANSI;
}
/** Get the documentation entry for this generator. */
@@ -55,6 +55,11 @@ protected:
void PrintBuildCommandAdvice(std::ostream& os, int jobs) const override;
private:
bool NMakeSupportsUTF8 = false;
std::string NMakeVersion;
bool FindMakeProgram(cmMakefile* mf) override;
void CheckNMakeFeatures();
void PrintCompilerAdvice(std::ostream& os, std::string const& lang,
const char* envVar) const override;
};
+143 -59
View File
@@ -9,6 +9,8 @@
#include <cm/iterator>
#include <cm/memory>
#include <cm/optional>
#include <cm/string_view>
#include <cmext/algorithm>
#include <cmext/memory>
@@ -214,22 +216,32 @@ void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os,
{
// Write explicit outputs
for (std::string const& output : build.Outputs) {
buildStr += cmStrCat(' ', this->EncodePath(output));
buildStr = cmStrCat(buildStr, ' ', this->EncodePath(output));
if (this->ComputingUnknownDependencies) {
this->CombinedBuildOutputs.insert(output);
}
}
// Write implicit outputs
if (!build.ImplicitOuts.empty()) {
buildStr += " |";
if (!build.ImplicitOuts.empty() || !build.WorkDirOuts.empty()) {
buildStr = cmStrCat(buildStr, " |");
for (std::string const& implicitOut : build.ImplicitOuts) {
buildStr += cmStrCat(' ', this->EncodePath(implicitOut));
buildStr = cmStrCat(buildStr, ' ', this->EncodePath(implicitOut));
if (this->ComputingUnknownDependencies) {
this->CombinedBuildOutputs.insert(implicitOut);
}
}
for (std::string const& workdirOut : build.WorkDirOuts) {
// Repeat some outputs, but expressed as absolute paths.
// This helps Ninja handle absolute paths found in a depfile.
// FIXME: Unfortunately this causes Ninja to stat the file twice.
// We could avoid this if Ninja Issue 1251 were fixed.
buildStr = cmStrCat(buildStr, " ${cmake_ninja_workdir}",
this->EncodePath(workdirOut));
}
}
buildStr += ':';
// Write the rule.
buildStr += cmStrCat(' ', build.Rule);
buildStr = cmStrCat(buildStr, ": ", build.Rule);
}
std::string arguments;
@@ -305,21 +317,46 @@ void cmGlobalNinjaGenerator::AddCustomCommandRule()
this->AddRule(rule);
}
void cmGlobalNinjaGenerator::CCOutputs::Add(
std::vector<std::string> const& paths)
{
for (std::string const& path : paths) {
std::string out = this->GG->ConvertToNinjaPath(path);
if (this->GG->SupportsImplicitOuts() &&
!cmSystemTools::FileIsFullPath(out)) {
// This output is expressed as a relative path. Repeat it,
// but expressed as an absolute path for Ninja Issue 1251.
this->WorkDirOuts.emplace_back(out);
}
this->GG->SeenCustomCommandOutput(out);
this->ExplicitOuts.emplace_back(std::move(out));
}
}
void cmGlobalNinjaGenerator::WriteCustomCommandBuild(
const std::string& command, const std::string& description,
const std::string& comment, const std::string& depfile,
const std::string& job_pool, bool uses_terminal, bool restat,
const cmNinjaDeps& outputs, const std::string& config,
const cmNinjaDeps& explicitDeps, const cmNinjaDeps& orderOnlyDeps)
std::string const& command, std::string const& description,
std::string const& comment, std::string const& depfile,
std::string const& job_pool, bool uses_terminal, bool restat,
std::string const& config, CCOutputs outputs, cmNinjaDeps explicitDeps,
cmNinjaDeps orderOnlyDeps)
{
this->AddCustomCommandRule();
if (this->ComputingUnknownDependencies) {
// we need to track every dependency that comes in, since we are trying
// to find dependencies that are side effects of build commands
for (std::string const& dep : explicitDeps) {
this->CombinedCustomCommandExplicitDependencies.insert(dep);
}
}
{
cmNinjaBuild build("CUSTOM_COMMAND");
build.Comment = comment;
build.Outputs = outputs;
build.ExplicitDeps = explicitDeps;
build.OrderOnlyDeps = orderOnlyDeps;
build.Outputs = std::move(outputs.ExplicitOuts);
build.WorkDirOuts = std::move(outputs.WorkDirOuts);
build.ExplicitDeps = std::move(explicitDeps);
build.OrderOnlyDeps = std::move(orderOnlyDeps);
cmNinjaVars& vars = build.Variables;
{
@@ -349,14 +386,6 @@ void cmGlobalNinjaGenerator::WriteCustomCommandBuild(
this->WriteBuild(*this->GetImplFileStream(config), build);
}
}
if (this->ComputingUnknownDependencies) {
// we need to track every dependency that comes in, since we are trying
// to find dependencies that are side effects of build commands
for (std::string const& dep : explicitDeps) {
this->CombinedCustomCommandExplicitDependencies.insert(dep);
}
}
}
void cmGlobalNinjaGenerator::AddMacOSXContentRule()
@@ -503,14 +532,7 @@ std::unique_ptr<cmLocalGenerator> cmGlobalNinjaGenerator::CreateLocalGenerator(
codecvt::Encoding cmGlobalNinjaGenerator::GetMakefileEncoding() const
{
#ifdef _WIN32
// Ninja on Windows does not support non-ANSI characters.
// https://github.com/ninja-build/ninja/issues/1195
return codecvt::ANSI;
#else
// No encoding conversion needed on other platforms.
return codecvt::None;
#endif
return this->NinjaExpectedEncoding;
}
void cmGlobalNinjaGenerator::GetDocumentation(cmDocumentationEntry& entry)
@@ -732,6 +754,61 @@ void cmGlobalNinjaGenerator::CheckNinjaFeatures()
this->NinjaSupportsMetadataOnRegeneration = !cmSystemTools::VersionCompare(
cmSystemTools::OP_LESS, this->NinjaVersion.c_str(),
RequiredNinjaVersionForMetadataOnRegeneration().c_str());
#ifdef _WIN32
this->NinjaSupportsCodePage = !cmSystemTools::VersionCompare(
cmSystemTools::OP_LESS, this->NinjaVersion.c_str(),
RequiredNinjaVersionForCodePage().c_str());
if (this->NinjaSupportsCodePage) {
this->CheckNinjaCodePage();
} else {
this->NinjaExpectedEncoding = codecvt::ANSI;
}
#endif
}
void cmGlobalNinjaGenerator::CheckNinjaCodePage()
{
std::vector<std::string> command{ this->NinjaCommand, "-t", "wincodepage" };
std::string output;
std::string error;
int result;
if (!cmSystemTools::RunSingleCommand(command, &output, &error, &result,
nullptr, cmSystemTools::OUTPUT_NONE)) {
this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
cmStrCat("Running\n '",
cmJoin(command, "' '"),
"'\n"
"failed with:\n ",
error));
cmSystemTools::SetFatalErrorOccured();
} else if (result == 0) {
std::istringstream outputStream(output);
std::string line;
bool found = false;
while (cmSystemTools::GetLineFromStream(outputStream, line)) {
if (cmHasLiteralPrefix(line, "Build file encoding: ")) {
cm::string_view lineView(line);
cm::string_view encoding =
lineView.substr(cmStrLen("Build file encoding: "));
if (encoding == "UTF-8") {
// Ninja expects UTF-8. We use that internally. No conversion needed.
this->NinjaExpectedEncoding = codecvt::None;
} else {
this->NinjaExpectedEncoding = codecvt::ANSI;
}
found = true;
break;
}
}
if (!found) {
this->GetCMakeInstance()->IssueMessage(
MessageType::WARNING,
"Could not determine Ninja's code page, defaulting to UTF-8");
this->NinjaExpectedEncoding = codecvt::None;
}
} else {
this->NinjaExpectedEncoding = codecvt::ANSI;
}
}
bool cmGlobalNinjaGenerator::CheckLanguages(
@@ -1073,10 +1150,8 @@ std::string const& cmGlobalNinjaGenerator::ConvertToNinjaPath(
return f->second;
}
const auto& ng =
cm::static_reference_cast<cmLocalNinjaGenerator>(this->LocalGenerators[0]);
std::string const& bin_dir = ng.GetState()->GetBinaryDirectory();
std::string convPath = ng.MaybeConvertToRelativePath(bin_dir, path);
std::string convPath =
this->LocalGenerators[0]->MaybeRelativeToTopBinDir(path);
convPath = this->NinjaOutputPath(convPath);
#ifdef _WIN32
std::replace(convPath.begin(), convPath.end(), '/', '\\');
@@ -1150,6 +1225,8 @@ void cmGlobalNinjaGenerator::WriteDisclaimer(std::ostream& os) const
void cmGlobalNinjaGenerator::WriteAssumedSourceDependencies()
{
for (auto const& asd : this->AssumedSourceDependencies) {
CCOutputs outputs(this);
outputs.ExplicitOuts.emplace_back(asd.first);
cmNinjaDeps orderOnlyDeps;
std::copy(asd.second.begin(), asd.second.end(),
std::back_inserter(orderOnlyDeps));
@@ -1158,8 +1235,8 @@ void cmGlobalNinjaGenerator::WriteAssumedSourceDependencies()
"Assume dependencies for generated source file.",
/*depfile*/ "", /*job_pool*/ "",
/*uses_terminal*/ false,
/*restat*/ true, cmNinjaDeps(1, asd.first), "", cmNinjaDeps(),
orderOnlyDeps);
/*restat*/ true, std::string(), outputs, cmNinjaDeps(),
std::move(orderOnlyDeps));
}
}
@@ -2198,14 +2275,22 @@ Compilation of source files within a target is split into the following steps:
(because the latter consumes the module).
*/
static std::unique_ptr<cmSourceInfo> cmcmd_cmake_ninja_depends_fortran(
namespace {
struct cmSourceInfo
{
cmScanDepInfo ScanDep;
std::vector<std::string> Includes;
};
cm::optional<cmSourceInfo> cmcmd_cmake_ninja_depends_fortran(
std::string const& arg_tdi, std::string const& arg_pp);
}
int cmcmd_cmake_ninja_depends(std::vector<std::string>::const_iterator argBeg,
std::vector<std::string>::const_iterator argEnd)
{
std::string arg_tdi;
std::string arg_src;
std::string arg_pp;
std::string arg_dep;
std::string arg_obj;
@@ -2214,8 +2299,6 @@ int cmcmd_cmake_ninja_depends(std::vector<std::string>::const_iterator argBeg,
for (std::string const& arg : cmMakeRange(argBeg, argEnd)) {
if (cmHasLiteralPrefix(arg, "--tdi=")) {
arg_tdi = arg.substr(6);
} else if (cmHasLiteralPrefix(arg, "--src=")) {
arg_src = arg.substr(6);
} else if (cmHasLiteralPrefix(arg, "--pp=")) {
arg_pp = arg.substr(5);
} else if (cmHasLiteralPrefix(arg, "--dep=")) {
@@ -2256,11 +2339,8 @@ int cmcmd_cmake_ninja_depends(std::vector<std::string>::const_iterator argBeg,
cmSystemTools::Error("-E cmake_ninja_depends requires value for --lang=");
return 1;
}
if (arg_src.empty()) {
arg_src = cmStrCat("<", arg_obj, " input file>");
}
std::unique_ptr<cmSourceInfo> info;
cm::optional<cmSourceInfo> info;
if (arg_lang == "Fortran") {
info = cmcmd_cmake_ninja_depends_fortran(arg_tdi, arg_pp);
} else {
@@ -2275,7 +2355,7 @@ int cmcmd_cmake_ninja_depends(std::vector<std::string>::const_iterator argBeg,
return 1;
}
info->PrimaryOutput = arg_obj;
info->ScanDep.PrimaryOutput = arg_obj;
{
cmGeneratedFileStream depfile(arg_dep);
@@ -2286,7 +2366,7 @@ int cmcmd_cmake_ninja_depends(std::vector<std::string>::const_iterator argBeg,
depfile << "\n";
}
if (!cmScanDepFormat_P1689_Write(arg_ddi, arg_src, *info)) {
if (!cmScanDepFormat_P1689_Write(arg_ddi, info->ScanDep)) {
cmSystemTools::Error(
cmStrCat("-E cmake_ninja_depends failed to write ", arg_ddi));
return 1;
@@ -2294,9 +2374,12 @@ int cmcmd_cmake_ninja_depends(std::vector<std::string>::const_iterator argBeg,
return 0;
}
std::unique_ptr<cmSourceInfo> cmcmd_cmake_ninja_depends_fortran(
namespace {
cm::optional<cmSourceInfo> cmcmd_cmake_ninja_depends_fortran(
std::string const& arg_tdi, std::string const& arg_pp)
{
cm::optional<cmSourceInfo> info;
cmFortranCompiler fc;
std::vector<std::string> includes;
{
@@ -2309,7 +2392,7 @@ std::unique_ptr<cmSourceInfo> cmcmd_cmake_ninja_depends_fortran(
cmSystemTools::Error(
cmStrCat("-E cmake_ninja_depends failed to parse ", arg_tdi,
reader.getFormattedErrorMessages()));
return nullptr;
return info;
}
}
@@ -2336,19 +2419,19 @@ std::unique_ptr<cmSourceInfo> cmcmd_cmake_ninja_depends_fortran(
if (!cmFortranParser_FilePush(&parser, arg_pp.c_str())) {
cmSystemTools::Error(
cmStrCat("-E cmake_ninja_depends failed to open ", arg_pp));
return nullptr;
return info;
}
if (cmFortran_yyparse(parser.Scanner) != 0) {
// Failed to parse the file.
return nullptr;
return info;
}
auto info = cm::make_unique<cmSourceInfo>();
info = cmSourceInfo();
for (std::string const& provide : finfo.Provides) {
cmSourceReqInfo src_info;
src_info.LogicalName = provide;
src_info.CompiledModulePath = provide;
info->Provides.emplace_back(src_info);
info->ScanDep.Provides.emplace_back(src_info);
}
for (std::string const& require : finfo.Requires) {
// Require modules not provided in the same source.
@@ -2358,13 +2441,14 @@ std::unique_ptr<cmSourceInfo> cmcmd_cmake_ninja_depends_fortran(
cmSourceReqInfo src_info;
src_info.LogicalName = require;
src_info.CompiledModulePath = require;
info->Requires.emplace_back(src_info);
info->ScanDep.Requires.emplace_back(src_info);
}
for (std::string const& include : finfo.Includes) {
info->Includes.push_back(include);
}
return info;
}
}
bool cmGlobalNinjaGenerator::WriteDyndepFile(
std::string const& dir_top_src, std::string const& dir_top_bld,
@@ -2379,17 +2463,17 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
cmStateSnapshot snapshot = this->GetCMakeInstance()->GetCurrentSnapshot();
snapshot.GetDirectory().SetCurrentSource(dir_cur_src);
snapshot.GetDirectory().SetCurrentBinary(dir_cur_bld);
snapshot.GetDirectory().SetRelativePathTopSource(dir_top_src.c_str());
snapshot.GetDirectory().SetRelativePathTopBinary(dir_top_bld.c_str());
auto mfd = cm::make_unique<cmMakefile>(this, snapshot);
auto lgd = this->CreateLocalGenerator(mfd.get());
lgd->SetRelativePathTopSource(dir_top_src);
lgd->SetRelativePathTopBinary(dir_top_bld);
this->Makefiles.push_back(std::move(mfd));
this->LocalGenerators.push_back(std::move(lgd));
}
std::vector<cmSourceInfo> objects;
std::vector<cmScanDepInfo> objects;
for (std::string const& arg_ddi : arg_ddis) {
cmSourceInfo info;
cmScanDepInfo info;
if (!cmScanDepFormat_P1689_Parse(arg_ddi, &info)) {
cmSystemTools::Error(
cmStrCat("-E cmake_ninja_dyndep failed to parse ddi file ", arg_ddi));
@@ -2425,7 +2509,7 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
// We do this after loading the modules provided by linked targets
// in case we have one of the same name that must be preferred.
Json::Value tm = Json::objectValue;
for (cmSourceInfo const& object : objects) {
for (cmScanDepInfo const& object : objects) {
for (auto const& p : object.Provides) {
std::string const mod = cmStrCat(
module_dir, cmSystemTools::GetFilenameName(p.CompiledModulePath));
@@ -2440,7 +2524,7 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
{
cmNinjaBuild build("dyndep");
build.Outputs.emplace_back("");
for (cmSourceInfo const& object : objects) {
for (cmScanDepInfo const& object : objects) {
build.Outputs[0] = this->ConvertToNinjaPath(object.PrimaryOutput);
build.ImplicitOuts.clear();
for (auto const& p : object.Provides) {
+28 -7
View File
@@ -110,13 +110,29 @@ public:
void WriteBuild(std::ostream& os, cmNinjaBuild const& build,
int cmdLineLimit = 0, bool* usedResponseFile = nullptr);
void WriteCustomCommandBuild(
const std::string& command, const std::string& description,
const std::string& comment, const std::string& depfile,
const std::string& pool, bool uses_terminal, bool restat,
const cmNinjaDeps& outputs, const std::string& config,
const cmNinjaDeps& explicitDeps = cmNinjaDeps(),
const cmNinjaDeps& orderOnlyDeps = cmNinjaDeps());
class CCOutputs
{
cmGlobalNinjaGenerator* GG;
public:
CCOutputs(cmGlobalNinjaGenerator* gg)
: GG(gg)
{
}
void Add(std::vector<std::string> const& outputs);
cmNinjaDeps ExplicitOuts;
cmNinjaDeps WorkDirOuts;
};
void WriteCustomCommandBuild(std::string const& command,
std::string const& description,
std::string const& comment,
std::string const& depfile,
std::string const& pool, bool uses_terminal,
bool restat, std::string const& config,
CCOutputs outputs,
cmNinjaDeps explicitDeps = cmNinjaDeps(),
cmNinjaDeps orderOnlyDeps = cmNinjaDeps());
void WriteMacOSXContentBuild(std::string input, std::string output,
const std::string& config);
@@ -388,6 +404,7 @@ public:
{
return "1.10.2";
}
static std::string RequiredNinjaVersionForCodePage() { return "1.11"; }
bool SupportsConsolePool() const;
bool SupportsImplicitOuts() const;
bool SupportsManifestRestat() const;
@@ -474,6 +491,7 @@ private:
std::string GetEditCacheCommand() const override;
bool FindMakeProgram(cmMakefile* mf) override;
void CheckNinjaFeatures();
void CheckNinjaCodePage();
bool CheckLanguages(std::vector<std::string> const& languages,
cmMakefile* mf) const override;
bool CheckFortran(cmMakefile* mf) const;
@@ -568,6 +586,9 @@ private:
bool NinjaSupportsUnconditionalRecompactTool = false;
bool NinjaSupportsMultipleOutputs = false;
bool NinjaSupportsMetadataOnRegeneration = false;
bool NinjaSupportsCodePage = false;
codecvt::Encoding NinjaExpectedEncoding = codecvt::None;
bool DiagnosedCxxModuleSupport = false;
+8 -39
View File
@@ -22,7 +22,6 @@
#include "cmOutputConverter.h"
#include "cmProperty.h"
#include "cmState.h"
#include "cmStateDirectory.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -147,7 +146,7 @@ void cmGlobalUnixMakefileGenerator3::Generate()
// write each target's progress.make this loop is done twice. Basically the
// Generate pass counts all the actions, the first loop below determines
// how many actions have progress updates for each target and writes to
// corrrect variable values for everything except the all targets. The
// correct variable values for everything except the all targets. The
// second loop actually writes out correct values for the all targets as
// well. This is because the all targets require more information that is
// computed in the first loop.
@@ -318,16 +317,13 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
const auto& lg = cm::static_reference_cast<cmLocalUnixMakefileGenerator3>(
this->LocalGenerators[0]);
const std::string& currentBinDir = lg.GetCurrentBinaryDirectory();
// Save the list to the cmake file.
cmakefileStream
<< "# The top level Makefile was generated from the following files:\n"
<< "set(CMAKE_MAKEFILE_DEPENDS\n"
<< " \"CMakeCache.txt\"\n";
for (std::string const& f : lfiles) {
cmakefileStream << " \""
<< lg.MaybeConvertToRelativePath(currentBinDir, f)
<< "\"\n";
cmakefileStream << " \"" << lg.MaybeRelativeToCurBinDir(f) << "\"\n";
}
cmakefileStream << " )\n\n";
@@ -339,17 +335,11 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
// Set the corresponding makefile in the cmake file.
cmakefileStream << "# The corresponding makefile is:\n"
<< "set(CMAKE_MAKEFILE_OUTPUTS\n"
<< " \""
<< lg.MaybeConvertToRelativePath(currentBinDir,
makefileName)
<< " \"" << lg.MaybeRelativeToCurBinDir(makefileName)
<< "\"\n"
<< " \""
<< lg.MaybeConvertToRelativePath(currentBinDir, check)
<< "\"\n";
<< " \"" << lg.MaybeRelativeToCurBinDir(check) << "\"\n";
cmakefileStream << " )\n\n";
const std::string& binDir = lg.GetBinaryDirectory();
// CMake must rerun if a byproduct is missing.
cmakefileStream << "# Byproducts of CMake generate step:\n"
<< "set(CMAKE_MAKEFILE_PRODUCTS\n";
@@ -359,14 +349,12 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
for (const auto& localGen : this->LocalGenerators) {
for (std::string const& outfile :
localGen->GetMakefile()->GetOutputFiles()) {
cmakefileStream << " \""
<< lg.MaybeConvertToRelativePath(binDir, outfile)
cmakefileStream << " \"" << lg.MaybeRelativeToTopBinDir(outfile)
<< "\"\n";
}
tmpStr = cmStrCat(localGen->GetCurrentBinaryDirectory(),
"/CMakeFiles/CMakeDirectoryInformation.cmake");
cmakefileStream << " \""
<< localGen->MaybeConvertToRelativePath(binDir, tmpStr)
cmakefileStream << " \"" << localGen->MaybeRelativeToTopBinDir(tmpStr)
<< "\"\n";
}
cmakefileStream << " )\n\n";
@@ -458,9 +446,8 @@ void cmGlobalUnixMakefileGenerator3::WriteDirectoryRules2(
auto* lg = static_cast<cmLocalUnixMakefileGenerator3*>(dt.LG);
// Begin the directory-level rules section.
{
std::string dir =
cmSystemTools::ConvertToOutputPath(lg->MaybeConvertToRelativePath(
lg->GetBinaryDirectory(), lg->GetCurrentBinaryDirectory()));
std::string dir = cmSystemTools::ConvertToOutputPath(
lg->MaybeRelativeToTopBinDir(lg->GetCurrentBinaryDirectory()));
lg->WriteDivider(ruleFileStream);
if (lg->IsRootMakefile()) {
ruleFileStream << "# Directory level rules for the build root directory";
@@ -564,21 +551,6 @@ cmGlobalUnixMakefileGenerator3::GenerateBuildCommand(
bool fast, int jobs, bool verbose,
std::vector<std::string> const& makeOptions)
{
std::unique_ptr<cmMakefile> mfu;
cmMakefile* mf;
if (!this->Makefiles.empty()) {
mf = this->Makefiles[0].get();
} else {
cmStateSnapshot snapshot = this->CMakeInstance->GetCurrentSnapshot();
snapshot.GetDirectory().SetCurrentSource(
this->CMakeInstance->GetHomeDirectory());
snapshot.GetDirectory().SetCurrentBinary(
this->CMakeInstance->GetHomeOutputDirectory());
snapshot.SetDefaultDefinitions();
mfu = cm::make_unique<cmMakefile>(this, snapshot);
mf = mfu.get();
}
GeneratedMakeCommand makeCommand;
// Make it possible to set verbosity also from command line
@@ -609,9 +581,6 @@ cmGlobalUnixMakefileGenerator3::GenerateBuildCommand(
if (fast) {
tname += "/fast";
}
tname =
mf->GetStateSnapshot().GetDirectory().ConvertToRelPathIfNotContained(
mf->GetState()->GetBinaryDirectory(), tname);
cmSystemTools::ConvertToOutputSlashes(tname);
makeCommand.Add(std::move(tname));
}

Some files were not shown because too many files have changed in this diff Show More