mirror of
https://github.com/Kitware/CMake.git
synced 2026-05-03 21:00:01 -05:00
Merge branch 'master' into cmp0082-exclude-from-all
This commit is contained in:
@@ -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,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)
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ private:
|
||||
return this->OutputExtension.c_str();
|
||||
}
|
||||
|
||||
bool SetArchiveOptions(cmArchiveWrite* archive);
|
||||
int GetThreadCount() const;
|
||||
|
||||
private:
|
||||
cmArchiveWrite::Compress Compress;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 << "\"";
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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";
|
||||
});
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -60,4 +60,5 @@ protected:
|
||||
std::string Configuration;
|
||||
std::string Flags;
|
||||
std::string ProjectName;
|
||||
std::string ParallelLevel;
|
||||
};
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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), "");
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
@@ -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 */
|
||||
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
+235
-844
File diff suppressed because it is too large
Load Diff
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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 },
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user