diff options
Diffstat (limited to 'Source')
289 files changed, 6220 insertions, 4797 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 9a18184fd..c8498a991 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -10,36 +10,6 @@ if (NOT CMAKE_SYSTEM_NAME STREQUAL "QNX") endif() include(CheckIncludeFile) -# Check if we can build support for ELF parsing. -if(WIN32) - set(HAVE_ELF_H 0) -elseif(CMAKE_CXX_PLATFORM_ID MATCHES "OpenBSD") - CHECK_INCLUDE_FILES("stdint.h;elf_abi.h" HAVE_ELF_H) -else() - CHECK_INCLUDE_FILE("elf.h" HAVE_ELF_H) -endif() -if(HAVE_ELF_H) - set(CMake_USE_ELF_PARSER 1) -elseif(HAIKU) - # On Haiku, we need to include elf32.h from the private headers - set(CMake_HAIKU_INCLUDE_DIRS - /boot/system/develop/headers/private/system - /boot/system/develop/headers/private/system/arch/x86 - ) - - set(CMAKE_REQUIRED_INCLUDES ${CMake_HAIKU_INCLUDE_DIRS}) - CHECK_INCLUDE_FILE("elf32.h" HAVE_ELF32_H) - unset(CMAKE_REQUIRED_INCLUDES) - - if(HAVE_ELF32_H) - set(CMake_USE_ELF_PARSER 1) - else() - unset(CMake_HAIKU_INCLUDE_DIRS) - set(CMake_USE_ELF_PARSER) - endif() -else() - set(CMake_USE_ELF_PARSER) -endif() if(NOT CMake_DEFAULT_RECURSION_LIMIT) if(DEFINED ENV{DASHBOARD_TEST_FROM_CTEST}) @@ -111,11 +81,6 @@ include_directories( ${CMake_HAIKU_INCLUDE_DIRS} ) -# Check if we can build the ELF parser. -if(CMake_USE_ELF_PARSER) - set(ELF_SRCS cmELF.h cmELF.cxx) -endif() - # Check if we can build the Mach-O parser. if(CMake_USE_MACH_PARSER) set(MACH_SRCS cmMachO.h cmMachO.cxx) @@ -245,7 +210,8 @@ set(SRCS cmDocumentationSection.cxx cmDynamicLoader.cxx cmDynamicLoader.h - ${ELF_SRCS} + cmELF.h + cmELF.cxx cmExprParserHelper.cxx cmExportBuildAndroidMKGenerator.h cmExportBuildAndroidMKGenerator.cxx @@ -415,6 +381,8 @@ set(SRCS cmProcessOutput.h cmProcessTools.cxx cmProcessTools.h + cmValue.cxx + cmValue.h cmProperty.h cmPropertyDefinition.cxx cmPropertyDefinition.h @@ -834,7 +802,7 @@ if (WIN32) endif () # Watcom support -if(WIN32 OR CMAKE_SYSTEM_NAME STREQUAL "Linux") +if(WIN32 OR CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "Darwin") set_property(SOURCE cmake.cxx APPEND PROPERTY COMPILE_DEFINITIONS CMAKE_USE_WMAKE) list(APPEND SRCS cmGlobalWatcomWMakeGenerator.cxx @@ -994,6 +962,7 @@ set(CTEST_SRCS cmCTest.cxx CTest/cmCTestSubmitHandler.cxx CTest/cmCTestTestCommand.cxx CTest/cmCTestTestHandler.cxx + CTest/cmCTestTestMeasurementXMLParser.cxx CTest/cmCTestUpdateCommand.cxx CTest/cmCTestUpdateHandler.cxx CTest/cmCTestUploadCommand.cxx diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 392f8a9c9..512f47eda 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,7 +1,7 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) -set(CMake_VERSION_MINOR 21) -set(CMake_VERSION_PATCH 7) +set(CMake_VERSION_MINOR 22) +set(CMake_VERSION_PATCH 0) #set(CMake_VERSION_RC 0) set(CMake_VERSION_IS_DIRTY 0) @@ -21,7 +21,7 @@ endif() if(NOT CMake_VERSION_NO_GIT) # If this source was exported by 'git archive', use its commit info. - set(git_info [==[97073b1991 CMake 3.21.7]==]) + set(git_info [==[ff8c3acc0f CMake 3.22.0]==]) # Otherwise, try to identify the current development source version. if(NOT git_info MATCHES "^([0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]?[0-9a-f]?)[0-9a-f]* " diff --git a/Source/CPack/IFW/cmCPackIFWCommon.cxx b/Source/CPack/IFW/cmCPackIFWCommon.cxx index 87ebbfeb9..f6b8a8a53 100644 --- a/Source/CPack/IFW/cmCPackIFWCommon.cxx +++ b/Source/CPack/IFW/cmCPackIFWCommon.cxx @@ -21,7 +21,7 @@ cmCPackIFWCommon::cmCPackIFWCommon() { } -const char* cmCPackIFWCommon::GetOption(const std::string& op) const +cmValue cmCPackIFWCommon::GetOption(const std::string& op) const { return this->Generator ? this->Generator->cmCPackGenerator::GetOption(op) : nullptr; @@ -51,7 +51,7 @@ bool cmCPackIFWCommon::IsVersionLess(const char* version) const } return cmSystemTools::VersionCompare( - cmSystemTools::OP_LESS, this->Generator->FrameworkVersion.data(), version); + cmSystemTools::OP_LESS, this->Generator->FrameworkVersion, version); } bool cmCPackIFWCommon::IsVersionGreater(const char* version) const @@ -61,8 +61,7 @@ bool cmCPackIFWCommon::IsVersionGreater(const char* version) const } return cmSystemTools::VersionCompare( - cmSystemTools::OP_GREATER, this->Generator->FrameworkVersion.data(), - version); + cmSystemTools::OP_GREATER, this->Generator->FrameworkVersion, version); } bool cmCPackIFWCommon::IsVersionEqual(const char* version) const @@ -72,8 +71,7 @@ bool cmCPackIFWCommon::IsVersionEqual(const char* version) const } return cmSystemTools::VersionCompare( - cmSystemTools::OP_EQUAL, this->Generator->FrameworkVersion.data(), - version); + cmSystemTools::OP_EQUAL, this->Generator->FrameworkVersion, version); } void cmCPackIFWCommon::ExpandListArgument( diff --git a/Source/CPack/IFW/cmCPackIFWCommon.h b/Source/CPack/IFW/cmCPackIFWCommon.h index 42deda4ea..f2e6b889c 100644 --- a/Source/CPack/IFW/cmCPackIFWCommon.h +++ b/Source/CPack/IFW/cmCPackIFWCommon.h @@ -7,6 +7,8 @@ #include <map> #include <string> +#include "cmValue.h" + class cmCPackIFWGenerator; class cmXMLWriter; @@ -26,7 +28,7 @@ public: public: // Internal implementation - const char* GetOption(const std::string& op) const; + cmValue GetOption(const std::string& op) const; bool IsOn(const std::string& op) const; bool IsSetToOff(const std::string& op) const; bool IsSetToEmpty(const std::string& op) const; diff --git a/Source/CPack/IFW/cmCPackIFWGenerator.cxx b/Source/CPack/IFW/cmCPackIFWGenerator.cxx index 2806c614e..b375ba605 100644 --- a/Source/CPack/IFW/cmCPackIFWGenerator.cxx +++ b/Source/CPack/IFW/cmCPackIFWGenerator.cxx @@ -16,6 +16,7 @@ #include "cmGeneratedFileStream.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" cmCPackIFWGenerator::cmCPackIFWGenerator() { @@ -248,9 +249,9 @@ const char* cmCPackIFWGenerator::GetPackagingInstallPrefix() tmpPref += "packages/" + this->GetRootPackageName() + "/data"; } - this->SetOption("CPACK_IFW_PACKAGING_INSTALL_PREFIX", tmpPref.c_str()); + this->SetOption("CPACK_IFW_PACKAGING_INSTALL_PREFIX", tmpPref); - return this->GetOption("CPACK_IFW_PACKAGING_INSTALL_PREFIX"); + return this->GetOption("CPACK_IFW_PACKAGING_INSTALL_PREFIX")->c_str(); } const char* cmCPackIFWGenerator::GetOutputExtension() @@ -273,11 +274,11 @@ int cmCPackIFWGenerator::InitializeInternal() // Look 'binarycreator' executable (needs) - const char* BinCreatorStr = this->GetOption(BinCreatorOpt); + cmValue BinCreatorStr = this->GetOption(BinCreatorOpt); if (!BinCreatorStr || cmIsNOTFOUND(BinCreatorStr)) { this->BinCreator.clear(); } else { - this->BinCreator = BinCreatorStr; + this->BinCreator = *BinCreatorStr; } if (this->BinCreator.empty()) { @@ -290,16 +291,16 @@ int cmCPackIFWGenerator::InitializeInternal() // Look 'repogen' executable (optional) - const char* RepoGenStr = this->GetOption(RepoGenOpt); - if (!RepoGenStr || cmIsNOTFOUND(RepoGenStr)) { + cmValue repoGen = this->GetOption(RepoGenOpt); + if (!repoGen || cmIsNOTFOUND(repoGen)) { this->RepoGen.clear(); } else { - this->RepoGen = RepoGenStr; + this->RepoGen = *repoGen; } // Framework version - if (const char* FrameworkVersionSrt = this->GetOption(FrameworkVersionOpt)) { - this->FrameworkVersion = FrameworkVersionSrt; + if (cmValue frameworkVersion = this->GetOption(FrameworkVersionOpt)) { + this->FrameworkVersion = *frameworkVersion; } else { this->FrameworkVersion = "1.9.9"; } @@ -312,14 +313,13 @@ int cmCPackIFWGenerator::InitializeInternal() // Additional packages dirs this->PkgsDirsVector.clear(); - if (const char* dirs = this->GetOption("CPACK_IFW_PACKAGES_DIRECTORIES")) { + if (cmValue dirs = this->GetOption("CPACK_IFW_PACKAGES_DIRECTORIES")) { cmExpandList(dirs, this->PkgsDirsVector); } // Additional repositories dirs this->RepoDirsVector.clear(); - if (const char* dirs = - this->GetOption("CPACK_IFW_REPOSITORIES_DIRECTORIES")) { + if (cmValue dirs = this->GetOption("CPACK_IFW_REPOSITORIES_DIRECTORIES")) { cmExpandList(dirs, this->RepoDirsVector); } @@ -330,22 +330,22 @@ int cmCPackIFWGenerator::InitializeInternal() // Repository this->Repository.Generator = this; this->Repository.Name = "Unspecified"; - if (const char* site = this->GetOption("CPACK_DOWNLOAD_SITE")) { - this->Repository.Url = site; + if (cmValue site = this->GetOption("CPACK_DOWNLOAD_SITE")) { + this->Repository.Url = *site; this->Installer.RemoteRepositories.push_back(&this->Repository); } // Repositories - if (const char* RepoAllStr = this->GetOption("CPACK_IFW_REPOSITORIES_ALL")) { + if (cmValue RepoAllStr = this->GetOption("CPACK_IFW_REPOSITORIES_ALL")) { std::vector<std::string> RepoAllVector = cmExpandedList(RepoAllStr); for (std::string const& r : RepoAllVector) { this->GetRepository(r); } } - if (const char* ifwDownloadAll = this->GetOption("CPACK_IFW_DOWNLOAD_ALL")) { + if (cmValue ifwDownloadAll = this->GetOption("CPACK_IFW_DOWNLOAD_ALL")) { this->OnlineOnly = cmIsOn(ifwDownloadAll); - } else if (const char* cpackDownloadAll = + } else if (cmValue cpackDownloadAll = this->GetOption("CPACK_DOWNLOAD_ALL")) { this->OnlineOnly = cmIsOn(cpackDownloadAll); } else { @@ -374,9 +374,9 @@ int cmCPackIFWGenerator::InitializeInternal() } // Output extension - if (const char* optOutExt = + if (cmValue optOutExt = this->GetOption("CPACK_IFW_PACKAGE_FILE_EXTENSION")) { - this->OutputExtension = optOutExt; + this->OutputExtension = *optOutExt; } else if (sysName == "Darwin") { this->OutputExtension = ".dmg"; } else { @@ -508,21 +508,20 @@ std::string cmCPackIFWGenerator::GetRootPackageName() { // Default value std::string name = "root"; - if (const char* optIFW_PACKAGE_GROUP = + if (cmValue optIFW_PACKAGE_GROUP = this->GetOption("CPACK_IFW_PACKAGE_GROUP")) { // Configure from root group cmCPackIFWPackage package; package.Generator = this; package.ConfigureFromGroup(optIFW_PACKAGE_GROUP); name = package.Name; - } else if (const char* optIFW_PACKAGE_NAME = + } else if (cmValue optIFW_PACKAGE_NAME = this->GetOption("CPACK_IFW_PACKAGE_NAME")) { // Configure from root package name - name = optIFW_PACKAGE_NAME; - } else if (const char* optPACKAGE_NAME = - this->GetOption("CPACK_PACKAGE_NAME")) { + name = *optIFW_PACKAGE_NAME; + } else if (cmValue optPACKAGE_NAME = this->GetOption("CPACK_PACKAGE_NAME")) { // Configure from package name - name = optPACKAGE_NAME; + name = *optPACKAGE_NAME; } return name; } @@ -537,10 +536,10 @@ std::string cmCPackIFWGenerator::GetGroupPackageName( if (cmCPackIFWPackage* package = this->GetGroupPackage(group)) { return package->Name; } - const char* option = + cmValue option = this->GetOption("CPACK_IFW_COMPONENT_GROUP_" + cmsys::SystemTools::UpperCase(group->Name) + "_NAME"); - name = option ? option : group->Name; + name = option ? *option : group->Name; if (group->ParentGroup) { cmCPackIFWPackage* package = this->GetGroupPackage(group->ParentGroup); bool dot = !this->ResolveDuplicateNames; @@ -563,8 +562,8 @@ std::string cmCPackIFWGenerator::GetComponentPackageName( } std::string prefix = "CPACK_IFW_COMPONENT_" + cmsys::SystemTools::UpperCase(component->Name) + "_"; - const char* option = this->GetOption(prefix + "NAME"); - name = option ? option : component->Name; + cmValue option = this->GetOption(prefix + "NAME"); + name = option ? *option : component->Name; if (component->Group) { cmCPackIFWPackage* package = this->GetGroupPackage(component->Group); if ((this->componentPackageMethod == diff --git a/Source/CPack/IFW/cmCPackIFWInstaller.cxx b/Source/CPack/IFW/cmCPackIFWInstaller.cxx index bf8b457b4..7ee6300b8 100644 --- a/Source/CPack/IFW/cmCPackIFWInstaller.cxx +++ b/Source/CPack/IFW/cmCPackIFWInstaller.cxx @@ -14,6 +14,7 @@ #include "cmGeneratedFileStream.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" #include "cmXMLParser.h" #include "cmXMLWriter.h" @@ -33,61 +34,60 @@ void cmCPackIFWInstaller::printSkippedOptionWarning( void cmCPackIFWInstaller::ConfigureFromOptions() { // Name; - if (const char* optIFW_PACKAGE_NAME = + if (cmValue optIFW_PACKAGE_NAME = this->GetOption("CPACK_IFW_PACKAGE_NAME")) { - this->Name = optIFW_PACKAGE_NAME; - } else if (const char* optPACKAGE_NAME = - this->GetOption("CPACK_PACKAGE_NAME")) { - this->Name = optPACKAGE_NAME; + this->Name = *optIFW_PACKAGE_NAME; + } else if (cmValue optPACKAGE_NAME = this->GetOption("CPACK_PACKAGE_NAME")) { + this->Name = *optPACKAGE_NAME; } else { this->Name = "Your package"; } // Title; - if (const char* optIFW_PACKAGE_TITLE = + if (cmValue optIFW_PACKAGE_TITLE = this->GetOption("CPACK_IFW_PACKAGE_TITLE")) { - this->Title = optIFW_PACKAGE_TITLE; - } else if (const char* optPACKAGE_DESCRIPTION_SUMMARY = + this->Title = *optIFW_PACKAGE_TITLE; + } else if (cmValue optPACKAGE_DESCRIPTION_SUMMARY = this->GetOption("CPACK_PACKAGE_DESCRIPTION_SUMMARY")) { - this->Title = optPACKAGE_DESCRIPTION_SUMMARY; + this->Title = *optPACKAGE_DESCRIPTION_SUMMARY; } else { this->Title = "Your package description"; } // Version; - if (const char* option = this->GetOption("CPACK_PACKAGE_VERSION")) { - this->Version = option; + if (cmValue option = this->GetOption("CPACK_PACKAGE_VERSION")) { + this->Version = *option; } else { this->Version = "1.0.0"; } // Publisher - if (const char* optIFW_PACKAGE_PUBLISHER = + if (cmValue optIFW_PACKAGE_PUBLISHER = this->GetOption("CPACK_IFW_PACKAGE_PUBLISHER")) { - this->Publisher = optIFW_PACKAGE_PUBLISHER; - } else if (const char* optPACKAGE_VENDOR = + this->Publisher = *optIFW_PACKAGE_PUBLISHER; + } else if (cmValue optPACKAGE_VENDOR = this->GetOption("CPACK_PACKAGE_VENDOR")) { - this->Publisher = optPACKAGE_VENDOR; + this->Publisher = *optPACKAGE_VENDOR; } // ProductUrl - if (const char* option = this->GetOption("CPACK_IFW_PRODUCT_URL")) { - this->ProductUrl = option; + if (cmValue option = this->GetOption("CPACK_IFW_PRODUCT_URL")) { + this->ProductUrl = *option; } // ApplicationIcon - if (const char* option = this->GetOption("CPACK_IFW_PACKAGE_ICON")) { + if (cmValue option = this->GetOption("CPACK_IFW_PACKAGE_ICON")) { if (cmSystemTools::FileExists(option)) { - this->InstallerApplicationIcon = option; + this->InstallerApplicationIcon = *option; } else { this->printSkippedOptionWarning("CPACK_IFW_PACKAGE_ICON", option); } } // WindowIcon - if (const char* option = this->GetOption("CPACK_IFW_PACKAGE_WINDOW_ICON")) { + if (cmValue option = this->GetOption("CPACK_IFW_PACKAGE_WINDOW_ICON")) { if (cmSystemTools::FileExists(option)) { - this->InstallerWindowIcon = option; + this->InstallerWindowIcon = *option; } else { this->printSkippedOptionWarning("CPACK_IFW_PACKAGE_WINDOW_ICON", option); } @@ -103,45 +103,45 @@ void cmCPackIFWInstaller::ConfigureFromOptions() } // Logo - if (const char* option = this->GetOption("CPACK_IFW_PACKAGE_LOGO")) { + if (cmValue option = this->GetOption("CPACK_IFW_PACKAGE_LOGO")) { if (cmSystemTools::FileExists(option)) { - this->Logo = option; + this->Logo = *option; } else { this->printSkippedOptionWarning("CPACK_IFW_PACKAGE_LOGO", option); } } // Watermark - if (const char* option = this->GetOption("CPACK_IFW_PACKAGE_WATERMARK")) { + if (cmValue option = this->GetOption("CPACK_IFW_PACKAGE_WATERMARK")) { if (cmSystemTools::FileExists(option)) { - this->Watermark = option; + this->Watermark = *option; } else { this->printSkippedOptionWarning("CPACK_IFW_PACKAGE_WATERMARK", option); } } // Banner - if (const char* option = this->GetOption("CPACK_IFW_PACKAGE_BANNER")) { + if (cmValue option = this->GetOption("CPACK_IFW_PACKAGE_BANNER")) { if (cmSystemTools::FileExists(option)) { - this->Banner = option; + this->Banner = *option; } else { this->printSkippedOptionWarning("CPACK_IFW_PACKAGE_BANNER", option); } } // Background - if (const char* option = this->GetOption("CPACK_IFW_PACKAGE_BACKGROUND")) { + if (cmValue option = this->GetOption("CPACK_IFW_PACKAGE_BACKGROUND")) { if (cmSystemTools::FileExists(option)) { - this->Background = option; + this->Background = *option; } else { this->printSkippedOptionWarning("CPACK_IFW_PACKAGE_BACKGROUND", option); } } // WizardStyle - if (const char* option = this->GetOption("CPACK_IFW_PACKAGE_WIZARD_STYLE")) { + if (cmValue option = this->GetOption("CPACK_IFW_PACKAGE_WIZARD_STYLE")) { // Setting the user value in any case - this->WizardStyle = option; + this->WizardStyle = *option; // Check known values if (this->WizardStyle != "Modern" && this->WizardStyle != "Aero" && this->WizardStyle != "Mac" && this->WizardStyle != "Classic") { @@ -154,28 +154,28 @@ void cmCPackIFWInstaller::ConfigureFromOptions() } // StyleSheet - if (const char* option = this->GetOption("CPACK_IFW_PACKAGE_STYLE_SHEET")) { + if (cmValue option = this->GetOption("CPACK_IFW_PACKAGE_STYLE_SHEET")) { if (cmSystemTools::FileExists(option)) { - this->StyleSheet = option; + this->StyleSheet = *option; } else { this->printSkippedOptionWarning("CPACK_IFW_PACKAGE_STYLE_SHEET", option); } } // WizardDefaultWidth - if (const char* option = + if (cmValue option = this->GetOption("CPACK_IFW_PACKAGE_WIZARD_DEFAULT_WIDTH")) { - this->WizardDefaultWidth = option; + this->WizardDefaultWidth = *option; } // WizardDefaultHeight - if (const char* option = + if (cmValue option = this->GetOption("CPACK_IFW_PACKAGE_WIZARD_DEFAULT_HEIGHT")) { - this->WizardDefaultHeight = option; + this->WizardDefaultHeight = *option; } // WizardShowPageList - if (const char* option = + if (cmValue option = this->GetOption("CPACK_IFW_PACKAGE_WIZARD_SHOW_PAGE_LIST")) { if (!this->IsVersionLess("4.0")) { if (this->IsSetToOff("CPACK_IFW_PACKAGE_WIZARD_SHOW_PAGE_LIST")) { @@ -204,23 +204,23 @@ void cmCPackIFWInstaller::ConfigureFromOptions() } // TitleColor - if (const char* option = this->GetOption("CPACK_IFW_PACKAGE_TITLE_COLOR")) { - this->TitleColor = option; + if (cmValue option = this->GetOption("CPACK_IFW_PACKAGE_TITLE_COLOR")) { + this->TitleColor = *option; } // Start menu - if (const char* optIFW_START_MENU_DIR = + if (cmValue optIFW_START_MENU_DIR = this->GetOption("CPACK_IFW_PACKAGE_START_MENU_DIRECTORY")) { - this->StartMenuDir = optIFW_START_MENU_DIR; + this->StartMenuDir = *optIFW_START_MENU_DIR; } else { this->StartMenuDir = this->Name; } // Default target directory for installation - if (const char* optIFW_TARGET_DIRECTORY = + if (cmValue optIFW_TARGET_DIRECTORY = this->GetOption("CPACK_IFW_TARGET_DIRECTORY")) { - this->TargetDir = optIFW_TARGET_DIRECTORY; - } else if (const char* optPACKAGE_INSTALL_DIRECTORY = + this->TargetDir = *optIFW_TARGET_DIRECTORY; + } else if (cmValue optPACKAGE_INSTALL_DIRECTORY = this->GetOption("CPACK_PACKAGE_INSTALL_DIRECTORY")) { this->TargetDir = cmStrCat("@ApplicationsDir@/", optPACKAGE_INSTALL_DIRECTORY); @@ -229,21 +229,20 @@ void cmCPackIFWInstaller::ConfigureFromOptions() } // Default target directory for installation with administrator rights - if (const char* option = - this->GetOption("CPACK_IFW_ADMIN_TARGET_DIRECTORY")) { - this->AdminTargetDir = option; + if (cmValue option = this->GetOption("CPACK_IFW_ADMIN_TARGET_DIRECTORY")) { + this->AdminTargetDir = *option; } // Maintenance tool - if (const char* optIFW_MAINTENANCE_TOOL = + if (cmValue optIFW_MAINTENANCE_TOOL = this->GetOption("CPACK_IFW_PACKAGE_MAINTENANCE_TOOL_NAME")) { - this->MaintenanceToolName = optIFW_MAINTENANCE_TOOL; + this->MaintenanceToolName = *optIFW_MAINTENANCE_TOOL; } // Maintenance tool ini file - if (const char* optIFW_MAINTENANCE_TOOL_INI = + if (cmValue optIFW_MAINTENANCE_TOOL_INI = this->GetOption("CPACK_IFW_PACKAGE_MAINTENANCE_TOOL_INI_FILE")) { - this->MaintenanceToolIniFile = optIFW_MAINTENANCE_TOOL_INI; + this->MaintenanceToolIniFile = *optIFW_MAINTENANCE_TOOL_INI; } // Allow non-ASCII characters @@ -265,13 +264,13 @@ void cmCPackIFWInstaller::ConfigureFromOptions() } // Control script - if (const char* optIFW_CONTROL_SCRIPT = + if (cmValue optIFW_CONTROL_SCRIPT = this->GetOption("CPACK_IFW_PACKAGE_CONTROL_SCRIPT")) { - this->ControlScript = optIFW_CONTROL_SCRIPT; + this->ControlScript = *optIFW_CONTROL_SCRIPT; } // Resources - if (const char* optIFW_PACKAGE_RESOURCES = + if (cmValue optIFW_PACKAGE_RESOURCES = this->GetOption("CPACK_IFW_PACKAGE_RESOURCES")) { this->Resources.clear(); cmExpandList(optIFW_PACKAGE_RESOURCES, this->Resources); @@ -541,7 +540,7 @@ void cmCPackIFWInstaller::GeneratePackageFiles() package.Generator = this->Generator; package.Installer = this; // Check package group - if (const char* option = this->GetOption("CPACK_IFW_PACKAGE_GROUP")) { + if (cmValue option = this->GetOption("CPACK_IFW_PACKAGE_GROUP")) { package.ConfigureFromGroup(option); std::string forcedOption = "CPACK_IFW_COMPONENT_GROUP_" + cmsys::SystemTools::UpperCase(option) + "_FORCED_INSTALLATION"; diff --git a/Source/CPack/IFW/cmCPackIFWPackage.cxx b/Source/CPack/IFW/cmCPackIFWPackage.cxx index 1429c4670..c2109c967 100644 --- a/Source/CPack/IFW/cmCPackIFWPackage.cxx +++ b/Source/CPack/IFW/cmCPackIFWPackage.cxx @@ -18,6 +18,7 @@ #include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTimestamp.h" +#include "cmValue.h" #include "cmXMLWriter.h" //---------------------------------------------------------- CompareStruct --- @@ -124,10 +125,10 @@ std::string cmCPackIFWPackage::GetComponentName(cmCPackComponent* component) if (!component) { return ""; } - const char* option = + cmValue option = this->GetOption("CPACK_IFW_COMPONENT_" + cmsys::SystemTools::UpperCase(component->Name) + "_NAME"); - return option ? option : component->Name; + return option ? *option : component->Name; } void cmCPackIFWPackage::DefaultConfiguration() @@ -159,23 +160,22 @@ int cmCPackIFWPackage::ConfigureFromOptions() this->Name = this->Generator->GetRootPackageName(); // Display name - if (const char* option = this->GetOption("CPACK_PACKAGE_NAME")) { - this->DisplayName[""] = option; + if (cmValue option = this->GetOption("CPACK_PACKAGE_NAME")) { + this->DisplayName[""] = *option; } else { this->DisplayName[""] = "Your package"; } // Description - if (const char* option = - this->GetOption("CPACK_PACKAGE_DESCRIPTION_SUMMARY")) { - this->Description[""] = option; + if (cmValue option = this->GetOption("CPACK_PACKAGE_DESCRIPTION_SUMMARY")) { + this->Description[""] = *option; } else { this->Description[""] = "Your package description"; } // Version - if (const char* option = this->GetOption("CPACK_PACKAGE_VERSION")) { - this->Version = option; + if (cmValue option = this->GetOption("CPACK_PACKAGE_VERSION")) { + this->Version = *option; } else { this->Version = "1.0.0"; } @@ -204,22 +204,22 @@ int cmCPackIFWPackage::ConfigureFromComponent(cmCPackComponent* component) this->Description[""] = component->Description; // Version - if (const char* optVERSION = this->GetOption(prefix + "VERSION")) { - this->Version = optVERSION; - } else if (const char* optPACKAGE_VERSION = + if (cmValue optVERSION = this->GetOption(prefix + "VERSION")) { + this->Version = *optVERSION; + } else if (cmValue optPACKAGE_VERSION = this->GetOption("CPACK_PACKAGE_VERSION")) { - this->Version = optPACKAGE_VERSION; + this->Version = *optPACKAGE_VERSION; } else { this->Version = "1.0.0"; } // Script - if (const char* option = this->GetOption(prefix + "SCRIPT")) { - this->Script = option; + if (cmValue option = this->GetOption(prefix + "SCRIPT")) { + this->Script = *option; } // User interfaces - if (const char* option = this->GetOption(prefix + "USER_INTERFACES")) { + if (cmValue option = this->GetOption(prefix + "USER_INTERFACES")) { this->UserInterfaces.clear(); cmExpandList(option, this->UserInterfaces); } @@ -232,7 +232,7 @@ int cmCPackIFWPackage::ConfigureFromComponent(cmCPackComponent* component) } // Licenses - if (const char* option = this->GetOption(prefix + "LICENSES")) { + if (cmValue option = this->GetOption(prefix + "LICENSES")) { this->Licenses.clear(); cmExpandList(option, this->Licenses); if (this->Licenses.size() % 2 != 0) { @@ -246,8 +246,8 @@ int cmCPackIFWPackage::ConfigureFromComponent(cmCPackComponent* component) } // Priority - if (const char* option = this->GetOption(prefix + "PRIORITY")) { - this->SortingPriority = option; + if (cmValue option = this->GetOption(prefix + "PRIORITY")) { + this->SortingPriority = *option; cmCPackIFWLogger( WARNING, "The \"PRIORITY\" option is set " @@ -289,28 +289,28 @@ int cmCPackIFWPackage::ConfigureFromGroup(cmCPackComponentGroup* group) this->Description[""] = group->Description; // Version - if (const char* optVERSION = this->GetOption(prefix + "VERSION")) { - this->Version = optVERSION; - } else if (const char* optPACKAGE_VERSION = + if (cmValue optVERSION = this->GetOption(prefix + "VERSION")) { + this->Version = *optVERSION; + } else if (cmValue optPACKAGE_VERSION = this->GetOption("CPACK_PACKAGE_VERSION")) { - this->Version = optPACKAGE_VERSION; + this->Version = *optPACKAGE_VERSION; } else { this->Version = "1.0.0"; } // Script - if (const char* option = this->GetOption(prefix + "SCRIPT")) { - this->Script = option; + if (cmValue option = this->GetOption(prefix + "SCRIPT")) { + this->Script = *option; } // User interfaces - if (const char* option = this->GetOption(prefix + "USER_INTERFACES")) { + if (cmValue option = this->GetOption(prefix + "USER_INTERFACES")) { this->UserInterfaces.clear(); cmExpandList(option, this->UserInterfaces); } // Licenses - if (const char* option = this->GetOption(prefix + "LICENSES")) { + if (cmValue option = this->GetOption(prefix + "LICENSES")) { this->Licenses.clear(); cmExpandList(option, this->Licenses); if (this->Licenses.size() % 2 != 0) { @@ -324,8 +324,8 @@ int cmCPackIFWPackage::ConfigureFromGroup(cmCPackComponentGroup* group) } // Priority - if (const char* option = this->GetOption(prefix + "PRIORITY")) { - this->SortingPriority = option; + if (cmValue option = this->GetOption(prefix + "PRIORITY")) { + this->SortingPriority = *option; cmCPackIFWLogger( WARNING, "The \"PRIORITY\" option is set " @@ -346,14 +346,14 @@ int cmCPackIFWPackage::ConfigureFromGroup(const std::string& groupName) std::string prefix = "CPACK_COMPONENT_GROUP_" + cmsys::SystemTools::UpperCase(groupName) + "_"; - if (const char* option = this->GetOption(prefix + "DISPLAY_NAME")) { - group.DisplayName = option; + if (cmValue option = this->GetOption(prefix + "DISPLAY_NAME")) { + group.DisplayName = *option; } else { group.DisplayName = group.Name; } - if (const char* option = this->GetOption(prefix + "DESCRIPTION")) { - group.Description = option; + if (cmValue option = this->GetOption(prefix + "DESCRIPTION")) { + group.Description = *option; } group.IsBold = this->IsOn(prefix + "BOLD_TITLE"); group.IsExpandedByDefault = this->IsOn(prefix + "EXPANDED"); @@ -381,7 +381,7 @@ int cmCPackIFWPackage::ConfigureFromPrefix(const std::string& prefix) option = prefix + "DISPLAY_NAME"; if (this->IsSetToEmpty(option)) { this->DisplayName.clear(); - } else if (const char* value = this->GetOption(option)) { + } else if (cmValue value = this->GetOption(option)) { cmCPackIFWPackage::ExpandListArgument(value, this->DisplayName); } @@ -389,7 +389,7 @@ int cmCPackIFWPackage::ConfigureFromPrefix(const std::string& prefix) option = prefix + "DESCRIPTION"; if (this->IsSetToEmpty(option)) { this->Description.clear(); - } else if (const char* value = this->GetOption(option)) { + } else if (cmValue value = this->GetOption(option)) { cmCPackIFWPackage::ExpandListArgument(value, this->Description); } @@ -397,31 +397,31 @@ int cmCPackIFWPackage::ConfigureFromPrefix(const std::string& prefix) option = prefix + "RELEASE_DATE"; if (this->IsSetToEmpty(option)) { this->ReleaseDate.clear(); - } else if (const char* value = this->GetOption(option)) { - this->ReleaseDate = value; + } else if (cmValue value = this->GetOption(option)) { + this->ReleaseDate = *value; } // Sorting priority option = prefix + "SORTING_PRIORITY"; if (this->IsSetToEmpty(option)) { this->SortingPriority.clear(); - } else if (const char* value = this->GetOption(option)) { - this->SortingPriority = value; + } else if (cmValue value = this->GetOption(option)) { + this->SortingPriority = *value; } // Update text option = prefix + "UPDATE_TEXT"; if (this->IsSetToEmpty(option)) { this->UpdateText.clear(); - } else if (const char* value = this->GetOption(option)) { - this->UpdateText = value; + } else if (cmValue value = this->GetOption(option)) { + this->UpdateText = *value; } // Translations option = prefix + "TRANSLATIONS"; if (this->IsSetToEmpty(option)) { this->Translations.clear(); - } else if (const char* value = this->GetOption(option)) { + } else if (cmValue value = this->GetOption(option)) { this->Translations.clear(); cmExpandList(value, this->Translations); } @@ -429,11 +429,11 @@ int cmCPackIFWPackage::ConfigureFromPrefix(const std::string& prefix) // QtIFW dependencies std::vector<std::string> deps; option = prefix + "DEPENDS"; - if (const char* value = this->GetOption(option)) { + if (cmValue value = this->GetOption(option)) { cmExpandList(value, deps); } option = prefix + "DEPENDENCIES"; - if (const char* value = this->GetOption(option)) { + if (cmValue value = this->GetOption(option)) { cmExpandList(value, deps); } for (std::string const& d : deps) { @@ -454,7 +454,7 @@ int cmCPackIFWPackage::ConfigureFromPrefix(const std::string& prefix) option = prefix + "AUTO_DEPEND_ON"; if (this->IsSetToEmpty(option)) { this->AlienAutoDependOn.clear(); - } else if (const char* value = this->GetOption(option)) { + } else if (cmValue value = this->GetOption(option)) { std::vector<std::string> depsOn = cmExpandedList(value); for (std::string const& d : depsOn) { DependenceStruct dep(d); @@ -483,7 +483,7 @@ int cmCPackIFWPackage::ConfigureFromPrefix(const std::string& prefix) option = prefix + "DEFAULT"; if (this->IsSetToEmpty(option)) { this->Default.clear(); - } else if (const char* value = this->GetOption(option)) { + } else if (cmValue value = this->GetOption(option)) { std::string lowerValue = cmsys::SystemTools::LowerCase(value); if (lowerValue == "true") { this->Default = "true"; @@ -492,7 +492,7 @@ int cmCPackIFWPackage::ConfigureFromPrefix(const std::string& prefix) } else if (lowerValue == "script") { this->Default = "script"; } else { - this->Default = value; + this->Default = *value; } } @@ -510,7 +510,7 @@ int cmCPackIFWPackage::ConfigureFromPrefix(const std::string& prefix) option = prefix + "REPLACES"; if (this->IsSetToEmpty(option)) { this->Replaces.clear(); - } else if (const char* value = this->GetOption(option)) { + } else if (cmValue value = this->GetOption(option)) { this->Replaces.clear(); cmExpandList(value, this->Replaces); } diff --git a/Source/CPack/IFW/cmCPackIFWRepository.cxx b/Source/CPack/IFW/cmCPackIFWRepository.cxx index 7ec225686..f25d2d28c 100644 --- a/Source/CPack/IFW/cmCPackIFWRepository.cxx +++ b/Source/CPack/IFW/cmCPackIFWRepository.cxx @@ -7,6 +7,7 @@ #include "cmCPackIFWGenerator.h" #include "cmGeneratedFileStream.h" #include "cmSystemTools.h" +#include "cmValue.h" #include "cmXMLParser.h" #include "cmXMLWriter.h" @@ -55,22 +56,22 @@ bool cmCPackIFWRepository::ConfigureFromOptions() } // Url - if (const char* url = this->GetOption(prefix + "URL")) { - this->Url = url; + if (cmValue url = this->GetOption(prefix + "URL")) { + this->Url = *url; } else { this->Url.clear(); } // Old url - if (const char* oldUrl = this->GetOption(prefix + "OLD_URL")) { - this->OldUrl = oldUrl; + if (cmValue oldUrl = this->GetOption(prefix + "OLD_URL")) { + this->OldUrl = *oldUrl; } else { this->OldUrl.clear(); } // New url - if (const char* newUrl = this->GetOption(prefix + "NEW_URL")) { - this->NewUrl = newUrl; + if (cmValue newUrl = this->GetOption(prefix + "NEW_URL")) { + this->NewUrl = *newUrl; } else { this->NewUrl.clear(); } @@ -83,22 +84,22 @@ bool cmCPackIFWRepository::ConfigureFromOptions() } // Username - if (const char* username = this->GetOption(prefix + "USERNAME")) { - this->Username = username; + if (cmValue username = this->GetOption(prefix + "USERNAME")) { + this->Username = *username; } else { this->Username.clear(); } // Password - if (const char* password = this->GetOption(prefix + "PASSWORD")) { - this->Password = password; + if (cmValue password = this->GetOption(prefix + "PASSWORD")) { + this->Password = *password; } else { this->Password.clear(); } // DisplayName - if (const char* displayName = this->GetOption(prefix + "DISPLAY_NAME")) { - this->DisplayName = displayName; + if (cmValue displayName = this->GetOption(prefix + "DISPLAY_NAME")) { + this->DisplayName = *displayName; } else { this->DisplayName.clear(); } diff --git a/Source/CPack/OSXScriptLauncher.cxx b/Source/CPack/OSXScriptLauncher.cxx index bdaf779af..b7140abd7 100644 --- a/Source/CPack/OSXScriptLauncher.cxx +++ b/Source/CPack/OSXScriptLauncher.cxx @@ -118,5 +118,5 @@ int main(int argc, char* argv[]) cmsysProcess_Delete(cp); - return 0; + return !result; } diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx index 8b3644f91..d03239b52 100644 --- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx +++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx @@ -21,6 +21,7 @@ #include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmUuid.h" +#include "cmValue.h" #include "cmWIXDirectoriesSourceWriter.h" #include "cmWIXFeaturesSourceWriter.h" #include "cmWIXFilesSourceWriter.h" @@ -125,7 +126,7 @@ bool cmCPackWIXGenerator::RunLightCommand(std::string const& objectFiles) command << " -ext " << QuotePath(ext); } - const char* const cultures = GetOption("CPACK_WIX_CULTURES"); + cmValue const cultures = GetOption("CPACK_WIX_CULTURES"); if (cultures) { command << " -cultures:" << cultures; } @@ -156,18 +157,18 @@ bool cmCPackWIXGenerator::InitializeWiXConfiguration() return false; } - if (GetOption("CPACK_WIX_PRODUCT_GUID") == 0) { + if (!GetOption("CPACK_WIX_PRODUCT_GUID")) { std::string guid = GenerateGUID(); - SetOption("CPACK_WIX_PRODUCT_GUID", guid.c_str()); + SetOption("CPACK_WIX_PRODUCT_GUID", guid); cmCPackLogger(cmCPackLog::LOG_VERBOSE, "CPACK_WIX_PRODUCT_GUID implicitly set to " << guid << " . " << std::endl); } - if (GetOption("CPACK_WIX_UPGRADE_GUID") == 0) { + if (!GetOption("CPACK_WIX_UPGRADE_GUID")) { std::string guid = GenerateGUID(); - SetOption("CPACK_WIX_UPGRADE_GUID", guid.c_str()); + SetOption("CPACK_WIX_UPGRADE_GUID", guid); cmCPackLogger(cmCPackLog::LOG_WARNING, "CPACK_WIX_UPGRADE_GUID implicitly set to " @@ -182,36 +183,36 @@ bool cmCPackWIXGenerator::InitializeWiXConfiguration() return false; } - if (GetOption("CPACK_WIX_LICENSE_RTF") == 0) { + if (!GetOption("CPACK_WIX_LICENSE_RTF")) { std::string licenseFilename = this->CPackTopLevel + "/License.rtf"; - SetOption("CPACK_WIX_LICENSE_RTF", licenseFilename.c_str()); + SetOption("CPACK_WIX_LICENSE_RTF", licenseFilename); if (!CreateLicenseFile()) { return false; } } - if (GetOption("CPACK_PACKAGE_VENDOR") == 0) { + if (!GetOption("CPACK_PACKAGE_VENDOR")) { std::string defaultVendor = "Humanity"; - SetOption("CPACK_PACKAGE_VENDOR", defaultVendor.c_str()); + SetOption("CPACK_PACKAGE_VENDOR", defaultVendor); cmCPackLogger(cmCPackLog::LOG_VERBOSE, "CPACK_PACKAGE_VENDOR implicitly set to " << defaultVendor << " . " << std::endl); } - if (GetOption("CPACK_WIX_UI_REF") == 0) { + if (!GetOption("CPACK_WIX_UI_REF")) { std::string defaultRef = "WixUI_InstallDir"; if (!this->Components.empty()) { defaultRef = "WixUI_FeatureTree"; } - SetOption("CPACK_WIX_UI_REF", defaultRef.c_str()); + SetOption("CPACK_WIX_UI_REF", defaultRef); } - const char* packageContact = GetOption("CPACK_PACKAGE_CONTACT"); - if (packageContact != 0 && GetOption("CPACK_WIX_PROPERTY_ARPCONTACT") == 0) { + cmValue packageContact = GetOption("CPACK_PACKAGE_CONTACT"); + if (packageContact && !GetOption("CPACK_WIX_PROPERTY_ARPCONTACT")) { SetOption("CPACK_WIX_PROPERTY_ARPCONTACT", packageContact); } @@ -223,7 +224,7 @@ bool cmCPackWIXGenerator::InitializeWiXConfiguration() CollectExtensions("CPACK_WIX_LIGHT_EXTENSIONS", this->LightExtensions); CollectXmlNamespaces("CPACK_WIX_CUSTOM_XMLNS", this->CustomXmlNamespaces); - const char* patchFilePath = GetOption("CPACK_WIX_PATCH_FILE"); + cmValue patchFilePath = GetOption("CPACK_WIX_PATCH_FILE"); if (patchFilePath) { std::vector<std::string> patchFilePaths = cmExpandedList(patchFilePath); @@ -295,7 +296,7 @@ bool cmCPackWIXGenerator::PackageFilesImpl() void cmCPackWIXGenerator::AppendUserSuppliedExtraSources() { - const char* cpackWixExtraSources = GetOption("CPACK_WIX_EXTRA_SOURCES"); + cmValue cpackWixExtraSources = GetOption("CPACK_WIX_EXTRA_SOURCES"); if (!cpackWixExtraSources) return; @@ -304,7 +305,7 @@ void cmCPackWIXGenerator::AppendUserSuppliedExtraSources() void cmCPackWIXGenerator::AppendUserSuppliedExtraObjects(std::ostream& stream) { - const char* cpackWixExtraObjects = GetOption("CPACK_WIX_EXTRA_OBJECTS"); + cmValue cpackWixExtraObjects = GetOption("CPACK_WIX_EXTRA_OBJECTS"); if (!cpackWixExtraObjects) return; @@ -355,7 +356,7 @@ void cmCPackWIXGenerator::CreateWiXPropertiesIncludeFile() for (std::string const& name : options) { if (cmHasPrefix(name, prefix)) { std::string id = name.substr(prefix.length()); - std::string value = GetOption(name.c_str()); + std::string value = GetOption(name); includeFile.BeginElement("Property"); includeFile.AddAttribute("Id", id); @@ -364,7 +365,7 @@ void cmCPackWIXGenerator::CreateWiXPropertiesIncludeFile() } } - if (GetOption("CPACK_WIX_PROPERTY_ARPINSTALLLOCATION") == 0) { + if (!GetOption("CPACK_WIX_PROPERTY_ARPINSTALLLOCATION")) { includeFile.BeginElement("Property"); includeFile.AddAttribute("Id", "INSTALL_ROOT"); includeFile.AddAttribute("Secure", "yes"); @@ -405,7 +406,7 @@ void cmCPackWIXGenerator::CopyDefinition(cmWIXSourceWriter& source, std::string const& name, DefinitionType type) { - const char* value = GetOption(name.c_str()); + cmValue value = GetOption(name); if (value) { if (type == DefinitionType::PATH) { AddDefinition(source, name, CMakeToWixPath(value)); @@ -485,17 +486,17 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles() } std::string featureTitle = cpackPackageName; - if (const char* title = GetOption("CPACK_WIX_ROOT_FEATURE_TITLE")) { - featureTitle = title; + if (cmValue title = GetOption("CPACK_WIX_ROOT_FEATURE_TITLE")) { + featureTitle = *title; } featureDefinitions.AddAttribute("Title", featureTitle); - if (const char* desc = GetOption("CPACK_WIX_ROOT_FEATURE_DESCRIPTION")) { + if (cmValue desc = GetOption("CPACK_WIX_ROOT_FEATURE_DESCRIPTION")) { featureDefinitions.AddAttribute("Description", desc); } featureDefinitions.AddAttribute("Level", "1"); this->Patch->ApplyFragment("#PRODUCTFEATURE", featureDefinitions); - const char* package = GetOption("CPACK_WIX_CMAKE_PACKAGE_REGISTRY"); + cmValue package = GetOption("CPACK_WIX_CMAKE_PACKAGE_REGISTRY"); if (package) { featureDefinitions.CreateCMakePackageRegistryEntry( package, GetOption("CPACK_WIX_UPGRADE_GUID")); @@ -540,10 +541,9 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles() } bool emitUninstallShortcut = true; - const char* cpackWixProgramMenuFolder = + cmValue cpackWixProgramMenuFolder = GetOption("CPACK_WIX_PROGRAM_MENU_FOLDER"); - if (cpackWixProgramMenuFolder && - cm::string_view(cpackWixProgramMenuFolder) == ".") { + if (cpackWixProgramMenuFolder && cpackWixProgramMenuFolder == ".") { emitUninstallShortcut = false; } else if (emittedShortcutTypes.find(cmWIXShortcuts::START_MENU) == emittedShortcutTypes.end()) { @@ -595,9 +595,9 @@ std::string cmCPackWIXGenerator::GetRootFolderId() const std::string result = "ProgramFiles<64>Folder"; - const char* rootFolderId = GetOption("CPACK_WIX_ROOT_FOLDER_ID"); + cmValue rootFolderId = GetOption("CPACK_WIX_ROOT_FOLDER_ID"); if (rootFolderId) { - result = rootFolderId; + result = *rootFolderId; } if (GetArchitecture() == "x86") { @@ -612,8 +612,8 @@ std::string cmCPackWIXGenerator::GetRootFolderId() const bool cmCPackWIXGenerator::GenerateMainSourceFileFromTemplate() { std::string wixTemplate = FindTemplate("WIX.template.in"); - if (GetOption("CPACK_WIX_TEMPLATE") != 0) { - wixTemplate = GetOption("CPACK_WIX_TEMPLATE"); + if (cmValue wixtpl = GetOption("CPACK_WIX_TEMPLATE")) { + wixTemplate = *wixtpl; } if (wixTemplate.empty()) { @@ -669,7 +669,7 @@ bool cmCPackWIXGenerator::AddComponentsToFeature( featureDefinitions.AddAttribute("Id", featureId); std::vector<std::string> cpackPackageExecutablesList; - const char* cpackPackageExecutables = GetOption("CPACK_PACKAGE_EXECUTABLES"); + cmValue cpackPackageExecutables = GetOption("CPACK_PACKAGE_EXECUTABLES"); if (cpackPackageExecutables) { cmExpandList(cpackPackageExecutables, cpackPackageExecutablesList); if (cpackPackageExecutablesList.size() % 2 != 0) { @@ -683,8 +683,7 @@ bool cmCPackWIXGenerator::AddComponentsToFeature( } std::vector<std::string> cpackPackageDesktopLinksList; - const char* cpackPackageDesktopLinks = - GetOption("CPACK_CREATE_DESKTOP_LINKS"); + cmValue cpackPackageDesktopLinks = GetOption("CPACK_CREATE_DESKTOP_LINKS"); if (cpackPackageDesktopLinks) { cmExpandList(cpackPackageDesktopLinks, cpackPackageDesktopLinksList); } @@ -743,10 +742,9 @@ bool cmCPackWIXGenerator::CreateShortcutsOfSpecificType( std::string directoryId; switch (type) { case cmWIXShortcuts::START_MENU: { - const char* cpackWixProgramMenuFolder = + cmValue cpackWixProgramMenuFolder = GetOption("CPACK_WIX_PROGRAM_MENU_FOLDER"); - if (cpackWixProgramMenuFolder && - cm::string_view(cpackWixProgramMenuFolder) == ".") { + if (cpackWixProgramMenuFolder && cpackWixProgramMenuFolder == ".") { directoryId = "ProgramMenuFolder"; } else { directoryId = "PROGRAM_MENU_FOLDER"; @@ -805,10 +803,9 @@ bool cmCPackWIXGenerator::CreateShortcutsOfSpecificType( fileDefinitions); if (type == cmWIXShortcuts::START_MENU) { - const char* cpackWixProgramMenuFolder = + cmValue cpackWixProgramMenuFolder = GetOption("CPACK_WIX_PROGRAM_MENU_FOLDER"); - if (cpackWixProgramMenuFolder && - cm::string_view(cpackWixProgramMenuFolder) != ".") { + if (cpackWixProgramMenuFolder && cpackWixProgramMenuFolder != ".") { fileDefinitions.EmitRemoveFolder("CM_REMOVE_PROGRAM_MENU_FOLDER" + idSuffix); } @@ -973,9 +970,9 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitions( bool cmCPackWIXGenerator::RequireOption(std::string const& name, std::string& value) const { - const char* tmp = GetOption(name.c_str()); + cmValue tmp = GetOption(name); if (tmp) { - value = tmp; + value = *tmp; return true; } else { @@ -1146,7 +1143,7 @@ bool cmCPackWIXGenerator::IsLegalIdCharacter(char c) void cmCPackWIXGenerator::CollectExtensions(std::string const& variableName, extension_set_t& extensions) { - const char* variableContent = GetOption(variableName.c_str()); + cmValue variableContent = GetOption(variableName); if (!variableContent) return; @@ -1157,7 +1154,7 @@ void cmCPackWIXGenerator::CollectExtensions(std::string const& variableName, void cmCPackWIXGenerator::CollectXmlNamespaces(std::string const& variableName, xmlns_map_t& namespaces) { - const char* variableContent = GetOption(variableName.c_str()); + cmValue variableContent = GetOption(variableName); if (!variableContent) { return; } @@ -1180,13 +1177,13 @@ void cmCPackWIXGenerator::CollectXmlNamespaces(std::string const& variableName, oss << " xmlns:" << ns.first << "=\"" << cmWIXSourceWriter::EscapeAttributeValue(ns.second) << '"'; } - SetOption("CPACK_WIX_CUSTOM_XMLNS_EXPANDED", oss.str().c_str()); + SetOption("CPACK_WIX_CUSTOM_XMLNS_EXPANDED", oss.str()); } void cmCPackWIXGenerator::AddCustomFlags(std::string const& variableName, std::ostream& stream) { - const char* variableContent = GetOption(variableName.c_str()); + cmValue variableContent = GetOption(variableName); if (!variableContent) return; diff --git a/Source/CPack/cmCPackArchiveGenerator.cxx b/Source/CPack/cmCPackArchiveGenerator.cxx index d9234e666..56e8463c1 100644 --- a/Source/CPack/cmCPackArchiveGenerator.cxx +++ b/Source/CPack/cmCPackArchiveGenerator.cxx @@ -2,7 +2,6 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCPackArchiveGenerator.h" -#include <cstdlib> #include <cstring> #include <map> #include <ostream> @@ -15,6 +14,7 @@ #include "cmGeneratedFileStream.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" #include "cmWorkingDirectory.h" cmCPackGenerator* cmCPackArchiveGenerator::Create7ZGenerator() @@ -77,7 +77,7 @@ std::string cmCPackArchiveGenerator::GetArchiveComponentFileName( if (this->IsSet("CPACK_ARCHIVE_" + componentUpper + "_FILE_NAME")) { packageFileName += - this->GetOption("CPACK_ARCHIVE_" + componentUpper + "_FILE_NAME"); + *this->GetOption("CPACK_ARCHIVE_" + componentUpper + "_FILE_NAME"); } else if (this->IsSet("CPACK_ARCHIVE_FILE_NAME")) { packageFileName += this->GetComponentPackageFileName( this->GetOption("CPACK_ARCHIVE_FILE_NAME"), component, isGroupName); @@ -118,11 +118,11 @@ int cmCPackArchiveGenerator::addOneComponentToArchive( if (this->IsOn("CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY")) { filePrefix = cmStrCat(this->GetOption("CPACK_PACKAGE_FILE_NAME"), '/'); } - const char* installPrefix = - this->GetOption("CPACK_PACKAGING_INSTALL_PREFIX"); - if (installPrefix && installPrefix[0] == '/' && installPrefix[1] != 0) { + cmValue installPrefix = this->GetOption("CPACK_PACKAGING_INSTALL_PREFIX"); + if (installPrefix && installPrefix->size() > 1 && + (*installPrefix)[0] == '/') { // add to file prefix and remove the leading '/' - filePrefix += installPrefix + 1; + filePrefix += installPrefix->substr(1); filePrefix += "/"; } for (std::string const& file : component->Files) { @@ -257,9 +257,9 @@ int cmCPackArchiveGenerator::PackageComponentsAllInOne() this->packageFileNames[0] += "/"; if (this->IsSet("CPACK_ARCHIVE_FILE_NAME")) { - this->packageFileNames[0] += this->GetOption("CPACK_ARCHIVE_FILE_NAME"); + this->packageFileNames[0] += *this->GetOption("CPACK_ARCHIVE_FILE_NAME"); } else { - this->packageFileNames[0] += this->GetOption("CPACK_PACKAGE_FILE_NAME"); + this->packageFileNames[0] += *this->GetOption("CPACK_PACKAGE_FILE_NAME"); } this->packageFileNames[0] += this->GetOutputExtension(); @@ -345,9 +345,9 @@ int cmCPackArchiveGenerator::GetThreadCount() const // CPACK_ARCHIVE_THREADS overrides CPACK_THREADS if (this->IsSet("CPACK_ARCHIVE_THREADS")) { - threads = std::atoi(this->GetOption("CPACK_ARCHIVE_THREADS")); + threads = std::stoi(this->GetOption("CPACK_ARCHIVE_THREADS")); } else if (this->IsSet("CPACK_THREADS")) { - threads = std::atoi(this->GetOption("CPACK_THREADS")); + threads = std::stoi(this->GetOption("CPACK_THREADS")); } return threads; diff --git a/Source/CPack/cmCPackBundleGenerator.cxx b/Source/CPack/cmCPackBundleGenerator.cxx index 4d5f43f9e..b3d425aa5 100644 --- a/Source/CPack/cmCPackBundleGenerator.cxx +++ b/Source/CPack/cmCPackBundleGenerator.cxx @@ -8,6 +8,7 @@ #include "cmCPackLog.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" cmCPackBundleGenerator::cmCPackBundleGenerator() = default; @@ -15,8 +16,8 @@ cmCPackBundleGenerator::~cmCPackBundleGenerator() = default; int cmCPackBundleGenerator::InitializeInternal() { - const char* name = this->GetOption("CPACK_BUNDLE_NAME"); - if (nullptr == name) { + cmValue name = this->GetOption("CPACK_BUNDLE_NAME"); + if (!name) { cmCPackLogger(cmCPackLog::LOG_ERROR, "CPACK_BUNDLE_NAME must be set to use the Bundle generator." << std::endl); @@ -33,7 +34,7 @@ int cmCPackBundleGenerator::InitializeInternal() "Cannot locate codesign command" << std::endl); return 0; } - this->SetOptionIfNotSet("CPACK_COMMAND_CODESIGN", codesign_path.c_str()); + this->SetOptionIfNotSet("CPACK_COMMAND_CODESIGN", codesign_path); } return this->Superclass::InitializeInternal(); @@ -51,30 +52,24 @@ int cmCPackBundleGenerator::ConstructBundle() { // Get required arguments ... - const std::string cpack_bundle_name = this->GetOption("CPACK_BUNDLE_NAME") - ? this->GetOption("CPACK_BUNDLE_NAME") - : ""; - if (cpack_bundle_name.empty()) { + cmValue cpack_bundle_name = this->GetOption("CPACK_BUNDLE_NAME"); + if (cpack_bundle_name->empty()) { cmCPackLogger(cmCPackLog::LOG_ERROR, "CPACK_BUNDLE_NAME must be set." << std::endl); return 0; } - const std::string cpack_bundle_plist = this->GetOption("CPACK_BUNDLE_PLIST") - ? this->GetOption("CPACK_BUNDLE_PLIST") - : ""; - if (cpack_bundle_plist.empty()) { + cmValue cpack_bundle_plist = this->GetOption("CPACK_BUNDLE_PLIST"); + if (cpack_bundle_plist->empty()) { cmCPackLogger(cmCPackLog::LOG_ERROR, "CPACK_BUNDLE_PLIST must be set." << std::endl); return 0; } - const std::string cpack_bundle_icon = this->GetOption("CPACK_BUNDLE_ICON") - ? this->GetOption("CPACK_BUNDLE_ICON") - : ""; - if (cpack_bundle_icon.empty()) { + cmValue cpack_bundle_icon = this->GetOption("CPACK_BUNDLE_ICON"); + if (cpack_bundle_icon->empty()) { cmCPackLogger(cmCPackLog::LOG_ERROR, "CPACK_BUNDLE_ICON must be set." << std::endl); @@ -82,10 +77,8 @@ int cmCPackBundleGenerator::ConstructBundle() } // Get optional arguments ... - const std::string cpack_bundle_startup_command = - this->GetOption("CPACK_BUNDLE_STARTUP_COMMAND") - ? this->GetOption("CPACK_BUNDLE_STARTUP_COMMAND") - : ""; + cmValue cpack_bundle_startup_command = + this->GetOption("CPACK_BUNDLE_STARTUP_COMMAND"); // The staging directory contains everything that will end-up inside the // final disk image ... @@ -138,7 +131,7 @@ int cmCPackBundleGenerator::ConstructBundle() // Optionally a user-provided startup command (could be an // executable or a script) ... - if (!cpack_bundle_startup_command.empty()) { + if (!cpack_bundle_startup_command->empty()) { std::ostringstream command_source; command_source << cpack_bundle_startup_command; @@ -180,13 +173,11 @@ bool cmCPackBundleGenerator::SupportsComponentInstallation() const int cmCPackBundleGenerator::SignBundle(const std::string& src_dir) { - const std::string cpack_apple_cert_app = - this->GetOption("CPACK_BUNDLE_APPLE_CERT_APP") - ? this->GetOption("CPACK_BUNDLE_APPLE_CERT_APP") - : ""; + cmValue cpack_apple_cert_app = + this->GetOption("CPACK_BUNDLE_APPLE_CERT_APP"); // codesign the application. - if (!cpack_apple_cert_app.empty()) { + if (!cpack_apple_cert_app->empty()) { std::string output; std::string bundle_path; bundle_path = @@ -195,13 +186,10 @@ int cmCPackBundleGenerator::SignBundle(const std::string& src_dir) // A list of additional files to sign, ie. frameworks and plugins. const std::string sign_parameter = this->GetOption("CPACK_BUNDLE_APPLE_CODESIGN_PARAMETER") - ? this->GetOption("CPACK_BUNDLE_APPLE_CODESIGN_PARAMETER") + ? *this->GetOption("CPACK_BUNDLE_APPLE_CODESIGN_PARAMETER") : "--deep -f"; - const std::string sign_files = - this->GetOption("CPACK_BUNDLE_APPLE_CODESIGN_FILES") - ? this->GetOption("CPACK_BUNDLE_APPLE_CODESIGN_FILES") - : ""; + cmValue sign_files = this->GetOption("CPACK_BUNDLE_APPLE_CODESIGN_FILES"); std::vector<std::string> relFiles = cmExpandedList(sign_files); diff --git a/Source/CPack/cmCPackCygwinBinaryGenerator.cxx b/Source/CPack/cmCPackCygwinBinaryGenerator.cxx index b5abd5a6b..484db0038 100644 --- a/Source/CPack/cmCPackCygwinBinaryGenerator.cxx +++ b/Source/CPack/cmCPackCygwinBinaryGenerator.cxx @@ -9,6 +9,7 @@ #include "cmGlobalGenerator.h" #include "cmMakefile.h" #include "cmSystemTools.h" +#include "cmValue.h" #include "cmake.h" cmCPackCygwinBinaryGenerator::cmCPackCygwinBinaryGenerator() @@ -59,14 +60,15 @@ int cmCPackCygwinBinaryGenerator::PackageFiles() const char* cmCPackCygwinBinaryGenerator::GetOutputExtension() { this->OutputExtension = "-"; - const char* patchNumber = this->GetOption("CPACK_CYGWIN_PATCH_NUMBER"); + cmValue patchNumber = this->GetOption("CPACK_CYGWIN_PATCH_NUMBER"); if (!patchNumber) { - patchNumber = "1"; + this->OutputExtension += "1"; cmCPackLogger(cmCPackLog::LOG_WARNING, "CPACK_CYGWIN_PATCH_NUMBER not specified using 1" << std::endl); + } else { + this->OutputExtension += patchNumber; } - this->OutputExtension += patchNumber; this->OutputExtension += ".tar.bz2"; return this->OutputExtension.c_str(); } diff --git a/Source/CPack/cmCPackCygwinSourceGenerator.cxx b/Source/CPack/cmCPackCygwinSourceGenerator.cxx index 64a88eba4..59df380c5 100644 --- a/Source/CPack/cmCPackCygwinSourceGenerator.cxx +++ b/Source/CPack/cmCPackCygwinSourceGenerator.cxx @@ -9,6 +9,7 @@ #include "cmGlobalGenerator.h" #include "cmMakefile.h" #include "cmSystemTools.h" +#include "cmValue.h" #include "cmake.h" // Includes needed for implementation of RenameFile. This is not in @@ -94,14 +95,15 @@ int cmCPackCygwinSourceGenerator::PackageFiles() } std::string outerTarFile = cmStrCat(this->GetOption("CPACK_TEMPORARY_DIRECTORY"), '-'); - const char* patch = this->GetOption("CPACK_CYGWIN_PATCH_NUMBER"); + cmValue patch = this->GetOption("CPACK_CYGWIN_PATCH_NUMBER"); if (!patch) { cmCPackLogger(cmCPackLog::LOG_WARNING, "CPACK_CYGWIN_PATCH_NUMBER" << " not specified, defaulting to 1\n"); - patch = "1"; + outerTarFile += "1"; + } else { + outerTarFile += patch; } - outerTarFile += patch; outerTarFile += "-src.tar.bz2"; std::string tmpDir = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); std::string buildScript = @@ -145,14 +147,15 @@ const char* cmCPackCygwinSourceGenerator::GetPackagingInstallPrefix() const char* cmCPackCygwinSourceGenerator::GetOutputExtension() { this->OutputExtension = "-"; - const char* patch = this->GetOption("CPACK_CYGWIN_PATCH_NUMBER"); + cmValue patch = this->GetOption("CPACK_CYGWIN_PATCH_NUMBER"); if (!patch) { cmCPackLogger(cmCPackLog::LOG_WARNING, "CPACK_CYGWIN_PATCH_NUMBER" << " not specified, defaulting to 1\n"); - patch = "1"; + this->OutputExtension += "1"; + } else { + this->OutputExtension += patch; } - this->OutputExtension += patch; this->OutputExtension += "-src.tar.bz2"; return this->OutputExtension.c_str(); } diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx index a1ebbdfb9..d7aa28717 100644 --- a/Source/CPack/cmCPackDebGenerator.cxx +++ b/Source/CPack/cmCPackDebGenerator.cxx @@ -2,11 +2,12 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCPackDebGenerator.h" -#include <cstdlib> +#include <algorithm> #include <cstring> #include <map> #include <ostream> #include <set> +#include <stdexcept> #include <utility> #include "cmsys/Glob.hxx" @@ -21,6 +22,7 @@ #include "cmGeneratedFileStream.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" namespace { @@ -29,12 +31,12 @@ class DebGenerator public: DebGenerator(cmCPackLog* logger, std::string outputName, std::string workDir, std::string topLevelDir, std::string temporaryDir, - const char* debianCompressionType, const char* numThreads, - const char* debianArchiveType, + cmValue debianCompressionType, cmValue numThreads, + cmValue debianArchiveType, std::map<std::string, std::string> controlValues, bool genShLibs, std::string shLibsFilename, bool genPostInst, std::string postInst, bool genPostRm, std::string postRm, - const char* controlExtra, bool permissionStrctPolicy, + cmValue controlExtra, bool permissionStrctPolicy, std::vector<std::string> packageFiles); bool generate() const; @@ -53,8 +55,8 @@ private: std::string CompressionSuffix; const std::string TopLevelDir; const std::string TemporaryDir; - const char* DebianArchiveType; - int NumThreads; + const std::string DebianArchiveType; + long NumThreads; const std::map<std::string, std::string> ControlValues; const bool GenShLibs; const std::string ShLibsFilename; @@ -62,7 +64,7 @@ private: const std::string PostInst; const bool GenPostRm; const std::string PostRm; - const char* ControlExtra; + cmValue ControlExtra; const bool PermissionStrictPolicy; const std::vector<std::string> PackageFiles; cmArchiveWrite::Compress TarCompressionType; @@ -71,18 +73,17 @@ private: DebGenerator::DebGenerator( cmCPackLog* logger, std::string outputName, std::string workDir, std::string topLevelDir, std::string temporaryDir, - const char* debianCompressionType, const char* numThreads, - const char* debianArchiveType, + cmValue debCompressionType, cmValue numThreads, cmValue debianArchiveType, std::map<std::string, std::string> controlValues, bool genShLibs, std::string shLibsFilename, bool genPostInst, std::string postInst, - bool genPostRm, std::string postRm, const char* controlExtra, + bool genPostRm, std::string postRm, cmValue controlExtra, bool permissionStrictPolicy, std::vector<std::string> packageFiles) : Logger(logger) , OutputName(std::move(outputName)) , WorkDir(std::move(workDir)) , TopLevelDir(std::move(topLevelDir)) , TemporaryDir(std::move(temporaryDir)) - , DebianArchiveType(debianArchiveType ? debianArchiveType : "gnutar") + , DebianArchiveType(debianArchiveType ? *debianArchiveType : "gnutar") , ControlValues(std::move(controlValues)) , GenShLibs(genShLibs) , ShLibsFilename(std::move(shLibsFilename)) @@ -94,23 +95,27 @@ DebGenerator::DebGenerator( , PermissionStrictPolicy(permissionStrictPolicy) , PackageFiles(std::move(packageFiles)) { - if (!debianCompressionType) { - debianCompressionType = "gzip"; + std::string debianCompressionType = "gzip"; + if (debCompressionType) { + debianCompressionType = *debCompressionType; } - if (!strcmp(debianCompressionType, "lzma")) { + if (debianCompressionType == "lzma") { this->CompressionSuffix = ".lzma"; this->TarCompressionType = cmArchiveWrite::CompressLZMA; - } else if (!strcmp(debianCompressionType, "xz")) { + } else if (debianCompressionType == "xz") { this->CompressionSuffix = ".xz"; this->TarCompressionType = cmArchiveWrite::CompressXZ; - } else if (!strcmp(debianCompressionType, "bzip2")) { + } else if (debianCompressionType == "bzip2") { this->CompressionSuffix = ".bz2"; this->TarCompressionType = cmArchiveWrite::CompressBZip2; - } else if (!strcmp(debianCompressionType, "gzip")) { + } else if (debianCompressionType == "gzip") { this->CompressionSuffix = ".gz"; this->TarCompressionType = cmArchiveWrite::CompressGZip; - } else if (!strcmp(debianCompressionType, "none")) { + } else if (debianCompressionType == "zstd") { + this->CompressionSuffix = ".zst"; + this->TarCompressionType = cmArchiveWrite::CompressZstd; + } else if (debianCompressionType == "none") { this->CompressionSuffix.clear(); this->TarCompressionType = cmArchiveWrite::CompressNone; } else { @@ -119,16 +124,15 @@ DebGenerator::DebGenerator( << debianCompressionType << std::endl); } - if (numThreads == nullptr) { - numThreads = "1"; - } - - char* endptr; - this->NumThreads = static_cast<int>(strtol(numThreads, &endptr, 10)); - if (numThreads != endptr && *endptr != '\0') { - cmCPackLogger(cmCPackLog::LOG_ERROR, - "Unrecognized number of threads: " << numThreads - << std::endl); + if (numThreads != nullptr) { + if (!cmStrToLong(numThreads, &this->NumThreads)) { + this->NumThreads = 1; + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Unrecognized number of threads: " << numThreads + << std::endl); + } + } else { + this->NumThreads = 1; } } @@ -187,8 +191,15 @@ bool DebGenerator::generateDataTar() const return false; } cmArchiveWrite data_tar(fileStream_data_tar, this->TarCompressionType, - this->DebianArchiveType, 0, this->NumThreads); - data_tar.Open(); + this->DebianArchiveType, 0, + static_cast<int>(this->NumThreads)); + if (!data_tar.Open()) { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Error opening the archive \"" + << filename_data_tar + << "\", ERROR = " << data_tar.GetError() << std::endl); + return false; + } // uid/gid should be the one of the root user, and this root user has // always uid/gid equal to 0. @@ -248,11 +259,15 @@ bool DebGenerator::generateDataTar() const // do not recurse because the loop will do it if (!data_tar.Add(file, topLevelLength, ".", false)) { cmCPackLogger(cmCPackLog::LOG_ERROR, - "Problem adding file to tar:" - << std::endl - << "#top level directory: " << this->WorkDir << std::endl - << "#file: " << file << std::endl - << "#error:" << data_tar.GetError() << std::endl); + "Problem adding file to tar:\n" + "#top level directory: " + << this->WorkDir + << "\n" + "#file: " + << file + << "\n" + "#error:" + << data_tar.GetError() << std::endl); return false; } } @@ -309,7 +324,13 @@ bool DebGenerator::generateControlTar(std::string const& md5Filename) const cmArchiveWrite control_tar(fileStream_control_tar, cmArchiveWrite::CompressGZip, this->DebianArchiveType); - control_tar.Open(); + if (!control_tar.Open()) { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Error opening the archive \"" + << filename_control_tar + << "\", ERROR = " << control_tar.GetError() << std::endl); + return false; + } // sets permissions and uid/gid for the files control_tar.SetUIDAndGID(0u, 0u); @@ -334,11 +355,13 @@ bool DebGenerator::generateControlTar(std::string const& md5Filename) const !control_tar.Add(this->WorkDir + "/control", this->WorkDir.length(), ".")) { cmCPackLogger(cmCPackLog::LOG_ERROR, - "Error adding file to tar:" - << std::endl - << "#top level directory: " << this->WorkDir << std::endl - << "#file: \"control\" or \"md5sums\"" << std::endl - << "#error:" << control_tar.GetError() << std::endl); + "Error adding file to tar:\n" + "#top level directory: " + << this->WorkDir + << "\n" + "#file: \"control\" or \"md5sums\"\n" + "#error:" + << control_tar.GetError() << std::endl); return false; } @@ -346,11 +369,13 @@ bool DebGenerator::generateControlTar(std::string const& md5Filename) const if (this->GenShLibs) { if (!control_tar.Add(this->ShLibsFilename, this->WorkDir.length(), ".")) { cmCPackLogger(cmCPackLog::LOG_ERROR, - "Error adding file to tar:" - << std::endl - << "#top level directory: " << this->WorkDir << std::endl - << "#file: \"shlibs\"" << std::endl - << "#error:" << control_tar.GetError() << std::endl); + "Error adding file to tar:\n" + "#top level directory: " + << this->WorkDir + << "\n" + "#file: \"shlibs\"\n" + "#error:" + << control_tar.GetError() << std::endl); return false; } } @@ -360,11 +385,13 @@ bool DebGenerator::generateControlTar(std::string const& md5Filename) const control_tar.SetPermissions(permission755); if (!control_tar.Add(this->PostInst, this->WorkDir.length(), ".")) { cmCPackLogger(cmCPackLog::LOG_ERROR, - "Error adding file to tar:" - << std::endl - << "#top level directory: " << this->WorkDir << std::endl - << "#file: \"postinst\"" << std::endl - << "#error:" << control_tar.GetError() << std::endl); + "Error adding file to tar:\n" + "#top level directory: " + << this->WorkDir + << "\n" + "#file: \"postinst\"\n" + "#error:" + << control_tar.GetError() << std::endl); return false; } control_tar.SetPermissions(permission644); @@ -374,11 +401,13 @@ bool DebGenerator::generateControlTar(std::string const& md5Filename) const control_tar.SetPermissions(permission755); if (!control_tar.Add(this->PostRm, this->WorkDir.length(), ".")) { cmCPackLogger(cmCPackLog::LOG_ERROR, - "Error adding file to tar:" - << std::endl - << "#top level directory: " << this->WorkDir << std::endl - << "#file: \"postinst\"" << std::endl - << "#error:" << control_tar.GetError() << std::endl); + "Error adding file to tar:\n" + "#top level directory: " + << this->WorkDir + << "\n" + "#file: \"postinst\"\n" + "#error:" + << control_tar.GetError() << std::endl); return false; } control_tar.SetPermissions(permission644); @@ -412,11 +441,12 @@ bool DebGenerator::generateControlTar(std::string const& md5Filename) const // if we can copy the file, it means it does exist, let's add it: if (!cmsys::SystemTools::FileExists(i)) { cmCPackLogger(cmCPackLog::LOG_WARNING, - "Adding file to tar:" << std::endl - << "#top level directory: " - << this->WorkDir << std::endl - << "#missing file: " << i - << std::endl); + "Adding file to tar:\n" + "#top level directory: " + << this->WorkDir + << "\n" + "#missing file: " + << i << std::endl); } if (cmsys::SystemTools::CopyFileIfDifferent(i, localcopy)) { @@ -440,7 +470,13 @@ bool DebGenerator::generateDeb() const cmGeneratedFileStream debStream; debStream.Open(outputPath, false, true); cmArchiveWrite deb(debStream, cmArchiveWrite::CompressNone, "arbsd"); - deb.Open(); + if (!deb.Open()) { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Error opening the archive \"" + << outputPath << "\", ERROR = " << deb.GetError() + << std::endl); + return false; + } // uid/gid should be the one of the root user, and this root user has // always uid/gid equal to 0. @@ -451,17 +487,37 @@ bool DebGenerator::generateDeb() const !deb.Add(tlDir + "control.tar.gz", tlDir.length()) || !deb.Add(tlDir + "data.tar" + this->CompressionSuffix, tlDir.length())) { cmCPackLogger(cmCPackLog::LOG_ERROR, - "Error creating debian package:" - << std::endl - << "#top level directory: " << this->TopLevelDir - << std::endl - << "#file: " << this->OutputName << std::endl - << "#error:" << deb.GetError() << std::endl); + "Error creating debian package:\n" + "#top level directory: " + << this->TopLevelDir + << "\n" + "#file: " + << this->OutputName + << "\n" + "#error:" + << deb.GetError() << std::endl); return false; } return true; } +std::vector<std::string> findFilesIn(const std::string& path) +{ + cmsys::Glob gl; + std::string findExpr = path + "/*"; + gl.RecurseOn(); + gl.SetRecurseListDirs(true); + gl.SetRecurseThroughSymlinks(false); + if (!gl.FindFiles(findExpr)) { + throw std::runtime_error( + "Cannot find any files in the installed directory"); + } + std::vector<std::string> files{ gl.GetFiles() }; + // Sort files so that they have a reproducible order + std::sort(files.begin(), files.end()); + return files; +} + } // end anonymous namespace cmCPackDebGenerator::cmCPackDebGenerator() = default; @@ -480,128 +536,71 @@ int cmCPackDebGenerator::InitializeInternal() int cmCPackDebGenerator::PackageOnePack(std::string const& initialTopLevel, std::string const& packageName) { - int retval = 1; // Begin the archive for this pack std::string localToplevel(initialTopLevel); std::string packageFileName( cmSystemTools::GetParentDirectory(this->toplevel)); - std::string outputFileName( - std::string(this->GetOption("CPACK_PACKAGE_FILE_NAME")) + "-" + - packageName + this->GetOutputExtension()); + std::string outputFileName(*this->GetOption("CPACK_PACKAGE_FILE_NAME") + + "-" + packageName + this->GetOutputExtension()); localToplevel += "/" + packageName; /* replace the TEMP DIRECTORY with the component one */ - this->SetOption("CPACK_TEMPORARY_DIRECTORY", localToplevel.c_str()); + this->SetOption("CPACK_TEMPORARY_DIRECTORY", localToplevel); packageFileName += "/" + outputFileName; /* replace proposed CPACK_OUTPUT_FILE_NAME */ - this->SetOption("CPACK_OUTPUT_FILE_NAME", outputFileName.c_str()); + this->SetOption("CPACK_OUTPUT_FILE_NAME", outputFileName); /* replace the TEMPORARY package file name */ - this->SetOption("CPACK_TEMPORARY_PACKAGE_FILE_NAME", - packageFileName.c_str()); + this->SetOption("CPACK_TEMPORARY_PACKAGE_FILE_NAME", packageFileName); // Tell CPackDeb.cmake the name of the component GROUP. - this->SetOption("CPACK_DEB_PACKAGE_COMPONENT", packageName.c_str()); + this->SetOption("CPACK_DEB_PACKAGE_COMPONENT", packageName); // Tell CPackDeb.cmake the path where the component is. std::string component_path = cmStrCat('/', packageName); - this->SetOption("CPACK_DEB_PACKAGE_COMPONENT_PART_PATH", - component_path.c_str()); + this->SetOption("CPACK_DEB_PACKAGE_COMPONENT_PART_PATH", component_path); if (!this->ReadListFile("Internal/CPack/CPackDeb.cmake")) { cmCPackLogger(cmCPackLog::LOG_ERROR, "Error while execution CPackDeb.cmake" << std::endl); - retval = 0; - return retval; - } - - { // Isolate globbing of binaries vs. dbgsyms - cmsys::Glob gl; - std::string findExpr(this->GetOption("GEN_WDIR")); - findExpr += "/*"; - gl.RecurseOn(); - gl.SetRecurseListDirs(true); - gl.SetRecurseThroughSymlinks(false); - if (!gl.FindFiles(findExpr)) { - cmCPackLogger(cmCPackLog::LOG_ERROR, - "Cannot find any files in the installed directory" - << std::endl); - return 0; - } - this->packageFiles = gl.GetFiles(); - } - - int res = this->createDeb(); - if (res != 1) { - retval = 0; - } - // add the generated package to package file names list - packageFileName = cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), '/', - this->GetOption("GEN_CPACK_OUTPUT_FILE_NAME")); - this->packageFileNames.push_back(std::move(packageFileName)); - - if (this->IsOn("GEN_CPACK_DEBIAN_DEBUGINFO_PACKAGE") && - this->GetOption("GEN_DBGSYMDIR")) { - cmsys::Glob gl; - std::string findExpr(this->GetOption("GEN_DBGSYMDIR")); - findExpr += "/*"; - gl.RecurseOn(); - gl.SetRecurseListDirs(true); - gl.SetRecurseThroughSymlinks(false); - if (!gl.FindFiles(findExpr)) { - cmCPackLogger(cmCPackLog::LOG_ERROR, - "Cannot find any files in the installed directory" - << std::endl); - return 0; - } - this->packageFiles = gl.GetFiles(); - - res = this->createDbgsymDDeb(); - if (res != 1) { - retval = 0; - } - // add the generated package to package file names list - packageFileName = - cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), '/', - this->GetOption("GEN_CPACK_DBGSYM_OUTPUT_FILE_NAME")); - this->packageFileNames.push_back(std::move(packageFileName)); + return 0; } - return retval; + return this->createDebPackages(); } int cmCPackDebGenerator::PackageComponents(bool ignoreGroup) { - int retval = 1; - /* Reset package file name list it will be populated during the - * component packaging run*/ + // Reset package file name list it will be populated during the + // component packaging run this->packageFileNames.clear(); std::string initialTopLevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY")); + int retval = 1; // The default behavior is to have one package by component group // unless CPACK_COMPONENTS_IGNORE_GROUP is specified. - if (!ignoreGroup) { - for (auto const& compG : this->ComponentGroups) { - cmCPackLogger(cmCPackLog::LOG_VERBOSE, - "Packaging component group: " << compG.first << std::endl); - // Begin the archive for this group - retval &= this->PackageOnePack(initialTopLevel, compG.first); - } - // Handle Orphan components (components not belonging to any groups) + if (ignoreGroup) { + // CPACK_COMPONENTS_IGNORE_GROUPS is set + // We build 1 package per component for (auto const& comp : this->Components) { - // Does the component belong to a group? - if (comp.second.Group == nullptr) { - cmCPackLogger( - cmCPackLog::LOG_VERBOSE, - "Component <" - << comp.second.Name - << "> does not belong to any group, package it separately." - << std::endl); - // Begin the archive for this orphan component - retval &= this->PackageOnePack(initialTopLevel, comp.first); - } + retval &= this->PackageOnePack(initialTopLevel, comp.first); } + return retval; } - // CPACK_COMPONENTS_IGNORE_GROUPS is set - // We build 1 package per component - else { - for (auto const& comp : this->Components) { + + for (auto const& compG : this->ComponentGroups) { + cmCPackLogger(cmCPackLog::LOG_VERBOSE, + "Packaging component group: " << compG.first << std::endl); + // Begin the archive for this group + retval &= this->PackageOnePack(initialTopLevel, compG.first); + } + // Handle Orphan components (components not belonging to any groups) + for (auto const& comp : this->Components) { + // Does the component belong to a group? + if (comp.second.Group == nullptr) { + cmCPackLogger( + cmCPackLog::LOG_VERBOSE, + "Component <" + << comp.second.Name + << "> does not belong to any group, package it separately." + << std::endl); + // Begin the archive for this orphan component retval &= this->PackageOnePack(initialTopLevel, comp.first); } } @@ -612,7 +611,6 @@ int cmCPackDebGenerator::PackageComponents(bool ignoreGroup) int cmCPackDebGenerator::PackageComponentsAllInOne( const std::string& compInstDirName) { - int retval = 1; /* Reset package file name list it will be populated during the * component packaging run*/ this->packageFileNames.clear(); @@ -627,9 +625,8 @@ int cmCPackDebGenerator::PackageComponentsAllInOne( std::string localToplevel(initialTopLevel); std::string packageFileName( cmSystemTools::GetParentDirectory(this->toplevel)); - std::string outputFileName( - std::string(this->GetOption("CPACK_PACKAGE_FILE_NAME")) + - this->GetOutputExtension()); + std::string outputFileName(*this->GetOption("CPACK_PACKAGE_FILE_NAME") + + this->GetOutputExtension()); // all GROUP in one vs all COMPONENT in one // if must be here otherwise non component paths have a trailing / while // components don't @@ -638,50 +635,25 @@ int cmCPackDebGenerator::PackageComponentsAllInOne( } /* replace the TEMP DIRECTORY with the component one */ - this->SetOption("CPACK_TEMPORARY_DIRECTORY", localToplevel.c_str()); + this->SetOption("CPACK_TEMPORARY_DIRECTORY", localToplevel); packageFileName += "/" + outputFileName; /* replace proposed CPACK_OUTPUT_FILE_NAME */ - this->SetOption("CPACK_OUTPUT_FILE_NAME", outputFileName.c_str()); + this->SetOption("CPACK_OUTPUT_FILE_NAME", outputFileName); /* replace the TEMPORARY package file name */ - this->SetOption("CPACK_TEMPORARY_PACKAGE_FILE_NAME", - packageFileName.c_str()); + this->SetOption("CPACK_TEMPORARY_PACKAGE_FILE_NAME", packageFileName); if (!compInstDirName.empty()) { // Tell CPackDeb.cmake the path where the component is. std::string component_path = cmStrCat('/', compInstDirName); - this->SetOption("CPACK_DEB_PACKAGE_COMPONENT_PART_PATH", - component_path.c_str()); + this->SetOption("CPACK_DEB_PACKAGE_COMPONENT_PART_PATH", component_path); } if (!this->ReadListFile("Internal/CPack/CPackDeb.cmake")) { cmCPackLogger(cmCPackLog::LOG_ERROR, "Error while execution CPackDeb.cmake" << std::endl); - retval = 0; - return retval; - } - - cmsys::Glob gl; - std::string findExpr(this->GetOption("GEN_WDIR")); - findExpr += "/*"; - gl.RecurseOn(); - gl.SetRecurseListDirs(true); - gl.SetRecurseThroughSymlinks(false); - if (!gl.FindFiles(findExpr)) { - cmCPackLogger(cmCPackLog::LOG_ERROR, - "Cannot find any files in the installed directory" - << std::endl); return 0; } - this->packageFiles = gl.GetFiles(); - int res = this->createDeb(); - if (res != 1) { - retval = 0; - } - // add the generated package to package file names list - packageFileName = cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), '/', - this->GetOption("GEN_CPACK_OUTPUT_FILE_NAME")); - this->packageFileNames.push_back(std::move(packageFileName)); - return retval; + return this->createDebPackages(); } int cmCPackDebGenerator::PackageFiles() @@ -705,7 +677,40 @@ int cmCPackDebGenerator::PackageFiles() return this->PackageComponentsAllInOne(""); } -int cmCPackDebGenerator::createDeb() +bool cmCPackDebGenerator::createDebPackages() +{ + auto make_package = [this](const std::string& path, + const char* const output_var, + bool (cmCPackDebGenerator::*creator)()) -> bool { + try { + this->packageFiles = findFilesIn(path); + } catch (const std::runtime_error& ex) { + cmCPackLogger(cmCPackLog::LOG_ERROR, ex.what() << std::endl); + return false; + } + + if ((this->*creator)()) { + // add the generated package to package file names list + this->packageFileNames.emplace_back( + cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), '/', + this->GetOption(output_var))); + return true; + } + return false; + }; + bool retval = + make_package(this->GetOption("GEN_WDIR"), "GEN_CPACK_OUTPUT_FILE_NAME", + &cmCPackDebGenerator::createDeb); + cmValue dbgsymdir_path = this->GetOption("GEN_DBGSYMDIR"); + if (this->IsOn("GEN_CPACK_DEBIAN_DEBUGINFO_PACKAGE") && dbgsymdir_path) { + retval = make_package(dbgsymdir_path, "GEN_CPACK_DBGSYM_OUTPUT_FILE_NAME", + &cmCPackDebGenerator::createDbgsymDDeb) && + retval; + } + return int(retval); +} + +bool cmCPackDebGenerator::createDeb() { std::map<std::string, std::string> controlValues; @@ -713,78 +718,77 @@ int cmCPackDebGenerator::createDeb() controlValues["Package"] = cmsys::SystemTools::LowerCase( this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_NAME")); controlValues["Version"] = - this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_VERSION"); + *this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_VERSION"); controlValues["Section"] = - this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_SECTION"); + *this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_SECTION"); controlValues["Priority"] = - this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_PRIORITY"); + *this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_PRIORITY"); controlValues["Architecture"] = - this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_ARCHITECTURE"); + *this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_ARCHITECTURE"); controlValues["Maintainer"] = - this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_MAINTAINER"); + *this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_MAINTAINER"); controlValues["Description"] = - this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_DESCRIPTION"); + *this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_DESCRIPTION"); - const char* debian_pkg_source = + cmValue debian_pkg_source = this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_SOURCE"); if (cmNonempty(debian_pkg_source)) { - controlValues["Source"] = debian_pkg_source; + controlValues["Source"] = *debian_pkg_source; } - const char* debian_pkg_dep = - this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_DEPENDS"); + cmValue debian_pkg_dep = this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_DEPENDS"); if (cmNonempty(debian_pkg_dep)) { - controlValues["Depends"] = debian_pkg_dep; + controlValues["Depends"] = *debian_pkg_dep; } - const char* debian_pkg_rec = + cmValue debian_pkg_rec = this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_RECOMMENDS"); if (cmNonempty(debian_pkg_rec)) { - controlValues["Recommends"] = debian_pkg_rec; + controlValues["Recommends"] = *debian_pkg_rec; } - const char* debian_pkg_sug = + cmValue debian_pkg_sug = this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_SUGGESTS"); if (cmNonempty(debian_pkg_sug)) { - controlValues["Suggests"] = debian_pkg_sug; + controlValues["Suggests"] = *debian_pkg_sug; } - const char* debian_pkg_url = + cmValue debian_pkg_url = this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_HOMEPAGE"); if (cmNonempty(debian_pkg_url)) { - controlValues["Homepage"] = debian_pkg_url; + controlValues["Homepage"] = *debian_pkg_url; } - const char* debian_pkg_predep = + cmValue debian_pkg_predep = this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_PREDEPENDS"); if (cmNonempty(debian_pkg_predep)) { - controlValues["Pre-Depends"] = debian_pkg_predep; + controlValues["Pre-Depends"] = *debian_pkg_predep; } - const char* debian_pkg_enhances = + cmValue debian_pkg_enhances = this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_ENHANCES"); if (cmNonempty(debian_pkg_enhances)) { - controlValues["Enhances"] = debian_pkg_enhances; + controlValues["Enhances"] = *debian_pkg_enhances; } - const char* debian_pkg_breaks = + cmValue debian_pkg_breaks = this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_BREAKS"); if (cmNonempty(debian_pkg_breaks)) { - controlValues["Breaks"] = debian_pkg_breaks; + controlValues["Breaks"] = *debian_pkg_breaks; } - const char* debian_pkg_conflicts = + cmValue debian_pkg_conflicts = this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_CONFLICTS"); if (cmNonempty(debian_pkg_conflicts)) { - controlValues["Conflicts"] = debian_pkg_conflicts; + controlValues["Conflicts"] = *debian_pkg_conflicts; } - const char* debian_pkg_provides = + cmValue debian_pkg_provides = this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_PROVIDES"); if (cmNonempty(debian_pkg_provides)) { - controlValues["Provides"] = debian_pkg_provides; + controlValues["Provides"] = *debian_pkg_provides; } - const char* debian_pkg_replaces = + cmValue debian_pkg_replaces = this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_REPLACES"); if (cmNonempty(debian_pkg_replaces)) { - controlValues["Replaces"] = debian_pkg_replaces; + controlValues["Replaces"] = *debian_pkg_replaces; } const std::string strGenWDIR(this->GetOption("GEN_WDIR")); const std::string shlibsfilename = strGenWDIR + "/shlibs"; - const char* debian_pkg_shlibs = + cmValue debian_pkg_shlibs = this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_SHLIBS"); const bool gen_shibs = this->IsOn("CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS") && cmNonempty(debian_pkg_shlibs); @@ -829,13 +833,10 @@ int cmCPackDebGenerator::createDeb() this->IsSet("GEN_CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION"), this->packageFiles); - if (!gen.generate()) { - return 0; - } - return 1; + return gen.generate(); } -int cmCPackDebGenerator::createDbgsymDDeb() +bool cmCPackDebGenerator::createDbgsymDDeb() { // Packages containing debug symbols follow the same structure as .debs // but have different metadata and content. @@ -844,38 +845,38 @@ int cmCPackDebGenerator::createDbgsymDDeb() // debian policy enforce lower case for package name std::string packageNameLower = cmsys::SystemTools::LowerCase( this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_NAME")); - const char* debian_pkg_version = + cmValue debian_pkg_version = this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_VERSION"); controlValues["Package"] = packageNameLower + "-dbgsym"; controlValues["Package-Type"] = "ddeb"; - controlValues["Version"] = debian_pkg_version; + controlValues["Version"] = *debian_pkg_version; controlValues["Auto-Built-Package"] = "debug-symbols"; - controlValues["Depends"] = this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_NAME") + - std::string(" (= ") + debian_pkg_version + ")"; + controlValues["Depends"] = + *this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_NAME") + std::string(" (= ") + + *debian_pkg_version + ")"; controlValues["Section"] = "debug"; controlValues["Priority"] = "optional"; controlValues["Architecture"] = - this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_ARCHITECTURE"); + *this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_ARCHITECTURE"); controlValues["Maintainer"] = - this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_MAINTAINER"); + *this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_MAINTAINER"); controlValues["Description"] = std::string("debug symbols for ") + packageNameLower; - const char* debian_pkg_source = + cmValue debian_pkg_source = this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_SOURCE"); if (cmNonempty(debian_pkg_source)) { - controlValues["Source"] = debian_pkg_source; + controlValues["Source"] = *debian_pkg_source; } - const char* debian_build_ids = this->GetOption("GEN_BUILD_IDS"); + cmValue debian_build_ids = this->GetOption("GEN_BUILD_IDS"); if (cmNonempty(debian_build_ids)) { - controlValues["Build-Ids"] = debian_build_ids; + controlValues["Build-Ids"] = *debian_build_ids; } DebGenerator gen( this->Logger, this->GetOption("GEN_CPACK_DBGSYM_OUTPUT_FILE_NAME"), this->GetOption("GEN_DBGSYMDIR"), - this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), this->GetOption("CPACK_TEMPORARY_DIRECTORY"), this->GetOption("GEN_CPACK_DEBIAN_COMPRESSION_TYPE"), @@ -885,10 +886,7 @@ int cmCPackDebGenerator::createDbgsymDDeb() this->IsSet("GEN_CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION"), this->packageFiles); - if (!gen.generate()) { - return 0; - } - return 1; + return gen.generate(); } bool cmCPackDebGenerator::SupportsComponentInstallation() const @@ -911,7 +909,7 @@ std::string cmCPackDebGenerator::GetComponentInstallDirNameSuffix( std::string groupVar = "CPACK_COMPONENT_" + cmSystemTools::UpperCase(componentName) + "_GROUP"; if (nullptr != this->GetOption(groupVar)) { - return std::string(this->GetOption(groupVar)); + return *this->GetOption(groupVar); } return componentName; } diff --git a/Source/CPack/cmCPackDebGenerator.h b/Source/CPack/cmCPackDebGenerator.h index ee8f39af6..61a6616d3 100644 --- a/Source/CPack/cmCPackDebGenerator.h +++ b/Source/CPack/cmCPackDebGenerator.h @@ -63,8 +63,9 @@ protected: const std::string& componentName) override; private: - int createDeb(); - int createDbgsymDDeb(); + bool createDebPackages(); + bool createDeb(); + bool createDbgsymDDeb(); std::vector<std::string> packageFiles; }; diff --git a/Source/CPack/cmCPackDragNDropGenerator.cxx b/Source/CPack/cmCPackDragNDropGenerator.cxx index b71c96982..9385a5a3e 100644 --- a/Source/CPack/cmCPackDragNDropGenerator.cxx +++ b/Source/CPack/cmCPackDragNDropGenerator.cxx @@ -20,6 +20,7 @@ #include "cmGeneratedFileStream.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" #include "cmXMLWriter.h" #ifdef HAVE_CoreServices @@ -76,7 +77,7 @@ int cmCPackDragNDropGenerator::InitializeInternal() "Cannot locate hdiutil command" << std::endl); return 0; } - this->SetOptionIfNotSet("CPACK_COMMAND_HDIUTIL", hdiutil_path.c_str()); + this->SetOptionIfNotSet("CPACK_COMMAND_HDIUTIL", hdiutil_path); const std::string setfile_path = cmSystemTools::FindProgram("SetFile", paths, false); @@ -85,7 +86,7 @@ int cmCPackDragNDropGenerator::InitializeInternal() "Cannot locate SetFile command" << std::endl); return 0; } - this->SetOptionIfNotSet("CPACK_COMMAND_SETFILE", setfile_path.c_str()); + this->SetOptionIfNotSet("CPACK_COMMAND_SETFILE", setfile_path); const std::string rez_path = cmSystemTools::FindProgram("Rez", paths, false); if (rez_path.empty()) { @@ -93,7 +94,7 @@ int cmCPackDragNDropGenerator::InitializeInternal() "Cannot locate Rez command" << std::endl); return 0; } - this->SetOptionIfNotSet("CPACK_COMMAND_REZ", rez_path.c_str()); + this->SetOptionIfNotSet("CPACK_COMMAND_REZ", rez_path); if (this->IsSet("CPACK_DMG_SLA_DIR")) { slaDirectory = this->GetOption("CPACK_DMG_SLA_DIR"); @@ -260,48 +261,35 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, const std::string& output_file) { // Get optional arguments ... - const std::string cpack_package_icon = this->GetOption("CPACK_PACKAGE_ICON") - ? this->GetOption("CPACK_PACKAGE_ICON") - : ""; + cmValue cpack_package_icon = this->GetOption("CPACK_PACKAGE_ICON"); const std::string cpack_dmg_volume_name = this->GetOption("CPACK_DMG_VOLUME_NAME") - ? this->GetOption("CPACK_DMG_VOLUME_NAME") - : this->GetOption("CPACK_PACKAGE_FILE_NAME"); + ? *this->GetOption("CPACK_DMG_VOLUME_NAME") + : *this->GetOption("CPACK_PACKAGE_FILE_NAME"); const std::string cpack_dmg_format = this->GetOption("CPACK_DMG_FORMAT") - ? this->GetOption("CPACK_DMG_FORMAT") + ? *this->GetOption("CPACK_DMG_FORMAT") : "UDZO"; const std::string cpack_dmg_filesystem = this->GetOption("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") - ? this->GetOption("CPACK_RESOURCE_FILE_LICENSE") - : ""; + *this->GetOption("CPACK_RESOURCE_FILE_LICENSE"); - const std::string cpack_dmg_background_image = - this->GetOption("CPACK_DMG_BACKGROUND_IMAGE") - ? this->GetOption("CPACK_DMG_BACKGROUND_IMAGE") - : ""; + cmValue cpack_dmg_background_image = + this->GetOption("CPACK_DMG_BACKGROUND_IMAGE"); - const std::string cpack_dmg_ds_store = this->GetOption("CPACK_DMG_DS_STORE") - ? this->GetOption("CPACK_DMG_DS_STORE") - : ""; + cmValue cpack_dmg_ds_store = this->GetOption("CPACK_DMG_DS_STORE"); - const std::string cpack_dmg_languages = - this->GetOption("CPACK_DMG_SLA_LANGUAGES") - ? this->GetOption("CPACK_DMG_SLA_LANGUAGES") - : ""; + cmValue cpack_dmg_languages = this->GetOption("CPACK_DMG_SLA_LANGUAGES"); - const std::string cpack_dmg_ds_store_setup_script = - this->GetOption("CPACK_DMG_DS_STORE_SETUP_SCRIPT") - ? this->GetOption("CPACK_DMG_DS_STORE_SETUP_SCRIPT") - : ""; + cmValue cpack_dmg_ds_store_setup_script = + this->GetOption("CPACK_DMG_DS_STORE_SETUP_SCRIPT"); const bool cpack_dmg_disable_applications_symlink = this->IsOn("CPACK_DMG_DISABLE_APPLICATIONS_SYMLINK"); @@ -332,7 +320,7 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, } // Optionally add a custom volume icon ... - if (!cpack_package_icon.empty()) { + if (!cpack_package_icon->empty()) { std::ostringstream package_icon_source; package_icon_source << cpack_package_icon; @@ -351,7 +339,7 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, // Optionally add a custom .DS_Store file // (e.g. for setting background/layout) ... - if (!cpack_dmg_ds_store.empty()) { + if (!cpack_dmg_ds_store->empty()) { std::ostringstream package_settings_source; package_settings_source << cpack_dmg_ds_store; @@ -372,7 +360,7 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, // Optionally add a custom background image ... // Make sure the background file type is the same as the custom image // and that the file is hidden so it doesn't show up. - if (!cpack_dmg_background_image.empty()) { + if (!cpack_dmg_background_image->empty()) { const std::string extension = cmSystemTools::GetFilenameLastExtension(cpack_dmg_background_image); std::ostringstream package_background_source; @@ -394,7 +382,7 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, } bool remount_image = - !cpack_package_icon.empty() || !cpack_dmg_ds_store_setup_script.empty(); + !cpack_package_icon->empty() || !cpack_dmg_ds_store_setup_script->empty(); std::string temp_image_format = "UDZO"; @@ -471,7 +459,7 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, } // Optionally set the custom icon flag for the image ... - if (!had_error && !cpack_package_icon.empty()) { + if (!had_error && !cpack_package_icon->empty()) { std::string error; std::ostringstream setfile_command; setfile_command << this->GetOption("CPACK_COMMAND_SETFILE"); @@ -490,7 +478,7 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, // Optionally we can execute a custom apple script to generate // the .DS_Store for the volume folder ... - if (!had_error && !cpack_dmg_ds_store_setup_script.empty()) { + if (!had_error && !cpack_dmg_ds_store_setup_script->empty()) { std::ostringstream setup_script_command; setup_script_command << "osascript" << " \"" << cpack_dmg_ds_store_setup_script << "\"" @@ -718,7 +706,7 @@ std::string cmCPackDragNDropGenerator::GetComponentInstallDirNameSuffix( // the current COMPONENT belongs to. std::string groupVar = "CPACK_COMPONENT_" + cmSystemTools::UpperCase(componentName) + "_GROUP"; - const char* _groupName = GetOption(groupVar); + cmValue _groupName = this->GetOption(groupVar); if (_groupName) { std::string groupName = _groupName; diff --git a/Source/CPack/cmCPackExternalGenerator.cxx b/Source/CPack/cmCPackExternalGenerator.cxx index e3521a0e5..157ee1de2 100644 --- a/Source/CPack/cmCPackExternalGenerator.cxx +++ b/Source/CPack/cmCPackExternalGenerator.cxx @@ -18,6 +18,7 @@ #include "cmMakefile.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" int cmCPackExternalGenerator::InitializeInternal() { @@ -60,7 +61,7 @@ int cmCPackExternalGenerator::PackageFiles() return 0; } - const char* packageScript = this->GetOption("CPACK_EXTERNAL_PACKAGE_SCRIPT"); + cmValue packageScript = this->GetOption("CPACK_EXTERNAL_PACKAGE_SCRIPT"); if (cmNonempty(packageScript)) { if (!cmSystemTools::FileIsFullPath(packageScript)) { cmCPackLogger( @@ -76,10 +77,9 @@ int cmCPackExternalGenerator::PackageFiles() return 0; } - const char* builtPackagesStr = - this->GetOption("CPACK_EXTERNAL_BUILT_PACKAGES"); - if (builtPackagesStr) { - cmExpandList(builtPackagesStr, this->packageFileNames, false); + cmValue builtPackages = this->GetOption("CPACK_EXTERNAL_BUILT_PACKAGES"); + if (builtPackages) { + cmExpandList(builtPackages, this->packageFileNames, false); } } @@ -181,43 +181,42 @@ int cmCPackExternalGenerator::cmCPackExternalVersionGenerator::WriteToJSON( return 0; } - const char* packageName = this->Parent->GetOption("CPACK_PACKAGE_NAME"); + cmValue packageName = this->Parent->GetOption("CPACK_PACKAGE_NAME"); if (packageName) { - root["packageName"] = packageName; + root["packageName"] = *packageName; } - const char* packageVersion = - this->Parent->GetOption("CPACK_PACKAGE_VERSION"); + cmValue packageVersion = this->Parent->GetOption("CPACK_PACKAGE_VERSION"); if (packageVersion) { - root["packageVersion"] = packageVersion; + root["packageVersion"] = *packageVersion; } - const char* packageDescriptionFile = + cmValue packageDescriptionFile = this->Parent->GetOption("CPACK_PACKAGE_DESCRIPTION_FILE"); if (packageDescriptionFile) { - root["packageDescriptionFile"] = packageDescriptionFile; + root["packageDescriptionFile"] = *packageDescriptionFile; } - const char* packageDescriptionSummary = + cmValue packageDescriptionSummary = this->Parent->GetOption("CPACK_PACKAGE_DESCRIPTION_SUMMARY"); if (packageDescriptionSummary) { - root["packageDescriptionSummary"] = packageDescriptionSummary; + root["packageDescriptionSummary"] = *packageDescriptionSummary; } - const char* buildConfigCstr = this->Parent->GetOption("CPACK_BUILD_CONFIG"); + cmValue buildConfigCstr = this->Parent->GetOption("CPACK_BUILD_CONFIG"); if (buildConfigCstr) { - root["buildConfig"] = buildConfigCstr; + root["buildConfig"] = *buildConfigCstr; } - const char* defaultDirectoryPermissions = + cmValue defaultDirectoryPermissions = this->Parent->GetOption("CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS"); if (cmNonempty(defaultDirectoryPermissions)) { - root["defaultDirectoryPermissions"] = defaultDirectoryPermissions; + root["defaultDirectoryPermissions"] = *defaultDirectoryPermissions; } if (cmIsInternallyOn(this->Parent->GetOption("CPACK_SET_DESTDIR"))) { root["setDestdir"] = true; root["packagingInstallPrefix"] = - this->Parent->GetOption("CPACK_PACKAGING_INSTALL_PREFIX"); + *this->Parent->GetOption("CPACK_PACKAGING_INSTALL_PREFIX"); } else { root["setDestdir"] = false; } diff --git a/Source/CPack/cmCPackFreeBSDGenerator.cxx b/Source/CPack/cmCPackFreeBSDGenerator.cxx index b673006f2..30b6b0d7f 100644 --- a/Source/CPack/cmCPackFreeBSDGenerator.cxx +++ b/Source/CPack/cmCPackFreeBSDGenerator.cxx @@ -203,11 +203,11 @@ cmGeneratedFileStream& operator<<(cmGeneratedFileStream& s, // basically a wrapper that handles the NULL-ptr return from GetOption(). std::string cmCPackFreeBSDGenerator::var_lookup(const char* var_name) { - const char* pv = this->GetOption(var_name); + cmValue pv = this->GetOption(var_name); if (!pv) { return std::string(); } - return pv; + return *pv; } // Produce UCL in the given @p manifest file for the common diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx index 00e274d6d..2f700b401 100644 --- a/Source/CPack/cmCPackGenerator.cxx +++ b/Source/CPack/cmCPackGenerator.cxx @@ -20,11 +20,11 @@ #include "cmGeneratedFileStream.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" -#include "cmProperty.h" #include "cmState.h" #include "cmStateSnapshot.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" #include "cmVersion.h" #include "cmWorkingDirectory.h" #include "cmXMLSafe.h" @@ -78,14 +78,14 @@ int cmCPackGenerator::PrepareNames() std::string tempDirectory = cmStrCat(this->GetOption("CPACK_PACKAGE_DIRECTORY"), "/_CPack_Packages/"); - const char* toplevelTag = this->GetOption("CPACK_TOPLEVEL_TAG"); + cmValue toplevelTag = this->GetOption("CPACK_TOPLEVEL_TAG"); if (toplevelTag) { - tempDirectory += toplevelTag; + tempDirectory += *toplevelTag; tempDirectory += "/"; } - tempDirectory += this->GetOption("CPACK_GENERATOR"); + tempDirectory += *this->GetOption("CPACK_GENERATOR"); std::string topDirectory = tempDirectory; - const char* pfname = this->GetOption("CPACK_PACKAGE_FILE_NAME"); + cmValue pfname = this->GetOption("CPACK_PACKAGE_FILE_NAME"); if (!pfname) { cmCPackLogger(cmCPackLog::LOG_ERROR, "CPACK_PACKAGE_FILE_NAME not specified" << std::endl); @@ -99,7 +99,7 @@ int cmCPackGenerator::PrepareNames() return 0; } outName += this->GetOutputExtension(); - const char* pdir = this->GetOption("CPACK_PACKAGE_DIRECTORY"); + cmValue pdir = this->GetOption("CPACK_PACKAGE_DIRECTORY"); if (!pdir) { cmCPackLogger(cmCPackLog::LOG_ERROR, "CPACK_PACKAGE_DIRECTORY not specified" << std::endl); @@ -107,25 +107,23 @@ int cmCPackGenerator::PrepareNames() } std::string destFile = pdir; - this->SetOptionIfNotSet("CPACK_OUTPUT_FILE_PREFIX", destFile.c_str()); + this->SetOptionIfNotSet("CPACK_OUTPUT_FILE_PREFIX", destFile); destFile += "/" + outName; std::string outFile = topDirectory + "/" + outName; - this->SetOptionIfNotSet("CPACK_TOPLEVEL_DIRECTORY", topDirectory.c_str()); - this->SetOptionIfNotSet("CPACK_TEMPORARY_DIRECTORY", tempDirectory.c_str()); - this->SetOptionIfNotSet("CPACK_OUTPUT_FILE_NAME", outName.c_str()); - this->SetOptionIfNotSet("CPACK_OUTPUT_FILE_PATH", destFile.c_str()); - this->SetOptionIfNotSet("CPACK_TEMPORARY_PACKAGE_FILE_NAME", - outFile.c_str()); + this->SetOptionIfNotSet("CPACK_TOPLEVEL_DIRECTORY", topDirectory); + this->SetOptionIfNotSet("CPACK_TEMPORARY_DIRECTORY", tempDirectory); + this->SetOptionIfNotSet("CPACK_OUTPUT_FILE_NAME", outName); + this->SetOptionIfNotSet("CPACK_OUTPUT_FILE_PATH", destFile); + this->SetOptionIfNotSet("CPACK_TEMPORARY_PACKAGE_FILE_NAME", outFile); this->SetOptionIfNotSet("CPACK_INSTALL_DIRECTORY", this->GetInstallPath()); this->SetOptionIfNotSet( "CPACK_NATIVE_INSTALL_DIRECTORY", - cmsys::SystemTools::ConvertToOutputPath(this->GetInstallPath()).c_str()); - this->SetOptionIfNotSet("CPACK_TEMPORARY_INSTALL_DIRECTORY", - tempDirectory.c_str()); + cmsys::SystemTools::ConvertToOutputPath(this->GetInstallPath())); + this->SetOptionIfNotSet("CPACK_TEMPORARY_INSTALL_DIRECTORY", tempDirectory); cmCPackLogger(cmCPackLog::LOG_DEBUG, "Look for: CPACK_PACKAGE_DESCRIPTION_FILE" << std::endl); - const char* descFileName = this->GetOption("CPACK_PACKAGE_DESCRIPTION_FILE"); + cmValue descFileName = this->GetOption("CPACK_PACKAGE_DESCRIPTION_FILE"); if (descFileName && !this->GetOption("CPACK_PACKAGE_DESCRIPTION")) { cmCPackLogger(cmCPackLog::LOG_DEBUG, "Look for: " << descFileName << std::endl); @@ -135,7 +133,7 @@ int cmCPackGenerator::PrepareNames() << descFileName << "]" << std::endl); return 0; } - cmsys::ifstream ifs(descFileName); + cmsys::ifstream ifs(descFileName->c_str()); if (!ifs) { cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot open description file name: " << descFileName @@ -150,10 +148,10 @@ int cmCPackGenerator::PrepareNames() while (ifs && cmSystemTools::GetLineFromStream(ifs, line)) { ostr << cmXMLSafe(line) << std::endl; } - this->SetOption("CPACK_PACKAGE_DESCRIPTION", ostr.str().c_str()); - const char* defFileName = + this->SetOption("CPACK_PACKAGE_DESCRIPTION", ostr.str()); + cmValue defFileName = this->GetOption("CPACK_DEFAULT_PACKAGE_DESCRIPTION_FILE"); - if (defFileName && !strcmp(defFileName, descFileName)) { + if (defFileName && (defFileName == descFileName)) { this->SetOption("CPACK_USED_DEFAULT_PACKAGE_DESCRIPTION_FILE", "ON"); } } @@ -165,9 +163,9 @@ int cmCPackGenerator::PrepareNames() << std::endl); return 0; } - const char* algoSignature = this->GetOption("CPACK_PACKAGE_CHECKSUM"); + cmValue algoSignature = this->GetOption("CPACK_PACKAGE_CHECKSUM"); if (algoSignature) { - if (!cmCryptoHash::New(algoSignature)) { + if (!cmCryptoHash::New(*algoSignature)) { cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot recognize algorithm: " << algoSignature << std::endl); @@ -215,7 +213,7 @@ int cmCPackGenerator::InstallProject() // prepare default created directory permissions mode_t default_dir_mode_v = 0; mode_t* default_dir_mode = nullptr; - const char* default_dir_install_permissions = + cmValue default_dir_install_permissions = this->GetOption("CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS"); if (cmNonempty(default_dir_install_permissions)) { std::vector<std::string> items = @@ -266,7 +264,7 @@ int cmCPackGenerator::InstallProject() } // Run pre-build actions - const char* preBuildScripts = this->GetOption("CPACK_PRE_BUILD_SCRIPTS"); + cmValue preBuildScripts = this->GetOption("CPACK_PRE_BUILD_SCRIPTS"); if (preBuildScripts) { const auto scripts = cmExpandedList(preBuildScripts, false); for (const auto& script : scripts) { @@ -293,7 +291,7 @@ int cmCPackGenerator::InstallProjectViaInstallCommands( bool setDestDir, const std::string& tempInstallDirectory) { (void)setDestDir; - const char* installCommands = this->GetOption("CPACK_INSTALL_COMMANDS"); + cmValue installCommands = this->GetOption("CPACK_INSTALL_COMMANDS"); if (cmNonempty(installCommands)) { std::string tempInstallDirectoryEnv = cmStrCat("CMAKE_INSTALL_PREFIX=", tempInstallDirectory); @@ -333,7 +331,7 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories( (void)setDestDir; (void)tempInstallDirectory; std::vector<cmsys::RegularExpression> ignoreFilesRegex; - const char* cpackIgnoreFiles = this->GetOption("CPACK_IGNORE_FILES"); + cmValue cpackIgnoreFiles = this->GetOption("CPACK_IGNORE_FILES"); if (cpackIgnoreFiles) { std::vector<std::string> ignoreFilesRegexString = cmExpandedList(cpackIgnoreFiles); @@ -343,8 +341,7 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories( ignoreFilesRegex.emplace_back(ifr); } } - const char* installDirectories = - this->GetOption("CPACK_INSTALLED_DIRECTORIES"); + cmValue installDirectories = this->GetOption("CPACK_INSTALLED_DIRECTORIES"); if (cmNonempty(installDirectories)) { std::vector<std::string> installDirectoriesVector = cmExpandedList(installDirectories); @@ -472,9 +469,9 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories( int cmCPackGenerator::InstallProjectViaInstallScript( bool setDestDir, const std::string& tempInstallDirectory) { - const char* cmakeScripts = this->GetOption("CPACK_INSTALL_SCRIPTS"); + cmValue cmakeScripts = this->GetOption("CPACK_INSTALL_SCRIPTS"); { - const char* const cmakeScript = this->GetOption("CPACK_INSTALL_SCRIPT"); + cmValue const cmakeScript = this->GetOption("CPACK_INSTALL_SCRIPT"); if (cmakeScript && cmakeScripts) { cmCPackLogger( cmCPackLog::LOG_WARNING, @@ -485,7 +482,7 @@ int cmCPackGenerator::InstallProjectViaInstallScript( cmakeScripts = cmakeScript; } } - if (cmakeScripts && *cmakeScripts) { + if (cmakeScripts && !cmakeScripts->empty()) { cmCPackLogger(cmCPackLog::LOG_OUTPUT, "- Install scripts: " << cmakeScripts << std::endl); std::vector<std::string> cmakeScriptsVector = cmExpandedList(cmakeScripts); @@ -502,9 +499,9 @@ int cmCPackGenerator::InstallProjectViaInstallScript( std::string dir; if (this->GetOption("CPACK_INSTALL_PREFIX")) { - dir += this->GetOption("CPACK_INSTALL_PREFIX"); + dir += *this->GetOption("CPACK_INSTALL_PREFIX"); } - this->SetOption("CMAKE_INSTALL_PREFIX", dir.c_str()); + this->SetOption("CMAKE_INSTALL_PREFIX", dir); cmCPackLogger( cmCPackLog::LOG_DEBUG, "- Using DESTDIR + CPACK_INSTALL_PREFIX... (this->SetOption)" @@ -513,7 +510,7 @@ int cmCPackGenerator::InstallProjectViaInstallScript( "- Setting CMAKE_INSTALL_PREFIX to '" << dir << "'" << std::endl); } else { - this->SetOption("CMAKE_INSTALL_PREFIX", tempInstallDirectory.c_str()); + this->SetOption("CMAKE_INSTALL_PREFIX", tempInstallDirectory); cmCPackLogger(cmCPackLog::LOG_DEBUG, "- Using non-DESTDIR install... (this->SetOption)" @@ -524,9 +521,9 @@ int cmCPackGenerator::InstallProjectViaInstallScript( } this->SetOptionIfNotSet("CMAKE_CURRENT_BINARY_DIR", - tempInstallDirectory.c_str()); + tempInstallDirectory); this->SetOptionIfNotSet("CMAKE_CURRENT_SOURCE_DIR", - tempInstallDirectory.c_str()); + tempInstallDirectory); bool res = this->MakefileMap->ReadListFile(installScript); if (cmSystemTools::GetErrorOccuredFlag() || !res) { return 0; @@ -540,8 +537,8 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( bool setDestDir, const std::string& baseTempInstallDirectory, const mode_t* default_dir_mode) { - const char* cmakeProjects = this->GetOption("CPACK_INSTALL_CMAKE_PROJECTS"); - const char* cmakeGenerator = this->GetOption("CPACK_CMAKE_GENERATOR"); + cmValue cmakeProjects = this->GetOption("CPACK_INSTALL_CMAKE_PROJECTS"); + cmValue cmakeGenerator = this->GetOption("CPACK_CMAKE_GENERATOR"); std::string absoluteDestFiles; if (cmNonempty(cmakeProjects)) { if (!cmakeGenerator) { @@ -595,7 +592,7 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( // Determine the installation types for this project (if provided). std::string installTypesVar = "CPACK_" + cmSystemTools::UpperCase(project.Component) + "_INSTALL_TYPES"; - const char* installTypes = this->GetOption(installTypesVar); + cmValue installTypes = this->GetOption(installTypesVar); if (cmNonempty(installTypes)) { std::vector<std::string> installTypesVector = cmExpandedList(installTypes); @@ -608,7 +605,7 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( // Determine the set of components that will be used in this project std::string componentsVar = "CPACK_COMPONENTS_" + cmSystemTools::UpperCase(project.Component); - const char* components = this->GetOption(componentsVar); + cmValue components = this->GetOption(componentsVar); if (cmNonempty(components)) { cmExpandList(components, componentsVector); for (std::string const& comp : componentsVector) { @@ -625,12 +622,7 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( std::vector<std::string> buildConfigs; // Try get configuration names given via `-C` CLI option - { - const char* const buildConfigCstr = - this->GetOption("CPACK_BUILD_CONFIG"); - auto buildConfig = buildConfigCstr ? buildConfigCstr : std::string{}; - cmExpandList(buildConfig, buildConfigs); - } + cmExpandList(this->GetOption("CPACK_BUILD_CONFIG"), buildConfigs); // Remove duplicates std::sort(buildConfigs.begin(), buildConfigs.end()); @@ -682,8 +674,7 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( this->CMakeProjects.emplace_back(std::move(project)); } } - this->SetOption("CPACK_ABSOLUTE_DESTINATION_FILES", - absoluteDestFiles.c_str()); + this->SetOption("CPACK_ABSOLUTE_DESTINATION_FILES", absoluteDestFiles); return 1; } @@ -767,11 +758,11 @@ int cmCPackGenerator::InstallCMakeProject( tempInstallDirectory += this->GetComponentInstallDirNameSuffix(component); if (this->IsOn("CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY")) { tempInstallDirectory += "/"; - tempInstallDirectory += this->GetOption("CPACK_PACKAGE_FILE_NAME"); + tempInstallDirectory += *this->GetOption("CPACK_PACKAGE_FILE_NAME"); } } - const char* default_dir_inst_permissions = + cmValue default_dir_inst_permissions = this->GetOption("CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS"); if (cmNonempty(default_dir_inst_permissions)) { mf.AddDefinition("CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS", @@ -800,7 +791,7 @@ int cmCPackGenerator::InstallCMakeProject( } std::string dir; if (this->GetOption("CPACK_INSTALL_PREFIX")) { - dir += this->GetOption("CPACK_INSTALL_PREFIX"); + dir += *this->GetOption("CPACK_INSTALL_PREFIX"); } mf.AddDefinition("CMAKE_INSTALL_PREFIX", dir); @@ -924,7 +915,7 @@ int cmCPackGenerator::InstallCMakeProject( // forward definition of CMAKE_ABSOLUTE_DESTINATION_FILES // to CPack (may be used by generators like CPack RPM or DEB) // in order to transparently handle ABSOLUTE PATH - if (cmProp def = mf.GetDefinition("CMAKE_ABSOLUTE_DESTINATION_FILES")) { + if (cmValue def = mf.GetDefinition("CMAKE_ABSOLUTE_DESTINATION_FILES")) { mf.AddDefinition("CPACK_ABSOLUTE_DESTINATION_FILES", *def); } @@ -958,7 +949,7 @@ int cmCPackGenerator::InstallCMakeProject( } } - if (cmProp d = mf.GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES")) { + if (cmValue d = mf.GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES")) { if (!absoluteDestFiles.empty()) { absoluteDestFiles += ";"; } @@ -975,11 +966,10 @@ int cmCPackGenerator::InstallCMakeProject( std::string absoluteDestFilesListComponent = cmStrCat(this->GetOption(absoluteDestFileComponent), ';', *d); this->SetOption(absoluteDestFileComponent, - absoluteDestFilesListComponent.c_str()); + absoluteDestFilesListComponent); } else { - this->SetOption( - absoluteDestFileComponent, - cmToCStr(mf.GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES"))); + this->SetOption(absoluteDestFileComponent, + mf.GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES")); } } } @@ -999,17 +989,29 @@ bool cmCPackGenerator::ReadListFile(const char* moduleName) return retval; } -void cmCPackGenerator::SetOptionIfNotSet(const std::string& op, - const char* value) +template <typename ValueType> +void cmCPackGenerator::StoreOptionIfNotSet(const std::string& op, + ValueType value) { - cmProp def = this->MakefileMap->GetDefinition(op); + cmValue def = this->MakefileMap->GetDefinition(op); if (cmNonempty(def)) { return; } - this->SetOption(op, value); + this->StoreOption(op, value); } -void cmCPackGenerator::SetOption(const std::string& op, const char* value) +void cmCPackGenerator::SetOptionIfNotSet(const std::string& op, + const char* value) +{ + this->StoreOptionIfNotSet(op, value); +} +void cmCPackGenerator::SetOptionIfNotSet(const std::string& op, cmValue value) +{ + this->StoreOptionIfNotSet(op, value); +} + +template <typename ValueType> +void cmCPackGenerator::StoreOption(const std::string& op, ValueType value) { if (!value) { this->MakefileMap->RemoveDefinition(op); @@ -1021,6 +1023,15 @@ void cmCPackGenerator::SetOption(const std::string& op, const char* value) this->MakefileMap->AddDefinition(op, value); } +void cmCPackGenerator::SetOption(const std::string& op, const char* value) +{ + this->StoreOption(op, value); +} +void cmCPackGenerator::SetOption(const std::string& op, cmValue value) +{ + this->StoreOption(op, value); +} + int cmCPackGenerator::DoPackage() { cmCPackLogger(cmCPackLog::LOG_OUTPUT, @@ -1038,8 +1049,7 @@ int cmCPackGenerator::DoPackage() } if (cmIsOn(this->GetOption("CPACK_REMOVE_TOPLEVEL_DIRECTORY"))) { - const char* toplevelDirectory = - this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); + cmValue toplevelDirectory = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); if (cmSystemTools::FileExists(toplevelDirectory)) { cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Remove toplevel directory: " << toplevelDirectory @@ -1060,9 +1070,9 @@ int cmCPackGenerator::DoPackage() } cmCPackLogger(cmCPackLog::LOG_DEBUG, "Done install project " << std::endl); - const char* tempPackageFileName = + cmValue tempPackageFileName = this->GetOption("CPACK_TEMPORARY_PACKAGE_FILE_NAME"); - const char* tempDirectory = this->GetOption("CPACK_TEMPORARY_DIRECTORY"); + cmValue tempDirectory = this->GetOption("CPACK_TEMPORARY_DIRECTORY"); cmCPackLogger(cmCPackLog::LOG_DEBUG, "Find files" << std::endl); cmsys::Glob gl; @@ -1079,7 +1089,7 @@ int cmCPackGenerator::DoPackage() cmCPackLogger(cmCPackLog::LOG_OUTPUT, "Create package" << std::endl); cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Package files to: " - << (tempPackageFileName ? tempPackageFileName : "(NULL)") + << (tempPackageFileName ? *tempPackageFileName : "(NULL)") << std::endl); if (cmSystemTools::FileExists(tempPackageFileName)) { cmCPackLogger(cmCPackLog::LOG_VERBOSE, @@ -1099,9 +1109,8 @@ int cmCPackGenerator::DoPackage() * may update this during PackageFiles. * (either putting several names or updating the provided one) */ - this->packageFileNames.emplace_back(tempPackageFileName ? tempPackageFileName - : ""); - this->toplevel = tempDirectory; + this->packageFileNames.emplace_back(tempPackageFileName); + this->toplevel = *tempDirectory; { // scope that enables package generators to run internal scripts with // latest CMake policies enabled cmMakefile::ScopePushPop pp{ this->MakefileMap }; @@ -1115,7 +1124,7 @@ int cmCPackGenerator::DoPackage() } } // Run post-build actions - const char* postBuildScripts = this->GetOption("CPACK_POST_BUILD_SCRIPTS"); + cmValue postBuildScripts = this->GetOption("CPACK_POST_BUILD_SCRIPTS"); if (postBuildScripts) { this->MakefileMap->AddDefinition("CPACK_PACKAGE_FILES", cmJoin(this->packageFileNames, ";")); @@ -1135,8 +1144,8 @@ int cmCPackGenerator::DoPackage() } /* Prepare checksum algorithm*/ - const char* algo = this->GetOption("CPACK_PACKAGE_CHECKSUM"); - std::unique_ptr<cmCryptoHash> crypto = cmCryptoHash::New(algo ? algo : ""); + cmValue algo = this->GetOption("CPACK_PACKAGE_CHECKSUM"); + std::unique_ptr<cmCryptoHash> crypto = cmCryptoHash::New(*algo); /* * Copy the generated packages to final destination @@ -1151,19 +1160,19 @@ int cmCPackGenerator::DoPackage() for (std::string const& pkgFileName : this->packageFileNames) { std::string tmpPF(this->GetOption("CPACK_OUTPUT_FILE_PREFIX")); std::string filename(cmSystemTools::GetFilenameName(pkgFileName)); - tempPackageFileName = pkgFileName.c_str(); + tempPackageFileName = cmValue(pkgFileName); tmpPF += "/" + filename; const char* packageFileName = tmpPF.c_str(); cmCPackLogger(cmCPackLog::LOG_DEBUG, "Copy final package(s): " - << (tempPackageFileName ? tempPackageFileName : "(NULL)") + << (tempPackageFileName ? *tempPackageFileName : "(NULL)") << " to " << (packageFileName ? packageFileName : "(NULL)") << std::endl); if (!cmSystemTools::CopyFileIfDifferent(pkgFileName, tmpPF)) { cmCPackLogger( cmCPackLog::LOG_ERROR, "Problem copying the package: " - << (tempPackageFileName ? tempPackageFileName : "(NULL)") << " to " + << (tempPackageFileName ? *tempPackageFileName : "(NULL)") << " to " << (packageFileName ? packageFileName : "(NULL)") << std::endl); return 0; } @@ -1198,9 +1207,9 @@ int cmCPackGenerator::Initialize(const std::string& name, cmMakefile* mf) this->MakefileMap = mf; this->Name = name; // set the running generator name - this->SetOption("CPACK_GENERATOR", this->Name.c_str()); + this->SetOption("CPACK_GENERATOR", this->Name); // Load the project specific config file - const char* config = this->GetOption("CPACK_PROJECT_CONFIG_FILE"); + cmValue config = this->GetOption("CPACK_PROJECT_CONFIG_FILE"); if (config) { mf->ReadListFile(config); } @@ -1234,7 +1243,7 @@ bool cmCPackGenerator::IsOn(const std::string& name) const bool cmCPackGenerator::IsSetToOff(const std::string& op) const { - cmProp ret = this->MakefileMap->GetDefinition(op); + cmValue ret = this->MakefileMap->GetDefinition(op); if (cmNonempty(ret)) { return cmIsOff(*ret); } @@ -1243,22 +1252,21 @@ bool cmCPackGenerator::IsSetToOff(const std::string& op) const bool cmCPackGenerator::IsSetToEmpty(const std::string& op) const { - cmProp ret = this->MakefileMap->GetDefinition(op); + cmValue ret = this->MakefileMap->GetDefinition(op); if (ret) { return ret->empty(); } return false; } -const char* cmCPackGenerator::GetOption(const std::string& op) const +cmValue cmCPackGenerator::GetOption(const std::string& op) const { - cmProp ret = this->MakefileMap->GetDefinition(op); + cmValue ret = this->MakefileMap->GetDefinition(op); if (!ret) { cmCPackLogger(cmCPackLog::LOG_DEBUG, "Warning, GetOption return NULL for: " << op << std::endl); - return nullptr; } - return ret->c_str(); + return ret; } std::vector<std::string> cmCPackGenerator::GetOptions() const @@ -1311,7 +1319,7 @@ const char* cmCPackGenerator::GetPackagingInstallPrefix() << this->GetOption("CPACK_PACKAGING_INSTALL_PREFIX") << "'" << std::endl); - return this->GetOption("CPACK_PACKAGING_INSTALL_PREFIX"); + return this->GetOption("CPACK_PACKAGING_INSTALL_PREFIX")->c_str(); } std::string cmCPackGenerator::FindTemplate(const char* name) @@ -1391,12 +1399,8 @@ int cmCPackGenerator::PrepareGroupingKind() method = ONE_PACKAGE_PER_GROUP; } - std::string groupingType; - // Second way to specify grouping - if (nullptr != this->GetOption("CPACK_COMPONENTS_GROUPING")) { - groupingType = this->GetOption("CPACK_COMPONENTS_GROUPING"); - } + std::string groupingType = *this->GetOption("CPACK_COMPONENTS_GROUPING"); if (!groupingType.empty()) { cmCPackLogger(cmCPackLog::LOG_VERBOSE, @@ -1477,18 +1481,18 @@ std::string cmCPackGenerator::GetComponentPackageFileName( if (isGroupName) { std::string groupDispVar = "CPACK_COMPONENT_GROUP_" + cmSystemTools::UpperCase(groupOrComponentName) + "_DISPLAY_NAME"; - const char* groupDispName = this->GetOption(groupDispVar); + cmValue groupDispName = this->GetOption(groupDispVar); if (groupDispName) { - suffix = "-" + std::string(groupDispName); + suffix = "-" + *groupDispName; } } /* the [single] component case */ else { std::string dispVar = "CPACK_COMPONENT_" + cmSystemTools::UpperCase(groupOrComponentName) + "_DISPLAY_NAME"; - const char* dispName = this->GetOption(dispVar); + cmValue dispName = this->GetOption(dispVar); if (dispName) { - suffix = "-" + std::string(dispName); + suffix = "-" + *dispName; } } } @@ -1531,9 +1535,9 @@ cmCPackInstallationType* cmCPackGenerator::GetInstallationType( "CPACK_INSTALL_TYPE_" + cmsys::SystemTools::UpperCase(name); installType->Name = name; - const char* displayName = this->GetOption(macroPrefix + "_DISPLAY_NAME"); + cmValue displayName = this->GetOption(macroPrefix + "_DISPLAY_NAME"); if (cmNonempty(displayName)) { - installType->DisplayName = displayName; + installType->DisplayName = *displayName; } else { installType->DisplayName = installType->Name; } @@ -1553,9 +1557,9 @@ cmCPackComponent* cmCPackGenerator::GetComponent( std::string macroPrefix = "CPACK_COMPONENT_" + cmsys::SystemTools::UpperCase(name); component->Name = name; - const char* displayName = this->GetOption(macroPrefix + "_DISPLAY_NAME"); + cmValue displayName = this->GetOption(macroPrefix + "_DISPLAY_NAME"); if (cmNonempty(displayName)) { - component->DisplayName = displayName; + component->DisplayName = *displayName; } else { component->DisplayName = component->Name; } @@ -1565,17 +1569,17 @@ cmCPackComponent* cmCPackGenerator::GetComponent( component->IsDownloaded = this->IsOn(macroPrefix + "_DOWNLOADED") || cmIsOn(this->GetOption("CPACK_DOWNLOAD_ALL")); - const char* archiveFile = this->GetOption(macroPrefix + "_ARCHIVE_FILE"); + cmValue archiveFile = this->GetOption(macroPrefix + "_ARCHIVE_FILE"); if (cmNonempty(archiveFile)) { - component->ArchiveFile = archiveFile; + component->ArchiveFile = *archiveFile; } - const char* plist = this->GetOption(macroPrefix + "_PLIST"); + cmValue plist = this->GetOption(macroPrefix + "_PLIST"); if (cmNonempty(plist)) { - component->Plist = plist; + component->Plist = *plist; } - const char* groupName = this->GetOption(macroPrefix + "_GROUP"); + cmValue groupName = this->GetOption(macroPrefix + "_GROUP"); if (cmNonempty(groupName)) { component->Group = this->GetComponentGroup(projectName, groupName); component->Group->Components.push_back(component); @@ -1583,13 +1587,13 @@ cmCPackComponent* cmCPackGenerator::GetComponent( component->Group = nullptr; } - const char* description = this->GetOption(macroPrefix + "_DESCRIPTION"); + cmValue description = this->GetOption(macroPrefix + "_DESCRIPTION"); if (cmNonempty(description)) { - component->Description = description; + component->Description = *description; } // Determine the installation types. - const char* installTypes = this->GetOption(macroPrefix + "_INSTALL_TYPES"); + cmValue installTypes = this->GetOption(macroPrefix + "_INSTALL_TYPES"); if (cmNonempty(installTypes)) { std::vector<std::string> installTypesVector = cmExpandedList(installTypes); @@ -1600,7 +1604,7 @@ cmCPackComponent* cmCPackGenerator::GetComponent( } // Determine the component dependencies. - const char* depends = this->GetOption(macroPrefix + "_DEPENDS"); + cmValue depends = this->GetOption(macroPrefix + "_DEPENDS"); if (cmNonempty(depends)) { std::vector<std::string> dependsVector = cmExpandedList(depends); for (std::string const& depend : dependsVector) { @@ -1624,21 +1628,20 @@ cmCPackComponentGroup* cmCPackGenerator::GetComponentGroup( if (!hasGroup) { // Define the group group->Name = name; - const char* displayName = this->GetOption(macroPrefix + "_DISPLAY_NAME"); + cmValue displayName = this->GetOption(macroPrefix + "_DISPLAY_NAME"); if (cmNonempty(displayName)) { - group->DisplayName = displayName; + group->DisplayName = *displayName; } else { group->DisplayName = group->Name; } - const char* description = this->GetOption(macroPrefix + "_DESCRIPTION"); + cmValue description = this->GetOption(macroPrefix + "_DESCRIPTION"); if (cmNonempty(description)) { - group->Description = description; + group->Description = *description; } group->IsBold = this->IsOn(macroPrefix + "_BOLD_TITLE"); group->IsExpandedByDefault = this->IsOn(macroPrefix + "_EXPANDED"); - const char* parentGroupName = - this->GetOption(macroPrefix + "_PARENT_GROUP"); + cmValue parentGroupName = this->GetOption(macroPrefix + "_PARENT_GROUP"); if (cmNonempty(parentGroupName)) { group->ParentGroup = this->GetComponentGroup(projectName, parentGroupName); diff --git a/Source/CPack/cmCPackGenerator.h b/Source/CPack/cmCPackGenerator.h index 2512d4208..65156ab25 100644 --- a/Source/CPack/cmCPackGenerator.h +++ b/Source/CPack/cmCPackGenerator.h @@ -13,6 +13,7 @@ #include "cmCPackComponentGroup.h" #include "cmSystemTools.h" +#include "cmValue.h" class cmCPackLog; class cmGlobalGenerator; @@ -84,8 +85,18 @@ public: //! Set and get the options void SetOption(const std::string& op, const char* value); + void SetOption(const std::string& op, const std::string& value) + { + this->SetOption(op, cmValue(value)); + } + void SetOption(const std::string& op, cmValue value); void SetOptionIfNotSet(const std::string& op, const char* value); - const char* GetOption(const std::string& op) const; + void SetOptionIfNotSet(const std::string& op, const std::string& value) + { + this->SetOptionIfNotSet(op, cmValue(value)); + } + void SetOptionIfNotSet(const std::string& op, cmValue value); + cmValue GetOption(const std::string& op) const; std::vector<std::string> GetOptions() const; bool IsSet(const std::string& name) const; bool IsOn(const std::string& name) const; @@ -323,6 +334,12 @@ protected: bool TraceExpand; cmMakefile* MakefileMap; + +private: + template <typename ValueType> + void StoreOption(const std::string& op, ValueType value); + template <typename ValueType> + void StoreOptionIfNotSet(const std::string& op, ValueType value); }; #define cmCPackTypeMacro(klass, superclass) \ diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx index 6bd0d1b2a..ecc5e0849 100644 --- a/Source/CPack/cmCPackNSISGenerator.cxx +++ b/Source/CPack/cmCPackNSISGenerator.cxx @@ -21,6 +21,7 @@ #include "cmGeneratedFileStream.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" /* NSIS uses different command line syntax on Windows and others */ #ifdef _WIN32 @@ -84,7 +85,7 @@ int cmCPackNSISGenerator::PackageFiles() } cmCPackLogger(cmCPackLog::LOG_DEBUG, "Uninstall Files: " << str.str() << std::endl); - this->SetOptionIfNotSet("CPACK_NSIS_DELETE_FILES", str.str().c_str()); + this->SetOptionIfNotSet("CPACK_NSIS_DELETE_FILES", str.str()); std::vector<std::string> dirs; this->GetListOfSubdirectories(this->toplevel.c_str(), dirs); std::ostringstream dstr; @@ -120,7 +121,7 @@ int cmCPackNSISGenerator::PackageFiles() } cmCPackLogger(cmCPackLog::LOG_DEBUG, "Uninstall Dirs: " << dstr.str() << std::endl); - this->SetOptionIfNotSet("CPACK_NSIS_DELETE_DIRECTORIES", dstr.str().c_str()); + this->SetOptionIfNotSet("CPACK_NSIS_DELETE_DIRECTORIES", dstr.str()); cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Configure file: " << nsisInFileName << " to " << nsisFileName @@ -142,15 +143,15 @@ int cmCPackNSISGenerator::PackageFiles() } std::string installerHeaderImage; if (this->IsSet("CPACK_NSIS_MUI_HEADERIMAGE")) { - installerHeaderImage = this->GetOption("CPACK_NSIS_MUI_HEADERIMAGE"); + installerHeaderImage = *this->GetOption("CPACK_NSIS_MUI_HEADERIMAGE"); } else if (this->IsSet("CPACK_PACKAGE_ICON")) { - installerHeaderImage = this->GetOption("CPACK_PACKAGE_ICON"); + installerHeaderImage = *this->GetOption("CPACK_PACKAGE_ICON"); } if (!installerHeaderImage.empty()) { std::string installerIconCode = cmStrCat( "!define MUI_HEADERIMAGE_BITMAP \"", installerHeaderImage, "\"\n"); this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_ICON_CODE", - installerIconCode.c_str()); + installerIconCode); } if (this->IsSet("CPACK_NSIS_MUI_WELCOMEFINISHPAGE_BITMAP")) { @@ -158,7 +159,7 @@ int cmCPackNSISGenerator::PackageFiles() "!define MUI_WELCOMEFINISHPAGE_BITMAP \"", this->GetOption("CPACK_NSIS_MUI_WELCOMEFINISHPAGE_BITMAP"), "\"\n"); this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_MUI_WELCOMEFINISH_CODE", - installerBitmapCode.c_str()); + installerBitmapCode); } if (this->IsSet("CPACK_NSIS_MUI_UNWELCOMEFINISHPAGE_BITMAP")) { @@ -166,7 +167,7 @@ int cmCPackNSISGenerator::PackageFiles() "!define MUI_UNWELCOMEFINISHPAGE_BITMAP \"", this->GetOption("CPACK_NSIS_MUI_UNWELCOMEFINISHPAGE_BITMAP"), "\"\n"); this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_MUI_UNWELCOMEFINISH_CODE", - installerBitmapCode.c_str()); + installerBitmapCode); } if (this->IsSet("CPACK_NSIS_MUI_FINISHPAGE_RUN")) { @@ -175,7 +176,7 @@ int cmCPackNSISGenerator::PackageFiles() this->GetOption("CPACK_NSIS_EXECUTABLES_DIRECTORY"), '\\', this->GetOption("CPACK_NSIS_MUI_FINISHPAGE_RUN"), "\"\n"); this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_MUI_FINISHPAGE_RUN_CODE", - installerRunCode.c_str()); + installerRunCode); } if (this->IsSet("CPACK_NSIS_WELCOME_TITLE")) { @@ -183,7 +184,7 @@ int cmCPackNSISGenerator::PackageFiles() cmStrCat("!define MUI_WELCOMEPAGE_TITLE \"", this->GetOption("CPACK_NSIS_WELCOME_TITLE"), "\""); this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_WELCOME_TITLE_CODE", - welcomeTitleCode.c_str()); + welcomeTitleCode); } if (this->IsSet("CPACK_NSIS_WELCOME_TITLE_3LINES")) { @@ -196,7 +197,7 @@ int cmCPackNSISGenerator::PackageFiles() cmStrCat("!define MUI_FINISHPAGE_TITLE \"", this->GetOption("CPACK_NSIS_FINISH_TITLE"), "\""); this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_FINISH_TITLE_CODE", - finishTitleCode.c_str()); + finishTitleCode); } if (this->IsSet("CPACK_NSIS_FINISH_TITLE_3LINES")) { @@ -231,8 +232,14 @@ int cmCPackNSISGenerator::PackageFiles() std::string brandingTextCode = cmStrCat("BrandingText /TRIM", brandingTextPosition, " \"", this->GetOption("CPACK_NSIS_BRANDING_TEXT"), "\"\n"); - this->SetOptionIfNotSet("CPACK_NSIS_BRANDING_TEXT_CODE", - brandingTextCode.c_str()); + this->SetOptionIfNotSet("CPACK_NSIS_BRANDING_TEXT_CODE", brandingTextCode); + } + + if (!this->IsSet("CPACK_NSIS_IGNORE_LICENSE_PAGE")) { + std::string licenceCode = + cmStrCat("!insertmacro MUI_PAGE_LICENSE \"", + this->GetOption("CPACK_RESOURCE_FILE_LICENSE"), "\"\n"); + this->SetOptionIfNotSet("CPACK_NSIS_LICENSE_PAGE", licenceCode); } // Setup all of the component sections @@ -327,7 +334,7 @@ int cmCPackNSISGenerator::PackageFiles() componentDescriptions + groupDescriptions + "!insertmacro MUI_FUNCTION_DESCRIPTION_END\n"; this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_MUI_COMPONENTS_DESC", - componentDescriptions.c_str()); + componentDescriptions); } if (anyDownloadedComponents) { @@ -337,18 +344,15 @@ int cmCPackNSISGenerator::PackageFiles() } } - this->SetOptionIfNotSet("CPACK_NSIS_INSTALLATION_TYPES", - installTypesCode.c_str()); + this->SetOptionIfNotSet("CPACK_NSIS_INSTALLATION_TYPES", installTypesCode); this->SetOptionIfNotSet("CPACK_NSIS_PAGE_COMPONENTS", "!insertmacro MUI_PAGE_COMPONENTS"); this->SetOptionIfNotSet("CPACK_NSIS_FULL_INSTALL", ""); - this->SetOptionIfNotSet("CPACK_NSIS_COMPONENT_SECTIONS", - componentCode.c_str()); - this->SetOptionIfNotSet("CPACK_NSIS_COMPONENT_SECTION_LIST", - sectionList.c_str()); + this->SetOptionIfNotSet("CPACK_NSIS_COMPONENT_SECTIONS", componentCode); + this->SetOptionIfNotSet("CPACK_NSIS_COMPONENT_SECTION_LIST", sectionList); this->SetOptionIfNotSet("CPACK_NSIS_SECTION_SELECTED_VARS", - selectedVarsList.c_str()); - this->SetOption("CPACK_NSIS_DEFINES", defines.c_str()); + selectedVarsList); + this->SetOption("CPACK_NSIS_DEFINES", defines); } this->ConfigureFile(nsisInInstallOptions, nsisInstallOptions); @@ -472,8 +476,8 @@ int cmCPackNSISGenerator::InitializeInternal() cmsys::RegularExpression versionRexCVS("v(.*)\\.cvs"); if (!resS || retVal || (!versionRex.find(output) && !versionRexCVS.find(output))) { - const char* topDir = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); - std::string tmpFile = cmStrCat(topDir ? topDir : ".", "/NSISOutput.log"); + cmValue topDir = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); + std::string tmpFile = cmStrCat(topDir ? *topDir : ".", "/NSISOutput.log"); cmGeneratedFileStream ofs(tmpFile); ofs << "# Run command: " << nsisCmd << std::endl << "# Output:" << std::endl @@ -487,12 +491,12 @@ int cmCPackNSISGenerator::InitializeInternal() } if (versionRex.find(output)) { double nsisVersion = atof(versionRex.match(1).c_str()); - double minNSISVersion = 3.0; + double minNSISVersion = 3.03; cmCPackLogger(cmCPackLog::LOG_DEBUG, "NSIS Version: " << nsisVersion << std::endl); if (nsisVersion < minNSISVersion) { cmCPackLogger(cmCPackLog::LOG_ERROR, - "CPack requires NSIS Version 3.0 or greater. " + "CPack requires NSIS Version 3.03 or greater. " "NSIS found on the system was: " << nsisVersion << std::endl); return 0; @@ -503,13 +507,13 @@ int cmCPackNSISGenerator::InitializeInternal() cmCPackLogger(cmCPackLog::LOG_DEBUG, "NSIS Version: CVS " << versionRexCVS.match(1) << std::endl); } - this->SetOptionIfNotSet("CPACK_INSTALLER_PROGRAM", nsisPath.c_str()); + this->SetOptionIfNotSet("CPACK_INSTALLER_PROGRAM", nsisPath); this->SetOptionIfNotSet("CPACK_NSIS_EXECUTABLES_DIRECTORY", "bin"); - const char* cpackPackageExecutables = + cmValue cpackPackageExecutables = this->GetOption("CPACK_PACKAGE_EXECUTABLES"); - const char* cpackPackageDeskTopLinks = + cmValue cpackPackageDeskTopLinks = this->GetOption("CPACK_CREATE_DESKTOP_LINKS"); - const char* cpackNsisExecutablesDirectory = + cmValue cpackNsisExecutablesDirectory = this->GetOption("CPACK_NSIS_EXECUTABLES_DIRECTORY"); std::vector<std::string> cpackPackageDesktopLinksVector; if (cpackPackageDeskTopLinks) { @@ -571,8 +575,8 @@ int cmCPackNSISGenerator::InitializeInternal() } this->CreateMenuLinks(str, deleteStr); - this->SetOptionIfNotSet("CPACK_NSIS_CREATE_ICONS", str.str().c_str()); - this->SetOptionIfNotSet("CPACK_NSIS_DELETE_ICONS", deleteStr.str().c_str()); + this->SetOptionIfNotSet("CPACK_NSIS_CREATE_ICONS", str.str()); + this->SetOptionIfNotSet("CPACK_NSIS_DELETE_ICONS", deleteStr.str()); this->SetOptionIfNotSet("CPACK_NSIS_COMPRESSOR", "lzma"); @@ -582,7 +586,7 @@ int cmCPackNSISGenerator::InitializeInternal() void cmCPackNSISGenerator::CreateMenuLinks(std::ostream& str, std::ostream& deleteStr) { - const char* cpackMenuLinks = this->GetOption("CPACK_NSIS_MENU_LINKS"); + cmValue cpackMenuLinks = this->GetOption("CPACK_NSIS_MENU_LINKS"); if (!cpackMenuLinks) { return; } @@ -721,11 +725,10 @@ std::string cmCPackNSISGenerator::CreateComponentDescription( } // Create the directory for the upload area - const char* userUploadDirectory = - this->GetOption("CPACK_UPLOAD_DIRECTORY"); + cmValue userUploadDirectory = this->GetOption("CPACK_UPLOAD_DIRECTORY"); std::string uploadDirectory; if (cmNonempty(userUploadDirectory)) { - uploadDirectory = userUploadDirectory; + uploadDirectory = *userUploadDirectory; } else { uploadDirectory = cmStrCat(this->GetOption("CPACK_PACKAGE_DIRECTORY"), "/CPackUploads"); @@ -961,9 +964,9 @@ std::string cmCPackNSISGenerator::CreateComponentGroupDescription( std::string cmCPackNSISGenerator::CustomComponentInstallDirectory( cm::string_view componentName) { - const char* outputDir = this->GetOption( + cmValue outputDir = this->GetOption( cmStrCat("CPACK_NSIS_", componentName, "_INSTALL_DIRECTORY")); - return outputDir ? outputDir : "$INSTDIR"; + return outputDir ? *outputDir : "$INSTDIR"; } std::string cmCPackNSISGenerator::TranslateNewlines(std::string str) diff --git a/Source/CPack/cmCPackNuGetGenerator.cxx b/Source/CPack/cmCPackNuGetGenerator.cxx index 98dc8906f..5de817937 100644 --- a/Source/CPack/cmCPackNuGetGenerator.cxx +++ b/Source/CPack/cmCPackNuGetGenerator.cxx @@ -14,6 +14,7 @@ #include "cmCPackLog.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" bool cmCPackNuGetGenerator::SupportsComponentInstallation() const { @@ -81,10 +82,10 @@ void cmCPackNuGetGenerator::SetupGroupComponentVariables(bool ignoreGroup) std::back_inserter(components), [](cmCPackComponent const* comp) { return comp->Name; }); this->SetOption("CPACK_NUGET_" + compGUp + "_GROUP_COMPONENTS", - cmJoin(components, ";").c_str()); + cmJoin(components, ";")); } if (!groups.empty()) { - this->SetOption("CPACK_NUGET_GROUPS", cmJoin(groups, ";").c_str()); + this->SetOption("CPACK_NUGET_GROUPS", cmJoin(groups, ";")); } // Handle Orphan components (components not belonging to any groups) @@ -102,8 +103,7 @@ void cmCPackNuGetGenerator::SetupGroupComponentVariables(bool ignoreGroup) } } if (!components.empty()) { - this->SetOption("CPACK_NUGET_COMPONENTS", - cmJoin(components, ";").c_str()); + this->SetOption("CPACK_NUGET_COMPONENTS", cmJoin(components, ";")); } } else { @@ -114,13 +114,13 @@ void cmCPackNuGetGenerator::SetupGroupComponentVariables(bool ignoreGroup) [](std::pair<std::string, cmCPackComponent> const& comp) { return comp.first; }); - this->SetOption("CPACK_NUGET_COMPONENTS", cmJoin(components, ";").c_str()); + this->SetOption("CPACK_NUGET_COMPONENTS", cmJoin(components, ";")); } } void cmCPackNuGetGenerator::AddGeneratedPackageNames() { - const char* const files_list = this->GetOption("GEN_CPACK_OUTPUT_FILES"); + cmValue const files_list = this->GetOption("GEN_CPACK_OUTPUT_FILES"); if (!files_list) { cmCPackLogger( cmCPackLog::LOG_ERROR, @@ -129,7 +129,7 @@ void cmCPackNuGetGenerator::AddGeneratedPackageNames() return; } // add the generated packages to package file names list - std::string fileNames{ files_list }; + const std::string& fileNames = *files_list; const char sep = ';'; std::string::size_type pos1 = 0; std::string::size_type pos2 = fileNames.find(sep, pos1 + 1); diff --git a/Source/CPack/cmCPackOSXX11Generator.cxx b/Source/CPack/cmCPackOSXX11Generator.cxx index 5de4a6f3f..7bf1dc735 100644 --- a/Source/CPack/cmCPackOSXX11Generator.cxx +++ b/Source/CPack/cmCPackOSXX11Generator.cxx @@ -12,6 +12,7 @@ #include "cmGeneratedFileStream.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" cmCPackOSXX11Generator::cmCPackOSXX11Generator() = default; @@ -22,7 +23,7 @@ int cmCPackOSXX11Generator::PackageFiles() // TODO: Use toplevel ? // It is used! Is this an obsolete comment? - const char* cpackPackageExecutables = + cmValue cpackPackageExecutables = this->GetOption("CPACK_PACKAGE_EXECUTABLES"); if (cpackPackageExecutables) { cmCPackLogger(cmCPackLog::LOG_DEBUG, @@ -45,8 +46,7 @@ int cmCPackOSXX11Generator::PackageFiles() it != cpackPackageExecutablesVector.end(); ++it) { std::string cpackExecutableName = *it; ++it; - this->SetOptionIfNotSet("CPACK_EXECUTABLE_NAME", - cpackExecutableName.c_str()); + this->SetOptionIfNotSet("CPACK_EXECUTABLE_NAME", cpackExecutableName); } } @@ -70,7 +70,7 @@ int cmCPackOSXX11Generator::PackageFiles() const char* scrDir = scriptDirectory.c_str(); const char* contDir = contentsDirectory.c_str(); const char* rsrcFile = resourceFileName.c_str(); - const char* iconFile = this->GetOption("CPACK_PACKAGE_ICON"); + cmValue iconFile = this->GetOption("CPACK_PACKAGE_ICON"); if (iconFile) { std::string iconFileName = cmsys::SystemTools::GetFilenameName(iconFile); if (!cmSystemTools::FileExists(iconFile)) { @@ -83,7 +83,7 @@ int cmCPackOSXX11Generator::PackageFiles() } std::string destFileName = resourcesDirectory + "/" + iconFileName; this->ConfigureFile(iconFile, destFileName, true); - this->SetOptionIfNotSet("CPACK_APPLE_GUI_ICON", iconFileName.c_str()); + this->SetOptionIfNotSet("CPACK_APPLE_GUI_ICON", iconFileName); } std::string applicationsLinkName = diskImageDirectory + "/Applications"; @@ -103,9 +103,9 @@ int cmCPackOSXX11Generator::PackageFiles() true) || !this->CopyResourcePlistFile("OSXScriptLauncher.rsrc", dir, rsrcFile, true) || - !this->CopyResourcePlistFile("OSXScriptLauncher", appdir, - this->GetOption("CPACK_PACKAGE_FILE_NAME"), - true)) { + !this->CopyResourcePlistFile( + "OSXScriptLauncher", appdir, + this->GetOption("CPACK_PACKAGE_FILE_NAME").GetCStr(), true)) { cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem copying the resource files" << std::endl); return 0; @@ -190,8 +190,7 @@ int cmCPackOSXX11Generator::InitializeInternal() "Cannot find hdiutil compiler" << std::endl); return 0; } - this->SetOptionIfNotSet("CPACK_INSTALLER_PROGRAM_DISK_IMAGE", - pkgPath.c_str()); + this->SetOptionIfNotSet("CPACK_INSTALLER_PROGRAM_DISK_IMAGE", pkgPath); return this->Superclass::InitializeInternal(); } diff --git a/Source/CPack/cmCPackPKGGenerator.cxx b/Source/CPack/cmCPackPKGGenerator.cxx index ac3d64d9a..91adf321e 100644 --- a/Source/CPack/cmCPackPKGGenerator.cxx +++ b/Source/CPack/cmCPackPKGGenerator.cxx @@ -9,6 +9,7 @@ #include "cmCPackLog.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" #include "cmXMLWriter.h" cmCPackPKGGenerator::cmCPackPKGGenerator() @@ -56,7 +57,7 @@ void cmCPackPKGGenerator::CreateBackground(const char* themeName, std::string opt = (themeName == nullptr) ? cmStrCat("CPACK_", genName, "_BACKGROUND") : cmStrCat("CPACK_", genName, "_BACKGROUND_", paramSuffix); - const char* bgFileName = this->GetOption(opt); + cmValue bgFileName = this->GetOption(opt); if (bgFileName == nullptr) { return; } @@ -78,7 +79,7 @@ void cmCPackPKGGenerator::CreateBackground(const char* themeName, xout.Attribute("file", bgFileName); - const char* param = this->GetOption(cmStrCat(opt, "_ALIGNMENT")); + cmValue param = this->GetOption(cmStrCat(opt, "_ALIGNMENT")); if (param != nullptr) { xout.Attribute("alignment", param); } @@ -166,7 +167,7 @@ void cmCPackPKGGenerator::WriteDistributionFile(const char* metapackageFile, // Dark Aqua this->CreateBackground("darkAqua", metapackageFile, genName, xout); - this->SetOption("CPACK_PACKAGEMAKER_CHOICES", choiceOut.str().c_str()); + this->SetOption("CPACK_PACKAGEMAKER_CHOICES", choiceOut.str()); // Create the distribution.dist file in the metapackage to turn it // into a distribution package. @@ -315,7 +316,7 @@ bool cmCPackPKGGenerator::CopyCreateResourceFile(const std::string& name, { std::string uname = cmSystemTools::UpperCase(name); std::string cpackVar = "CPACK_RESOURCE_FILE_" + uname; - const char* inFileName = this->GetOption(cpackVar); + cmValue inFileName = this->GetOption(cpackVar); if (!inFileName) { cmCPackLogger(cmCPackLog::LOG_ERROR, "CPack option: " << cpackVar.c_str() @@ -347,11 +348,10 @@ bool cmCPackPKGGenerator::CopyCreateResourceFile(const std::string& name, // Set this so that distribution.dist gets the right name (without // the path). - this->SetOption("CPACK_RESOURCE_FILE_" + uname + "_NOPATH", - (name + ext).c_str()); + this->SetOption("CPACK_RESOURCE_FILE_" + uname + "_NOPATH", (name + ext)); cmCPackLogger(cmCPackLog::LOG_VERBOSE, - "Configure file: " << (inFileName ? inFileName : "(NULL)") + "Configure file: " << (inFileName ? *inFileName : "(NULL)") << " to " << destFileName << std::endl); this->ConfigureFile(inFileName, destFileName); return true; diff --git a/Source/CPack/cmCPackPackageMakerGenerator.cxx b/Source/CPack/cmCPackPackageMakerGenerator.cxx index f51ea42de..a8cf1fad9 100644 --- a/Source/CPack/cmCPackPackageMakerGenerator.cxx +++ b/Source/CPack/cmCPackPackageMakerGenerator.cxx @@ -18,6 +18,7 @@ #include "cmGeneratedFileStream.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" #include "cmXMLWriter.h" static inline unsigned int getVersion(unsigned int major, unsigned int minor) @@ -79,9 +80,9 @@ int cmCPackPackageMakerGenerator::PackageFiles() resDir += "/en.lproj"; } - const char* preflight = this->GetOption("CPACK_PREFLIGHT_SCRIPT"); - const char* postflight = this->GetOption("CPACK_POSTFLIGHT_SCRIPT"); - const char* postupgrade = this->GetOption("CPACK_POSTUPGRADE_SCRIPT"); + cmValue preflight = this->GetOption("CPACK_PREFLIGHT_SCRIPT"); + cmValue postflight = this->GetOption("CPACK_POSTFLIGHT_SCRIPT"); + cmValue postupgrade = this->GetOption("CPACK_POSTUPGRADE_SCRIPT"); if (this->Components.empty()) { // Create directory structure @@ -167,10 +168,9 @@ int cmCPackPackageMakerGenerator::PackageFiles() // Create the directory where downloaded component packages will // be placed. - const char* userUploadDirectory = - this->GetOption("CPACK_UPLOAD_DIRECTORY"); + cmValue userUploadDirectory = this->GetOption("CPACK_UPLOAD_DIRECTORY"); std::string uploadDirectory; - if (userUploadDirectory && *userUploadDirectory) { + if (userUploadDirectory && !userUploadDirectory->empty()) { uploadDirectory = userUploadDirectory; } else { uploadDirectory = @@ -352,8 +352,8 @@ int cmCPackPackageMakerGenerator::InitializeInternal() "/PackageMaker.app/Contents/MacOS"); std::string pkgPath; - const char* inst_program = this->GetOption("CPACK_INSTALLER_PROGRAM"); - if (inst_program && *inst_program) { + cmValue inst_program = this->GetOption("CPACK_INSTALLER_PROGRAM"); + if (inst_program && !inst_program->empty()) { pkgPath = inst_program; } else { pkgPath = cmSystemTools::FindProgram("PackageMaker", paths, false); @@ -362,7 +362,7 @@ int cmCPackPackageMakerGenerator::InitializeInternal() "Cannot find PackageMaker compiler" << std::endl); return 0; } - this->SetOptionIfNotSet("CPACK_INSTALLER_PROGRAM", pkgPath.c_str()); + this->SetOptionIfNotSet("CPACK_INSTALLER_PROGRAM", pkgPath); } // Get path to the real PackageMaker, not a symlink: @@ -427,11 +427,12 @@ int cmCPackPackageMakerGenerator::InitializeInternal() // Determine the package compatibility version. If it wasn't // specified by the user, we define it based on which features the // user requested. - const char* packageCompat = this->GetOption("CPACK_OSX_PACKAGE_VERSION"); - if (packageCompat && *packageCompat) { + cmValue packageCompat = this->GetOption("CPACK_OSX_PACKAGE_VERSION"); + if (packageCompat && !packageCompat->empty()) { unsigned int majorVersion = 10; unsigned int minorVersion = 5; - int res = sscanf(packageCompat, "%u.%u", &majorVersion, &minorVersion); + int res = + sscanf(packageCompat->c_str(), "%u.%u", &majorVersion, &minorVersion); if (res == 2) { this->PackageCompatibilityVersion = getVersion(majorVersion, minorVersion); @@ -454,8 +455,7 @@ int cmCPackPackageMakerGenerator::InitializeInternal() "Cannot find hdiutil compiler" << std::endl); return 0; } - this->SetOptionIfNotSet("CPACK_INSTALLER_PROGRAM_DISK_IMAGE", - pkgPath.c_str()); + this->SetOptionIfNotSet("CPACK_INSTALLER_PROGRAM_DISK_IMAGE", pkgPath); return this->Superclass::InitializeInternal(); } @@ -543,8 +543,7 @@ bool cmCPackPackageMakerGenerator::GenerateComponentPackage( // Create the Info.plist file for this component std::string moduleVersionSuffix = cmStrCat('.', component.Name); - this->SetOption("CPACK_MODULE_VERSION_SUFFIX", - moduleVersionSuffix.c_str()); + this->SetOption("CPACK_MODULE_VERSION_SUFFIX", moduleVersionSuffix); std::string infoFileName = cmStrCat(component.Name, "-Info.plist"); if (!this->CopyResourcePlistFile("Info.plist", infoFileName.c_str())) { return false; diff --git a/Source/CPack/cmCPackProductBuildGenerator.cxx b/Source/CPack/cmCPackProductBuildGenerator.cxx index a3e55de5c..f55b8def0 100644 --- a/Source/CPack/cmCPackProductBuildGenerator.cxx +++ b/Source/CPack/cmCPackProductBuildGenerator.cxx @@ -12,6 +12,7 @@ #include "cmGeneratedFileStream.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" cmCPackProductBuildGenerator::cmCPackProductBuildGenerator() { @@ -87,11 +88,11 @@ int cmCPackProductBuildGenerator::PackageFiles() std::string version = this->GetOption("CPACK_PACKAGE_VERSION"); std::string productbuild = this->GetOption("CPACK_COMMAND_PRODUCTBUILD"); std::string identityName; - if (const char* n = this->GetOption("CPACK_PRODUCTBUILD_IDENTITY_NAME")) { + if (cmValue n = this->GetOption("CPACK_PRODUCTBUILD_IDENTITY_NAME")) { identityName = n; } std::string keychainPath; - if (const char* p = this->GetOption("CPACK_PRODUCTBUILD_KEYCHAIN_PATH")) { + if (cmValue p = this->GetOption("CPACK_PRODUCTBUILD_KEYCHAIN_PATH")) { keychainPath = p; } @@ -122,7 +123,7 @@ int cmCPackProductBuildGenerator::InitializeInternal() "Cannot find pkgbuild executable" << std::endl); return 0; } - this->SetOptionIfNotSet("CPACK_COMMAND_PKGBUILD", program.c_str()); + this->SetOptionIfNotSet("CPACK_COMMAND_PKGBUILD", program); program = cmSystemTools::FindProgram("productbuild", no_paths, false); if (program.empty()) { @@ -130,7 +131,7 @@ int cmCPackProductBuildGenerator::InitializeInternal() "Cannot find productbuild executable" << std::endl); return 0; } - this->SetOptionIfNotSet("CPACK_COMMAND_PRODUCTBUILD", program.c_str()); + this->SetOptionIfNotSet("CPACK_COMMAND_PRODUCTBUILD", program); return this->Superclass::InitializeInternal(); } @@ -173,8 +174,8 @@ bool cmCPackProductBuildGenerator::GenerateComponentPackage( const char* comp_name = component ? component->Name.c_str() : nullptr; - const char* preflight = this->GetComponentScript("PREFLIGHT", comp_name); - const char* postflight = this->GetComponentScript("POSTFLIGHT", comp_name); + cmValue preflight = this->GetComponentScript("PREFLIGHT", comp_name); + cmValue postflight = this->GetComponentScript("POSTFLIGHT", comp_name); std::string resDir = packageFileDir; if (component) { @@ -213,11 +214,11 @@ bool cmCPackProductBuildGenerator::GenerateComponentPackage( std::string version = this->GetOption("CPACK_PACKAGE_VERSION"); std::string pkgbuild = this->GetOption("CPACK_COMMAND_PKGBUILD"); std::string identityName; - if (const char* n = this->GetOption("CPACK_PKGBUILD_IDENTITY_NAME")) { + if (cmValue n = this->GetOption("CPACK_PKGBUILD_IDENTITY_NAME")) { identityName = n; } std::string keychainPath; - if (const char* p = this->GetOption("CPACK_PKGBUILD_KEYCHAIN_PATH")) { + if (cmValue p = this->GetOption("CPACK_PKGBUILD_KEYCHAIN_PATH")) { keychainPath = p; } @@ -239,7 +240,7 @@ bool cmCPackProductBuildGenerator::GenerateComponentPackage( return RunProductBuild(pkgCmd.str()); } -const char* cmCPackProductBuildGenerator::GetComponentScript( +cmValue cmCPackProductBuildGenerator::GetComponentScript( const char* script, const char* component_name) { std::string scriptname = std::string("CPACK_") + script + "_"; diff --git a/Source/CPack/cmCPackProductBuildGenerator.h b/Source/CPack/cmCPackProductBuildGenerator.h index 462e2fcc9..31cfafadf 100644 --- a/Source/CPack/cmCPackProductBuildGenerator.h +++ b/Source/CPack/cmCPackProductBuildGenerator.h @@ -8,6 +8,7 @@ #include "cmCPackGenerator.h" #include "cmCPackPKGGenerator.h" +#include "cmValue.h" class cmCPackComponent; @@ -45,6 +46,5 @@ protected: const std::string& packageDir, const cmCPackComponent* component); - const char* GetComponentScript(const char* script, - const char* script_component); + cmValue GetComponentScript(const char* script, const char* script_component); }; diff --git a/Source/CPack/cmCPackRPMGenerator.cxx b/Source/CPack/cmCPackRPMGenerator.cxx index c3f6d594b..9e50700c6 100644 --- a/Source/CPack/cmCPackRPMGenerator.cxx +++ b/Source/CPack/cmCPackRPMGenerator.cxx @@ -14,6 +14,7 @@ #include "cmCPackLog.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" cmCPackRPMGenerator::cmCPackRPMGenerator() = default; @@ -32,13 +33,13 @@ int cmCPackRPMGenerator::InitializeInternal() if (this->GetOption("CPACK_PACKAGE_NAME")) { std::string packageName = this->GetOption("CPACK_PACKAGE_NAME"); std::replace(packageName.begin(), packageName.end(), ' ', '-'); - this->SetOption("CPACK_PACKAGE_NAME", packageName.c_str()); + this->SetOption("CPACK_PACKAGE_NAME", packageName); } /* same for CPACK_PACKAGE_FILE_NAME */ if (this->GetOption("CPACK_PACKAGE_FILE_NAME")) { std::string packageName = this->GetOption("CPACK_PACKAGE_FILE_NAME"); std::replace(packageName.begin(), packageName.end(), ' ', '-'); - this->SetOption("CPACK_PACKAGE_FILE_NAME", packageName.c_str()); + this->SetOption("CPACK_PACKAGE_FILE_NAME", packageName); } return this->Superclass::InitializeInternal(); } @@ -73,19 +74,17 @@ int cmCPackRPMGenerator::PackageOnePack(std::string const& initialToplevel, localToplevel += "/" + packageName; /* replace the TEMP DIRECTORY with the component one */ - this->SetOption("CPACK_TEMPORARY_DIRECTORY", localToplevel.c_str()); + this->SetOption("CPACK_TEMPORARY_DIRECTORY", localToplevel); packageFileName += "/" + outputFileName; /* replace proposed CPACK_OUTPUT_FILE_NAME */ - this->SetOption("CPACK_OUTPUT_FILE_NAME", outputFileName.c_str()); + this->SetOption("CPACK_OUTPUT_FILE_NAME", outputFileName); /* replace the TEMPORARY package file name */ - this->SetOption("CPACK_TEMPORARY_PACKAGE_FILE_NAME", - packageFileName.c_str()); + this->SetOption("CPACK_TEMPORARY_PACKAGE_FILE_NAME", packageFileName); // Tell CPackRPM.cmake the name of the component NAME. - this->SetOption("CPACK_RPM_PACKAGE_COMPONENT", packageName.c_str()); + this->SetOption("CPACK_RPM_PACKAGE_COMPONENT", packageName); // Tell CPackRPM.cmake the path where the component is. std::string component_path = cmStrCat('/', packageName); - this->SetOption("CPACK_RPM_PACKAGE_COMPONENT_PART_PATH", - component_path.c_str()); + this->SetOption("CPACK_RPM_PACKAGE_COMPONENT_PART_PATH", component_path); if (!this->ReadListFile("Internal/CPack/CPackRPM.cmake")) { cmCPackLogger(cmCPackLog::LOG_ERROR, "Error while execution CPackRPM.cmake" << std::endl); @@ -103,7 +102,7 @@ int cmCPackRPMGenerator::PackageComponents(bool ignoreGroup) this->packageFileNames.clear(); std::string initialTopLevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY")); - const char* mainComponent = this->GetOption("CPACK_RPM_MAIN_COMPONENT"); + cmValue mainComponent = this->GetOption("CPACK_RPM_MAIN_COMPONENT"); if (this->IsOn("CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE") && !this->IsOn("CPACK_RPM_DEBUGINFO_PACKAGE")) { @@ -364,19 +363,17 @@ int cmCPackRPMGenerator::PackageComponentsAllInOne( localToplevel += "/" + compInstDirName; /* replace the TEMP DIRECTORY with the component one */ - this->SetOption("CPACK_TEMPORARY_DIRECTORY", localToplevel.c_str()); + this->SetOption("CPACK_TEMPORARY_DIRECTORY", localToplevel); packageFileName += "/" + outputFileName; /* replace proposed CPACK_OUTPUT_FILE_NAME */ - this->SetOption("CPACK_OUTPUT_FILE_NAME", outputFileName.c_str()); + this->SetOption("CPACK_OUTPUT_FILE_NAME", outputFileName); /* replace the TEMPORARY package file name */ - this->SetOption("CPACK_TEMPORARY_PACKAGE_FILE_NAME", - packageFileName.c_str()); + this->SetOption("CPACK_TEMPORARY_PACKAGE_FILE_NAME", packageFileName); if (!compInstDirName.empty()) { // Tell CPackRPM.cmake the path where the component is. std::string component_path = cmStrCat('/', compInstDirName); - this->SetOption("CPACK_RPM_PACKAGE_COMPONENT_PART_PATH", - component_path.c_str()); + this->SetOption("CPACK_RPM_PACKAGE_COMPONENT_PART_PATH", component_path); } if (this->ReadListFile("Internal/CPack/CPackRPM.cmake")) { diff --git a/Source/CPack/cmCPackSTGZGenerator.cxx b/Source/CPack/cmCPackSTGZGenerator.cxx index ad0a3e21b..1340fb59f 100644 --- a/Source/CPack/cmCPackSTGZGenerator.cxx +++ b/Source/CPack/cmCPackSTGZGenerator.cxx @@ -15,6 +15,7 @@ #include "cmCPackGenerator.h" #include "cmCPackLog.h" #include "cmSystemTools.h" +#include "cmValue.h" cmCPackSTGZGenerator::cmCPackSTGZGenerator() : cmCPackArchiveGenerator(cmArchiveWrite::CompressGZip, "paxr", ".sh") @@ -33,7 +34,7 @@ int cmCPackSTGZGenerator::InitializeInternal() "Cannot find template file: " << inFile << std::endl); return 0; } - this->SetOptionIfNotSet("CPACK_STGZ_HEADER_FILE", inFile.c_str()); + this->SetOptionIfNotSet("CPACK_STGZ_HEADER_FILE", inFile); this->SetOptionIfNotSet("CPACK_AT_SIGN", "@"); return this->Superclass::InitializeInternal(); @@ -78,8 +79,7 @@ int cmCPackSTGZGenerator::GenerateHeader(std::ostream* os) while (cmSystemTools::GetLineFromStream(ilfs, line)) { licenseText += line + "\n"; } - this->SetOptionIfNotSet("CPACK_RESOURCE_FILE_LICENSE_CONTENT", - licenseText.c_str()); + this->SetOptionIfNotSet("CPACK_RESOURCE_FILE_LICENSE_CONTENT", licenseText); const char headerLengthTag[] = "###CPACK_HEADER_LENGTH###"; diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx index a77893903..54fd3587c 100644 --- a/Source/CPack/cpack.cxx +++ b/Source/CPack/cpack.cxx @@ -22,11 +22,11 @@ #include "cmDocumentationFormatter.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" -#include "cmProperty.h" #include "cmState.h" #include "cmStateSnapshot.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" #include "cmake.h" namespace { @@ -326,11 +326,11 @@ int main(int argc, char const* const* argv) cmSystemTools::CollapseFullPath(cpackProjectDirectory); globalMF.AddDefinition("CPACK_PACKAGE_DIRECTORY", cpackProjectDirectory); - cmProp cpackModulesPath = globalMF.GetDefinition("CPACK_MODULE_PATH"); + cmValue cpackModulesPath = globalMF.GetDefinition("CPACK_MODULE_PATH"); if (cpackModulesPath) { globalMF.AddDefinition("CMAKE_MODULE_PATH", *cpackModulesPath); } - cmProp genList = globalMF.GetDefinition("CPACK_GENERATOR"); + cmValue genList = globalMF.GetDefinition("CPACK_GENERATOR"); if (!genList) { cmCPack_Log(&log, cmCPackLog::LOG_ERROR, "CPack generator not specified" << std::endl); @@ -408,20 +408,20 @@ int main(int argc, char const* const* argv) parsed = 0; } if (parsed) { - cmProp projName = mf->GetDefinition("CPACK_PACKAGE_NAME"); + cmValue projName = mf->GetDefinition("CPACK_PACKAGE_NAME"); cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE, "Use generator: " << cpackGenerator->GetNameOfClass() << std::endl); cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE, "For project: " << *projName << std::endl); - cmProp projVersion = mf->GetDefinition("CPACK_PACKAGE_VERSION"); + cmValue projVersion = mf->GetDefinition("CPACK_PACKAGE_VERSION"); if (!projVersion) { - cmProp projVersionMajor = + cmValue projVersionMajor = mf->GetDefinition("CPACK_PACKAGE_VERSION_MAJOR"); - cmProp projVersionMinor = + cmValue projVersionMinor = mf->GetDefinition("CPACK_PACKAGE_VERSION_MINOR"); - cmProp projVersionPatch = + cmValue projVersionPatch = mf->GetDefinition("CPACK_PACKAGE_VERSION_PATCH"); std::ostringstream ostr; ostr << *projVersionMajor << "." << *projVersionMinor << "." diff --git a/Source/CTest/cmCTestBuildCommand.cxx b/Source/CTest/cmCTestBuildCommand.cxx index 483c316a6..6e7c9e10f 100644 --- a/Source/CTest/cmCTestBuildCommand.cxx +++ b/Source/CTest/cmCTestBuildCommand.cxx @@ -11,9 +11,9 @@ #include "cmGlobalGenerator.h" #include "cmMakefile.h" #include "cmMessageType.h" -#include "cmProperty.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" #include "cmake.h" class cmExecutionStatus; @@ -39,13 +39,13 @@ cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler() this->Handler = handler; - cmProp ctestBuildCommand = + cmValue ctestBuildCommand = this->Makefile->GetDefinition("CTEST_BUILD_COMMAND"); if (cmNonempty(ctestBuildCommand)) { this->CTest->SetCTestConfiguration("MakeCommand", *ctestBuildCommand, this->Quiet); } else { - cmProp cmakeGeneratorName = + cmValue cmakeGeneratorName = this->Makefile->GetDefinition("CTEST_CMAKE_GENERATOR"); // Build configuration is determined by: CONFIGURATION argument, @@ -53,7 +53,7 @@ cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler() // CTEST_CONFIGURATION_TYPE script variable, or ctest -C command // line argument... in that order. // - cmProp ctestBuildConfiguration = + cmValue ctestBuildConfiguration = this->Makefile->GetDefinition("CTEST_BUILD_CONFIGURATION"); std::string cmakeBuildConfiguration = cmNonempty(this->Configuration) ? this->Configuration @@ -119,13 +119,13 @@ cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler() } } - if (cmProp useLaunchers = + if (cmValue useLaunchers = this->Makefile->GetDefinition("CTEST_USE_LAUNCHERS")) { this->CTest->SetCTestConfiguration("UseLaunchers", *useLaunchers, this->Quiet); } - if (cmProp labelsForSubprojects = + if (cmValue labelsForSubprojects = this->Makefile->GetDefinition("CTEST_LABELS_FOR_SUBPROJECTS")) { this->CTest->SetCTestConfiguration("LabelsForSubprojects", *labelsForSubprojects, this->Quiet); diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx index 03caa6372..f9c4a8e35 100644 --- a/Source/CTest/cmCTestBuildHandler.cxx +++ b/Source/CTest/cmCTestBuildHandler.cxx @@ -19,10 +19,10 @@ #include "cmGeneratedFileStream.h" #include "cmMakefile.h" #include "cmProcessOutput.h" -#include "cmProperty.h" #include "cmStringAlgorithms.h" #include "cmStringReplaceHelper.h" #include "cmSystemTools.h" +#include "cmValue.h" #include "cmXMLWriter.h" static const char* cmCTestErrorMatches[] = { @@ -249,11 +249,11 @@ void cmCTestBuildHandler::PopulateCustomVectors(cmMakefile* mf) } // Record the user-specified custom warning rules. - if (cmProp customWarningMatchers = + if (cmValue customWarningMatchers = mf->GetDefinition("CTEST_CUSTOM_WARNING_MATCH")) { cmExpandList(*customWarningMatchers, this->ReallyCustomWarningMatches); } - if (cmProp customWarningExceptions = + if (cmValue customWarningExceptions = mf->GetDefinition("CTEST_CUSTOM_WARNING_EXCEPTION")) { cmExpandList(*customWarningExceptions, this->ReallyCustomWarningExceptions); diff --git a/Source/CTest/cmCTestConfigureCommand.cxx b/Source/CTest/cmCTestConfigureCommand.cxx index db9923e95..fd20398d2 100644 --- a/Source/CTest/cmCTestConfigureCommand.cxx +++ b/Source/CTest/cmCTestConfigureCommand.cxx @@ -12,9 +12,9 @@ #include "cmCTestConfigureHandler.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" -#include "cmProperty.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" #include "cmake.h" void cmCTestConfigureCommand::BindArguments() @@ -39,14 +39,14 @@ cmCTestGenericHandler* cmCTestConfigureCommand::InitializeHandler() return nullptr; } - cmProp ctestConfigureCommand = + cmValue ctestConfigureCommand = this->Makefile->GetDefinition("CTEST_CONFIGURE_COMMAND"); if (cmNonempty(ctestConfigureCommand)) { this->CTest->SetCTestConfiguration("ConfigureCommand", *ctestConfigureCommand, this->Quiet); } else { - cmProp cmakeGeneratorName = + cmValue cmakeGeneratorName = this->Makefile->GetDefinition("CTEST_CMAKE_GENERATOR"); if (cmNonempty(cmakeGeneratorName)) { const std::string& source_dir = @@ -106,7 +106,7 @@ cmCTestGenericHandler* cmCTestConfigureCommand::InitializeHandler() cmakeConfigureCommand += *cmakeGeneratorName; cmakeConfigureCommand += "\""; - cmProp cmakeGeneratorPlatform = + cmValue cmakeGeneratorPlatform = this->Makefile->GetDefinition("CTEST_CMAKE_GENERATOR_PLATFORM"); if (cmNonempty(cmakeGeneratorPlatform)) { cmakeConfigureCommand += " \"-A"; @@ -114,7 +114,7 @@ cmCTestGenericHandler* cmCTestConfigureCommand::InitializeHandler() cmakeConfigureCommand += "\""; } - cmProp cmakeGeneratorToolset = + cmValue cmakeGeneratorToolset = this->Makefile->GetDefinition("CTEST_CMAKE_GENERATOR_TOOLSET"); if (cmNonempty(cmakeGeneratorToolset)) { cmakeConfigureCommand += " \"-T"; @@ -137,7 +137,7 @@ cmCTestGenericHandler* cmCTestConfigureCommand::InitializeHandler() } } - if (cmProp labelsForSubprojects = + if (cmValue labelsForSubprojects = this->Makefile->GetDefinition("CTEST_LABELS_FOR_SUBPROJECTS")) { this->CTest->SetCTestConfiguration("LabelsForSubprojects", *labelsForSubprojects, this->Quiet); diff --git a/Source/CTest/cmCTestGIT.cxx b/Source/CTest/cmCTestGIT.cxx index 568b0917c..d85edcc5f 100644 --- a/Source/CTest/cmCTestGIT.cxx +++ b/Source/CTest/cmCTestGIT.cxx @@ -18,6 +18,7 @@ #include "cmProcessTools.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" static unsigned int cmCTestGITVersion(unsigned int epic, unsigned int major, unsigned int minor, unsigned int fix) diff --git a/Source/CTest/cmCTestGenericHandler.cxx b/Source/CTest/cmCTestGenericHandler.cxx index 48cc0e450..9800192ca 100644 --- a/Source/CTest/cmCTestGenericHandler.cxx +++ b/Source/CTest/cmCTestGenericHandler.cxx @@ -21,11 +21,12 @@ cmCTestGenericHandler::cmCTestGenericHandler() cmCTestGenericHandler::~cmCTestGenericHandler() = default; +namespace { /* 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) +void SetMapValue(cmCTestGenericHandler::t_StringToString& map, + const std::string& op, const char* value) { if (!value) { map.erase(op); @@ -34,11 +35,26 @@ static void SetMapValue(cmCTestGenericHandler::t_StringToString& map, map[op] = value; } +void SetMapValue(cmCTestGenericHandler::t_StringToString& map, + const std::string& op, cmValue value) +{ + if (!value) { + map.erase(op); + return; + } + + map[op] = *value; +} +} void cmCTestGenericHandler::SetOption(const std::string& op, const char* value) { SetMapValue(this->Options, op, value); } +void cmCTestGenericHandler::SetOption(const std::string& op, cmValue value) +{ + SetMapValue(this->Options, op, value); +} void cmCTestGenericHandler::SetPersistentOption(const std::string& op, const char* value) @@ -46,6 +62,12 @@ void cmCTestGenericHandler::SetPersistentOption(const std::string& op, this->SetOption(op, value); SetMapValue(this->PersistentOptions, op, value); } +void cmCTestGenericHandler::SetPersistentOption(const std::string& op, + cmValue value) +{ + this->SetOption(op, value); + SetMapValue(this->PersistentOptions, op, value); +} void cmCTestGenericHandler::AddMultiOption(const std::string& op, const std::string& value) @@ -72,13 +94,13 @@ void cmCTestGenericHandler::Initialize() this->MultiOptions = this->PersistentMultiOptions; } -const char* cmCTestGenericHandler::GetOption(const std::string& op) +cmValue cmCTestGenericHandler::GetOption(const std::string& op) { auto remit = this->Options.find(op); if (remit == this->Options.end()) { return nullptr; } - return remit->second.c_str(); + return cmValue(remit->second); } std::vector<std::string> cmCTestGenericHandler::GetMultiOption( diff --git a/Source/CTest/cmCTestGenericHandler.h b/Source/CTest/cmCTestGenericHandler.h index e846fd956..b4b0ad8a2 100644 --- a/Source/CTest/cmCTestGenericHandler.h +++ b/Source/CTest/cmCTestGenericHandler.h @@ -12,6 +12,7 @@ #include "cmCTest.h" #include "cmSystemTools.h" +#include "cmValue.h" class cmGeneratedFileStream; class cmMakefile; @@ -86,8 +87,18 @@ public: * as a multi-value will return nullptr. */ void SetPersistentOption(const std::string& op, const char* value); + void SetPersistentOption(const std::string& op, const std::string& value) + { + this->SetPersistentOption(op, cmValue(value)); + } + void SetPersistentOption(const std::string& op, cmValue value); void SetOption(const std::string& op, const char* value); - const char* GetOption(const std::string& op); + void SetOption(const std::string& op, const std::string& value) + { + this->SetOption(op, cmValue(value)); + } + void SetOption(const std::string& op, cmValue value); + cmValue GetOption(const std::string& op); /** * Multi-Options collect one or more values from flags; passing diff --git a/Source/CTest/cmCTestHandlerCommand.cxx b/Source/CTest/cmCTestHandlerCommand.cxx index 731932e38..ea8feaa9f 100644 --- a/Source/CTest/cmCTestHandlerCommand.cxx +++ b/Source/CTest/cmCTestHandlerCommand.cxx @@ -14,9 +14,9 @@ #include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmMessageType.h" -#include "cmProperty.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" #include "cmWorkingDirectory.h" namespace { @@ -126,7 +126,7 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args, // CTEST_CONFIGURATION_TYPE script variable if it is defined. // The current script value trumps the -C argument on the command // line. - cmProp ctestConfigType = + cmValue ctestConfigType = this->Makefile->GetDefinition("CTEST_CONFIGURATION_TYPE"); if (ctestConfigType) { this->CTest->SetConfigType(*ctestConfigType); @@ -161,7 +161,7 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args, this->Quiet); } - if (cmProp changeId = this->Makefile->GetDefinition("CTEST_CHANGE_ID")) { + if (cmValue changeId = this->Makefile->GetDefinition("CTEST_CHANGE_ID")) { this->CTest->SetCTestConfiguration("ChangeId", *changeId, this->Quiet); } diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx index 125d0034d..6bb8e79c1 100644 --- a/Source/CTest/cmCTestMemCheckHandler.cxx +++ b/Source/CTest/cmCTestMemCheckHandler.cxx @@ -305,7 +305,7 @@ int cmCTestMemCheckHandler::GetDefectCount() const return this->DefectCount; } -void cmCTestMemCheckHandler::GenerateDartOutput(cmXMLWriter& xml) +void cmCTestMemCheckHandler::GenerateCTestXML(cmXMLWriter& xml) { if (!this->CTest->GetProduceXML()) { return; diff --git a/Source/CTest/cmCTestMemCheckHandler.h b/Source/CTest/cmCTestMemCheckHandler.h index b200c4394..a63a24df1 100644 --- a/Source/CTest/cmCTestMemCheckHandler.h +++ b/Source/CTest/cmCTestMemCheckHandler.h @@ -119,9 +119,9 @@ private: bool InitializeMemoryChecking(); /** - * Generate the Dart compatible output + * Generate CTest DynamicAnalysis.xml files */ - void GenerateDartOutput(cmXMLWriter& xml) override; + void GenerateCTestXML(cmXMLWriter& xml) override; std::vector<std::string> CustomPreMemCheck; std::vector<std::string> CustomPostMemCheck; diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx index 86a8e00a6..d90c4a646 100644 --- a/Source/CTest/cmCTestMultiProcessHandler.cxx +++ b/Source/CTest/cmCTestMultiProcessHandler.cxx @@ -1026,6 +1026,11 @@ static Json::Value DumpCTestProperties( properties.append(DumpCTestProperty( "ENVIRONMENT", DumpToJsonArray(testProperties.Environment))); } + if (!testProperties.EnvironmentModification.empty()) { + properties.append(DumpCTestProperty( + "ENVIRONMENT_MODIFICATION", + DumpToJsonArray(testProperties.EnvironmentModification))); + } if (!testProperties.ErrorRegularExpressions.empty()) { properties.append(DumpCTestProperty( "FAIL_REGULAR_EXPRESSION", diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx index a8921134b..9d2cef69f 100644 --- a/Source/CTest/cmCTestRunTest.cxx +++ b/Source/CTest/cmCTestRunTest.cxx @@ -2,17 +2,22 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCTestRunTest.h" +#include <algorithm> #include <chrono> #include <cstddef> // IWYU pragma: keep #include <cstdint> #include <cstdio> #include <cstring> +#include <functional> #include <iomanip> #include <ratio> #include <sstream> #include <utility> #include <cm/memory> +#include <cm/optional> +#include <cm/string_view> +#include <cmext/string_view> #include "cmsys/RegularExpression.hxx" @@ -44,7 +49,9 @@ void cmCTestRunTest::CheckOutput(std::string const& line) // Check for special CTest XML tags in this line of output. // If any are found, this line is excluded from ProcessOutput. if (!line.empty() && line.find("<CTest") != std::string::npos) { + bool ctest_tag_found = false; if (this->TestHandler->CustomCompletionStatusRegex.find(line)) { + ctest_tag_found = true; this->TestResult.CustomCompletionStatus = this->TestHandler->CustomCompletionStatusRegex.match(1); cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, @@ -52,6 +59,20 @@ void cmCTestRunTest::CheckOutput(std::string const& line) << "Test Details changed to '" << this->TestResult.CustomCompletionStatus << "'" << std::endl); + } else if (this->TestHandler->CustomLabelRegex.find(line)) { + ctest_tag_found = true; + auto label = this->TestHandler->CustomLabelRegex.match(1); + auto& labels = this->TestProperties->Labels; + if (std::find(labels.begin(), labels.end(), label) == labels.end()) { + labels.push_back(label); + std::sort(labels.begin(), labels.end()); + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + this->GetIndex() + << ": " + << "Test Label added: '" << label << "'" << std::endl); + } + } + if (ctest_tag_found) { return; } } @@ -245,7 +266,7 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started) *this->TestHandler->LogFile << "Test time = " << buf << std::endl; } - this->DartProcessing(); + this->ParseOutputForMeasurements(); // if this is doing MemCheck then all the output needs to be put into // Output since that is what is parsed by cmCTestMemCheckHandler @@ -623,6 +644,7 @@ bool cmCTestRunTest::StartTest(size_t completed, size_t total) return this->ForkProcess(timeout, this->TestProperties->ExplicitTimeout, &this->TestProperties->Environment, + &this->TestProperties->EnvironmentModification, &this->TestProperties->Affinity); } @@ -679,28 +701,45 @@ void cmCTestRunTest::ComputeArguments() cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, this->Index << ": " << env << std::endl); } + if (!this->TestProperties->EnvironmentModification.empty()) { + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + this->Index << ": " + << "Environment variable modifications: " + << std::endl); + } + for (std::string const& envmod : + this->TestProperties->EnvironmentModification) { + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + this->Index << ": " << envmod << std::endl); + } } -void cmCTestRunTest::DartProcessing() +void cmCTestRunTest::ParseOutputForMeasurements() { if (!this->ProcessOutput.empty() && - this->ProcessOutput.find("<DartMeasurement") != std::string::npos) { - if (this->TestHandler->DartStuff.find(this->ProcessOutput)) { - this->TestResult.DartString = this->TestHandler->DartStuff.match(1); + (this->ProcessOutput.find("<DartMeasurement") != std::string::npos || + this->ProcessOutput.find("<CTestMeasurement") != std::string::npos)) { + if (this->TestHandler->AllTestMeasurementsRegex.find( + this->ProcessOutput)) { + this->TestResult.TestMeasurementsOutput = + this->TestHandler->AllTestMeasurementsRegex.match(1); // keep searching and replacing until none are left - while (this->TestHandler->DartStuff1.find(this->ProcessOutput)) { + while (this->TestHandler->SingleTestMeasurementRegex.find( + this->ProcessOutput)) { // replace the exact match for the string cmSystemTools::ReplaceString( - this->ProcessOutput, this->TestHandler->DartStuff1.match(1).c_str(), - ""); + this->ProcessOutput, + this->TestHandler->SingleTestMeasurementRegex.match(1).c_str(), ""); } } } } -bool cmCTestRunTest::ForkProcess(cmDuration testTimeOut, bool explicitTimeout, - std::vector<std::string>* environment, - std::vector<size_t>* affinity) +bool cmCTestRunTest::ForkProcess( + cmDuration testTimeOut, bool explicitTimeout, + std::vector<std::string>* environment, + std::vector<std::string>* environment_modification, + std::vector<size_t>* affinity) { this->TestProcess->SetId(this->Index); this->TestProcess->SetWorkingDirectory(this->TestProperties->Directory); @@ -743,12 +782,145 @@ bool cmCTestRunTest::ForkProcess(cmDuration testTimeOut, bool explicitTimeout, std::ostringstream envMeasurement; if (environment && !environment->empty()) { + // Environment modification works on the assumption that the environment is + // actually modified here. If another strategy is used, there will need to + // be updates below in `apply_diff`. cmSystemTools::AppendEnv(*environment); for (auto const& var : *environment) { envMeasurement << var << std::endl; } } + if (environment_modification && !environment_modification->empty()) { + std::map<std::string, cm::optional<std::string>> env_application; + +#ifdef _WIN32 + char path_sep = ';'; +#else + char path_sep = ':'; +#endif + + auto apply_diff = + [&env_application](const std::string& name, + std::function<void(std::string&)> const& apply) { + cm::optional<std::string> old_value = env_application[name]; + std::string output; + if (old_value) { + output = *old_value; + } else { + // This only works because the environment is actually modified above + // (`AppendEnv`). If CTest ever just creates an environment block + // directly, that block will need to be queried for the subprocess' + // value instead. + const char* curval = cmSystemTools::GetEnv(name); + if (curval) { + output = curval; + } + } + apply(output); + env_application[name] = output; + }; + + bool err_occurred = false; + + for (auto const& envmod : *environment_modification) { + // Split on `=` + auto const eq_loc = envmod.find_first_of('='); + if (eq_loc == std::string::npos) { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Error: Missing `=` after the variable name in: " + << envmod << std::endl); + err_occurred = true; + continue; + } + auto const name = envmod.substr(0, eq_loc); + + // Split value on `:` + auto const op_value_start = eq_loc + 1; + auto const colon_loc = envmod.find_first_of(':', op_value_start); + if (colon_loc == std::string::npos) { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Error: Missing `:` after the operation in: " << envmod + << std::endl); + err_occurred = true; + continue; + } + auto const op = + envmod.substr(op_value_start, colon_loc - op_value_start); + + auto const value_start = colon_loc + 1; + auto const value = envmod.substr(value_start); + + // Determine what to do with the operation. + if (op == "reset"_s) { + auto entry = env_application.find(name); + if (entry != env_application.end()) { + env_application.erase(entry); + } + } else if (op == "set"_s) { + env_application[name] = value; + } else if (op == "unset"_s) { + env_application[name] = {}; + } else if (op == "string_append"_s) { + apply_diff(name, [&value](std::string& output) { output += value; }); + } else if (op == "string_prepend"_s) { + apply_diff(name, + [&value](std::string& output) { output.insert(0, value); }); + } else if (op == "path_list_append"_s) { + apply_diff(name, [&value, path_sep](std::string& output) { + if (!output.empty()) { + output += path_sep; + } + output += value; + }); + } else if (op == "path_list_prepend"_s) { + apply_diff(name, [&value, path_sep](std::string& output) { + if (!output.empty()) { + output.insert(output.begin(), path_sep); + } + output.insert(0, value); + }); + } else if (op == "cmake_list_append"_s) { + apply_diff(name, [&value](std::string& output) { + if (!output.empty()) { + output += ';'; + } + output += value; + }); + } else if (op == "cmake_list_prepend"_s) { + apply_diff(name, [&value](std::string& output) { + if (!output.empty()) { + output.insert(output.begin(), ';'); + } + output.insert(0, value); + }); + } else { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Error: Unrecognized environment manipulation argument: " + << op << std::endl); + err_occurred = true; + continue; + } + } + + if (err_occurred) { + return false; + } + + for (auto const& env_apply : env_application) { + if (env_apply.second) { + auto const env_update = + cmStrCat(env_apply.first, '=', *env_apply.second); + cmSystemTools::PutEnv(env_update); + envMeasurement << env_update << std::endl; + } else { + cmSystemTools::UnsetEnv(env_apply.first.c_str()); + // Signify that this variable is being actively unset + envMeasurement << "#" << env_apply.first << "=" << std::endl; + } + } + } + if (this->UseAllocatedResources) { std::vector<std::string> envLog; this->SetupResourcesEnvironment(&envLog); diff --git a/Source/CTest/cmCTestRunTest.h b/Source/CTest/cmCTestRunTest.h index 863ac1bfd..2082156b8 100644 --- a/Source/CTest/cmCTestRunTest.h +++ b/Source/CTest/cmCTestRunTest.h @@ -109,10 +109,11 @@ public: private: bool NeedsToRepeat(); - void DartProcessing(); + void ParseOutputForMeasurements(); void ExeNotFound(std::string exe); bool ForkProcess(cmDuration testTimeOut, bool explicitTimeout, std::vector<std::string>* environment, + std::vector<std::string>* environment_modification, std::vector<size_t>* affinity); void WriteLogOutputTop(size_t completed, size_t total); // Run post processing of the process output for MemCheck diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx index d2cad3992..f685f6681 100644 --- a/Source/CTest/cmCTestScriptHandler.cxx +++ b/Source/CTest/cmCTestScriptHandler.cxx @@ -34,12 +34,12 @@ #include "cmGeneratedFileStream.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" -#include "cmProperty.h" #include "cmState.h" #include "cmStateDirectory.h" #include "cmStateSnapshot.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" #include "cmake.h" #ifdef _WIN32 @@ -372,8 +372,8 @@ int cmCTestScriptHandler::ReadInScript(const std::string& total_script_arg) int cmCTestScriptHandler::ExtractVariables() { // Temporary variables - cmProp minInterval; - cmProp contDuration; + cmValue minInterval; + cmValue contDuration; this->SourceDir = this->Makefile->GetSafeDefinition("CTEST_SOURCE_DIRECTORY"); @@ -412,7 +412,7 @@ int cmCTestScriptHandler::ExtractVariables() int i; for (i = 1; i < 10; ++i) { sprintf(updateVar, "CTEST_EXTRA_UPDATES_%i", i); - cmProp updateVal = this->Makefile->GetDefinition(updateVar); + cmValue updateVal = this->Makefile->GetDefinition(updateVar); if (updateVal) { if (this->UpdateCmd.empty()) { cmSystemTools::Error( @@ -930,7 +930,7 @@ cmDuration cmCTestScriptHandler::GetRemainingTimeAllowed() return cmCTest::MaxDuration(); } - cmProp timelimitS = this->Makefile->GetDefinition("CTEST_TIME_LIMIT"); + cmValue timelimitS = this->Makefile->GetDefinition("CTEST_TIME_LIMIT"); if (!timelimitS) { return cmCTest::MaxDuration(); diff --git a/Source/CTest/cmCTestStartCommand.cxx b/Source/CTest/cmCTestStartCommand.cxx index 53e1b2f96..84d12d77b 100644 --- a/Source/CTest/cmCTestStartCommand.cxx +++ b/Source/CTest/cmCTestStartCommand.cxx @@ -9,8 +9,8 @@ #include "cmCTestVC.h" #include "cmGeneratedFileStream.h" #include "cmMakefile.h" -#include "cmProperty.h" #include "cmSystemTools.h" +#include "cmValue.h" class cmExecutionStatus; @@ -30,8 +30,8 @@ bool cmCTestStartCommand::InitialPass(std::vector<std::string> const& args, size_t cnt = 0; const char* smodel = nullptr; - const std::string* src_dir = nullptr; - const std::string* bld_dir = nullptr; + cmValue src_dir; + cmValue bld_dir; while (cnt < args.size()) { if (args[cnt] == "GROUP" || args[cnt] == "TRACK") { @@ -55,10 +55,10 @@ bool cmCTestStartCommand::InitialPass(std::vector<std::string> const& args, smodel = args[cnt].c_str(); cnt++; } else if (!src_dir) { - src_dir = &args[cnt]; + src_dir = cmValue(args[cnt]); cnt++; } else if (!bld_dir) { - bld_dir = &args[cnt]; + bld_dir = cmValue(args[cnt]); cnt++; } else { this->SetError("Too many arguments"); @@ -162,7 +162,7 @@ bool cmCTestStartCommand::InitialCheckout(std::ostream& ofs, std::string const& sourceDir) { // Use the user-provided command to create the source tree. - cmProp initialCheckoutCommand = + cmValue initialCheckoutCommand = this->Makefile->GetDefinition("CTEST_CHECKOUT_COMMAND"); if (!initialCheckoutCommand) { initialCheckoutCommand = diff --git a/Source/CTest/cmCTestSubmitCommand.cxx b/Source/CTest/cmCTestSubmitCommand.cxx index bdba0e5d2..c4f87e993 100644 --- a/Source/CTest/cmCTestSubmitCommand.cxx +++ b/Source/CTest/cmCTestSubmitCommand.cxx @@ -16,10 +16,10 @@ #include "cmCommand.h" #include "cmMakefile.h" #include "cmMessageType.h" -#include "cmProperty.h" #include "cmRange.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" class cmExecutionStatus; @@ -36,8 +36,8 @@ std::unique_ptr<cmCommand> cmCTestSubmitCommand::Clone() cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler() { - const std::string* submitURL = !this->SubmitURL.empty() - ? &this->SubmitURL + cmValue submitURL = !this->SubmitURL.empty() + ? cmValue(this->SubmitURL) : this->Makefile->GetDefinition("CTEST_SUBMIT_URL"); if (submitURL) { @@ -59,14 +59,14 @@ cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler() this->CTest->SetCTestConfigurationFromCMakeVariable( this->Makefile, "CurlOptions", "CTEST_CURL_OPTIONS", this->Quiet); - cmProp notesFilesVariable = + cmValue notesFilesVariable = this->Makefile->GetDefinition("CTEST_NOTES_FILES"); if (notesFilesVariable) { std::vector<std::string> notesFiles = cmExpandedList(*notesFilesVariable); this->CTest->GenerateNotesFile(notesFiles); } - cmProp extraFilesVariable = + cmValue extraFilesVariable = this->Makefile->GetDefinition("CTEST_EXTRA_SUBMIT_FILES"); if (extraFilesVariable) { std::vector<std::string> extraFiles = cmExpandedList(*extraFilesVariable); @@ -119,15 +119,15 @@ cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler() handler->SetHttpHeaders(this->HttpHeaders); } - handler->SetOption("RetryDelay", this->RetryDelay.c_str()); - handler->SetOption("RetryCount", this->RetryCount.c_str()); + handler->SetOption("RetryDelay", this->RetryDelay); + handler->SetOption("RetryCount", this->RetryCount); handler->SetOption("InternalTest", this->InternalTest ? "ON" : "OFF"); handler->SetQuiet(this->Quiet); if (this->CDashUpload) { - handler->SetOption("CDashUploadFile", this->CDashUploadFile.c_str()); - handler->SetOption("CDashUploadType", this->CDashUploadType.c_str()); + handler->SetOption("CDashUploadFile", this->CDashUploadFile); + handler->SetOption("CDashUploadType", this->CDashUploadType); } return handler; } diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx index 5b54573f3..b99bb79d1 100644 --- a/Source/CTest/cmCTestSubmitHandler.cxx +++ b/Source/CTest/cmCTestSubmitHandler.cxx @@ -21,10 +21,10 @@ #include "cmCurl.h" #include "cmDuration.h" #include "cmGeneratedFileStream.h" -#include "cmProperty.h" #include "cmState.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" #include "cmXMLParser.h" #include "cmake.h" @@ -261,7 +261,7 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP( cmCTestScriptHandler* ch = this->CTest->GetScriptHandler(); cmake* cm = ch->GetCMake(); if (cm) { - cmProp subproject = cm->GetState()->GetGlobalProperty("SubProject"); + cmValue subproject = cm->GetState()->GetGlobalProperty("SubProject"); if (subproject) { upload_as += "&subproject="; upload_as += ctest_curl.Escape(*subproject); @@ -357,12 +357,8 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP( // If curl failed for any reason, or checksum fails, wait and retry // if (res != CURLE_OK || this->HasErrors) { - std::string retryDelay = this->GetOption("RetryDelay") == nullptr - ? "" - : this->GetOption("RetryDelay"); - std::string retryCount = this->GetOption("RetryCount") == nullptr - ? "" - : this->GetOption("RetryCount"); + std::string retryDelay = *this->GetOption("RetryDelay"); + std::string retryCount = *this->GetOption("RetryCount"); auto delay = cmDuration( retryDelay.empty() @@ -522,12 +518,8 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file, bool internalTest = cmIsOn(this->GetOption("InternalTest")); // Get RETRY_COUNT and RETRY_DELAY values if they were set. - std::string retryDelayString = this->GetOption("RetryDelay") == nullptr - ? "" - : this->GetOption("RetryDelay"); - std::string retryCountString = this->GetOption("RetryCount") == nullptr - ? "" - : this->GetOption("RetryCount"); + std::string retryDelayString = *this->GetOption("RetryDelay"); + std::string retryCountString = *this->GetOption("RetryCount"); auto retryDelay = std::chrono::seconds(0); if (!retryDelayString.empty()) { unsigned long retryDelayValue = 0; @@ -556,7 +548,7 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file, // a "&subproject=subprojectname" to the first POST. cmCTestScriptHandler* ch = this->CTest->GetScriptHandler(); cmake* cm = ch->GetCMake(); - cmProp subproject = cm->GetState()->GetGlobalProperty("SubProject"); + cmValue subproject = cm->GetState()->GetGlobalProperty("SubProject"); // TODO: Encode values for a URL instead of trusting caller. std::ostringstream str; if (subproject) { @@ -716,8 +708,8 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file, int cmCTestSubmitHandler::ProcessHandler() { - const char* cdashUploadFile = this->GetOption("CDashUploadFile"); - const char* cdashUploadType = this->GetOption("CDashUploadType"); + cmValue cdashUploadFile = this->GetOption("CDashUploadFile"); + cmValue cdashUploadType = this->GetOption("CDashUploadType"); if (cdashUploadFile && cdashUploadType) { return this->HandleCDashUploadFile(cdashUploadFile, cdashUploadType); } @@ -804,6 +796,7 @@ int cmCTestSubmitHandler::ProcessHandler() } } this->CTest->AddIfExists(cmCTest::PartMemCheck, "DynamicAnalysis.xml"); + this->CTest->AddIfExists(cmCTest::PartMemCheck, "DynamicAnalysis-Test.xml"); this->CTest->AddIfExists(cmCTest::PartMemCheck, "Purify.xml"); this->CTest->AddIfExists(cmCTest::PartNotes, "Notes.xml"); this->CTest->AddIfExists(cmCTest::PartUpload, "Upload.xml"); diff --git a/Source/CTest/cmCTestTestCommand.cxx b/Source/CTest/cmCTestTestCommand.cxx index 67f498608..5488388c8 100644 --- a/Source/CTest/cmCTestTestCommand.cxx +++ b/Source/CTest/cmCTestTestCommand.cxx @@ -12,8 +12,8 @@ #include "cmCTestTestHandler.h" #include "cmDuration.h" #include "cmMakefile.h" -#include "cmProperty.h" #include "cmStringAlgorithms.h" +#include "cmValue.h" void cmCTestTestCommand::BindArguments() { @@ -40,7 +40,7 @@ void cmCTestTestCommand::BindArguments() cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler() { - cmProp ctestTimeout = this->Makefile->GetDefinition("CTEST_TEST_TIMEOUT"); + cmValue ctestTimeout = this->Makefile->GetDefinition("CTEST_TEST_TIMEOUT"); cmDuration timeout; if (ctestTimeout) { @@ -54,7 +54,7 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler() } this->CTest->SetTimeOut(timeout); - cmProp resourceSpecFile = + cmValue resourceSpecFile = this->Makefile->GetDefinition("CTEST_RESOURCE_SPEC_FILE"); if (this->ResourceSpecFile.empty() && resourceSpecFile) { this->ResourceSpecFile = *resourceSpecFile; @@ -64,13 +64,13 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler() if (!this->Start.empty() || !this->End.empty() || !this->Stride.empty()) { handler->SetOption( "TestsToRunInformation", - cmStrCat(this->Start, ',', this->End, ',', this->Stride).c_str()); + cmStrCat(this->Start, ',', this->End, ',', this->Stride)); } if (!this->Exclude.empty()) { - handler->SetOption("ExcludeRegularExpression", this->Exclude.c_str()); + handler->SetOption("ExcludeRegularExpression", this->Exclude); } if (!this->Include.empty()) { - handler->SetOption("IncludeRegularExpression", this->Include.c_str()); + handler->SetOption("IncludeRegularExpression", this->Include); } if (!this->ExcludeLabel.empty()) { handler->AddMultiOption("ExcludeLabelRegularExpression", @@ -81,30 +81,30 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler() } if (!this->ExcludeFixture.empty()) { handler->SetOption("ExcludeFixtureRegularExpression", - this->ExcludeFixture.c_str()); + this->ExcludeFixture); } if (!this->ExcludeFixtureSetup.empty()) { handler->SetOption("ExcludeFixtureSetupRegularExpression", - this->ExcludeFixtureSetup.c_str()); + this->ExcludeFixtureSetup); } if (!this->ExcludeFixtureCleanup.empty()) { handler->SetOption("ExcludeFixtureCleanupRegularExpression", - this->ExcludeFixtureCleanup.c_str()); + this->ExcludeFixtureCleanup); } if (this->StopOnFailure) { handler->SetOption("StopOnFailure", "ON"); } if (!this->ParallelLevel.empty()) { - handler->SetOption("ParallelLevel", this->ParallelLevel.c_str()); + handler->SetOption("ParallelLevel", this->ParallelLevel); } if (!this->Repeat.empty()) { - handler->SetOption("Repeat", this->Repeat.c_str()); + handler->SetOption("Repeat", this->Repeat); } if (!this->ScheduleRandom.empty()) { - handler->SetOption("ScheduleRandom", this->ScheduleRandom.c_str()); + handler->SetOption("ScheduleRandom", this->ScheduleRandom); } if (!this->ResourceSpecFile.empty()) { - handler->SetOption("ResourceSpecFile", this->ResourceSpecFile.c_str()); + handler->SetOption("ResourceSpecFile", this->ResourceSpecFile); } if (!this->StopTime.empty()) { this->CTest->SetStopTime(this->StopTime); @@ -114,7 +114,7 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler() // or CTEST_TEST_LOAD script variable, or ctest --test-load // command line argument... in that order. unsigned long testLoad; - cmProp ctestTestLoad = this->Makefile->GetDefinition("CTEST_TEST_LOAD"); + cmValue ctestTestLoad = this->Makefile->GetDefinition("CTEST_TEST_LOAD"); if (!this->TestLoad.empty()) { if (!cmStrToULong(this->TestLoad, &testLoad)) { testLoad = 0; @@ -134,7 +134,7 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler() } handler->SetTestLoad(testLoad); - if (cmProp labelsForSubprojects = + if (cmValue labelsForSubprojects = this->Makefile->GetDefinition("CTEST_LABELS_FOR_SUBPROJECTS")) { this->CTest->SetCTestConfiguration("LabelsForSubprojects", *labelsForSubprojects, this->Quiet); diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx index 730ec0f04..6e97a8345 100644 --- a/Source/CTest/cmCTestTestHandler.cxx +++ b/Source/CTest/cmCTestTestHandler.cxx @@ -32,17 +32,18 @@ #include "cmCTest.h" #include "cmCTestMultiProcessHandler.h" #include "cmCTestResourceGroupsLexerHelper.h" +#include "cmCTestTestMeasurementXMLParser.h" #include "cmDuration.h" #include "cmExecutionStatus.h" #include "cmGeneratedFileStream.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" -#include "cmProperty.h" #include "cmState.h" #include "cmStateSnapshot.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTimestamp.h" +#include "cmValue.h" #include "cmWorkingDirectory.h" #include "cmXMLWriter.h" #include "cmake.h" @@ -303,15 +304,24 @@ cmCTestTestHandler::cmCTestTestHandler() // 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> - this->DartStuff1.compile( - "(<DartMeasurement[^<]*</DartMeasurement[a-zA-Z]*>)"); + // Regular expressions to scan test output for custom measurements. - // regex to detect <CTestDetails>...</CTestDetails> + // Capture the whole section of test output from the first opening + // <(CTest|Dart)Measurement*> tag to the last </(CTest|Dart)Measurement*> + // closing tag. + this->AllTestMeasurementsRegex.compile( + "(<(CTest|Dart)Measurement.*/(CTest|Dart)Measurement[a-zA-Z]*>)"); + + // Capture a single <(CTest|Dart)Measurement*> XML element. + this->SingleTestMeasurementRegex.compile( + "(<(CTest|Dart)Measurement[^<]*</(CTest|Dart)Measurement[a-zA-Z]*>)"); + + // Capture content from <CTestDetails>...</CTestDetails> this->CustomCompletionStatusRegex.compile( "<CTestDetails>(.*)</CTestDetails>"); + + // Capture content from <CTestLabel>...</CTestLabel> + this->CustomLabelRegex.compile("<CTestLabel>(.*)</CTestLabel>"); } void cmCTestTestHandler::Initialize() @@ -511,7 +521,7 @@ bool cmCTestTestHandler::ProcessOptions() if (cmIsOn(this->GetOption("ScheduleRandom"))) { this->CTest->SetScheduleType("Random"); } - if (const char* repeat = this->GetOption("Repeat")) { + if (cmValue repeat = this->GetOption("Repeat")) { cmsys::RegularExpression repeatRegex( "^(UNTIL_FAIL|UNTIL_PASS|AFTER_TIMEOUT):([0-9]+)$"); if (repeatRegex.find(repeat)) { @@ -536,7 +546,7 @@ bool cmCTestTestHandler::ProcessOptions() } } if (this->GetOption("ParallelLevel")) { - this->CTest->SetParallelLevel(atoi(this->GetOption("ParallelLevel"))); + this->CTest->SetParallelLevel(std::stoi(this->GetOption("ParallelLevel"))); } if (this->GetOption("StopOnFailure")) { @@ -547,7 +557,7 @@ bool cmCTestTestHandler::ProcessOptions() this->IncludeLabelRegularExpressions); BuildLabelRE(this->GetMultiOption("ExcludeLabelRegularExpression"), this->ExcludeLabelRegularExpressions); - const char* val = this->GetOption("IncludeRegularExpression"); + cmValue val = this->GetOption("IncludeRegularExpression"); if (val) { this->UseIncludeRegExp(); this->SetIncludeRegExp(val); @@ -559,19 +569,19 @@ bool cmCTestTestHandler::ProcessOptions() } val = this->GetOption("ExcludeFixtureRegularExpression"); if (val) { - this->ExcludeFixtureRegExp = val; + this->ExcludeFixtureRegExp = *val; } val = this->GetOption("ExcludeFixtureSetupRegularExpression"); if (val) { - this->ExcludeFixtureSetupRegExp = val; + this->ExcludeFixtureSetupRegExp = *val; } val = this->GetOption("ExcludeFixtureCleanupRegularExpression"); if (val) { - this->ExcludeFixtureCleanupRegExp = val; + this->ExcludeFixtureCleanupRegExp = *val; } val = this->GetOption("ResourceSpecFile"); if (val) { - this->ResourceSpecFile = val; + this->ResourceSpecFile = *val; } this->SetRerunFailed(cmIsOn(this->GetOption("RerunFailed"))); @@ -692,7 +702,22 @@ bool cmCTestTestHandler::GenerateXML() return false; } cmXMLWriter xml(xmlfile); - this->GenerateDartOutput(xml); + this->GenerateCTestXML(xml); + } + + if (this->MemCheck) { + cmGeneratedFileStream xmlfile; + if (!this->StartResultingXML(cmCTest::PartTest, "DynamicAnalysis-Test", + xmlfile)) { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Cannot create testing XML file" << std::endl); + this->LogFile = nullptr; + return false; + } + cmXMLWriter xml(xmlfile); + // Explicitly call this class' `GenerateCTestXML` method to make `Test.xml` + // as well. + this->cmCTestTestHandler::GenerateCTestXML(xml); } return true; @@ -1400,7 +1425,7 @@ void cmCTestTestHandler::GenerateTestCommand( { } -void cmCTestTestHandler::GenerateDartOutput(cmXMLWriter& xml) +void cmCTestTestHandler::GenerateCTestXML(cmXMLWriter& xml) { if (!this->CTest->GetProduceXML()) { return; @@ -1436,7 +1461,7 @@ void cmCTestTestHandler::GenerateDartOutput(cmXMLWriter& xml) xml.Element("Value", result.ReturnValue); xml.EndElement(); // NamedMeasurement } - this->GenerateRegressionImages(xml, result.DartString); + this->RecordCustomTestMeasurements(xml, result.TestMeasurementsOutput); xml.StartElement("NamedMeasurement"); xml.Attribute("type", "numeric/double"); xml.Attribute("name", "Execution Time"); @@ -1804,7 +1829,7 @@ bool cmCTestTestHandler::GetListOfTests() // SEND_ERROR or FATAL_ERROR in CTestTestfile or TEST_INCLUDE_FILES return false; } - cmProp specFile = mf.GetDefinition("CTEST_RESOURCE_SPEC_FILE"); + cmValue specFile = mf.GetDefinition("CTEST_RESOURCE_SPEC_FILE"); if (this->ResourceSpecFile.empty() && specFile) { this->ResourceSpecFile = *specFile; } @@ -1976,124 +2001,48 @@ void cmCTestTestHandler::ExpandTestsToRunInformationForRerunFailed() } } -// Just for convenience -#define SPACE_REGEX "[ \t\r\n]" -void cmCTestTestHandler::GenerateRegressionImages(cmXMLWriter& xml, - const std::string& dart) -{ - cmsys::RegularExpression twoattributes( - "<DartMeasurement" SPACE_REGEX - "*(name|type|encoding|compression)=\"([^\"]*)\"" SPACE_REGEX - "*(name|type|encoding|compression)=\"([^\"]*)\"" SPACE_REGEX - "*>([^<]*)</DartMeasurement>"); - cmsys::RegularExpression threeattributes( - "<DartMeasurement" SPACE_REGEX - "*(name|type|encoding|compression)=\"([^\"]*)\"" SPACE_REGEX - "*(name|type|encoding|compression)=\"([^\"]*)\"" SPACE_REGEX - "*(name|type|encoding|compression)=\"([^\"]*)\"" SPACE_REGEX - "*>([^<]*)</DartMeasurement>"); - cmsys::RegularExpression fourattributes( - "<DartMeasurement" SPACE_REGEX - "*(name|type|encoding|compression)=\"([^\"]*)\"" SPACE_REGEX - "*(name|type|encoding|compression)=\"([^\"]*)\"" SPACE_REGEX - "*(name|type|encoding|compression)=\"([^\"]*)\"" SPACE_REGEX - "*(name|type|encoding|compression)=\"([^\"]*)\"" SPACE_REGEX - "*>([^<]*)</DartMeasurement>"); - cmsys::RegularExpression cdatastart( - "<DartMeasurement" SPACE_REGEX - "*(name|type|encoding|compression)=\"([^\"]*)\"" SPACE_REGEX - "*(name|type|encoding|compression)=\"([^\"]*)\"" SPACE_REGEX - "*>" SPACE_REGEX "*<!\\[CDATA\\["); - cmsys::RegularExpression cdataend("]]>" SPACE_REGEX "*</DartMeasurement>"); - cmsys::RegularExpression measurementfile( - "<DartMeasurementFile" SPACE_REGEX - "*(name|type|encoding|compression)=\"([^\"]*)\"" SPACE_REGEX - "*(name|type|encoding|compression)=\"([^\"]*)\"" SPACE_REGEX - "*>([^<]*)</DartMeasurementFile>"); - - bool done = false; - std::string cxml = dart; - while (!done) { - if (twoattributes.find(cxml)) { - xml.StartElement("NamedMeasurement"); - xml.Attribute(twoattributes.match(1).c_str(), twoattributes.match(2)); - xml.Attribute(twoattributes.match(3).c_str(), twoattributes.match(4)); - xml.Element("Value", twoattributes.match(5)); - xml.EndElement(); - cxml.erase(twoattributes.start(), - twoattributes.end() - twoattributes.start()); - } else if (threeattributes.find(cxml)) { - xml.StartElement("NamedMeasurement"); - xml.Attribute(threeattributes.match(1).c_str(), - threeattributes.match(2)); - xml.Attribute(threeattributes.match(3).c_str(), - threeattributes.match(4)); - xml.Attribute(threeattributes.match(5).c_str(), - threeattributes.match(6)); - xml.Element("Value", twoattributes.match(7)); - xml.EndElement(); - cxml.erase(threeattributes.start(), - threeattributes.end() - threeattributes.start()); - } else if (fourattributes.find(cxml)) { +void cmCTestTestHandler::RecordCustomTestMeasurements(cmXMLWriter& xml, + std::string content) +{ + while (this->SingleTestMeasurementRegex.find(content)) { + // Extract regex match from content and parse it as an XML element. + auto measurement_str = this->SingleTestMeasurementRegex.match(1); + auto parser = cmCTestTestMeasurementXMLParser(); + parser.Parse(measurement_str.c_str()); + + if (parser.ElementName == "CTestMeasurement" || + parser.ElementName == "DartMeasurement") { xml.StartElement("NamedMeasurement"); - xml.Attribute(fourattributes.match(1).c_str(), fourattributes.match(2)); - xml.Attribute(fourattributes.match(3).c_str(), fourattributes.match(4)); - xml.Attribute(fourattributes.match(5).c_str(), fourattributes.match(6)); - xml.Attribute(fourattributes.match(7).c_str(), fourattributes.match(8)); - xml.Element("Value", twoattributes.match(9)); + xml.Attribute("type", parser.MeasurementType); + xml.Attribute("name", parser.MeasurementName); + xml.Element("Value", parser.CharacterData); xml.EndElement(); - cxml.erase(fourattributes.start(), - fourattributes.end() - fourattributes.start()); - } else if (cdatastart.find(cxml) && cdataend.find(cxml)) { - xml.StartElement("NamedMeasurement"); - xml.Attribute(cdatastart.match(1).c_str(), cdatastart.match(2)); - xml.Attribute(cdatastart.match(3).c_str(), cdatastart.match(4)); - xml.StartElement("Value"); - xml.CData( - cxml.substr(cdatastart.end(), cdataend.start() - cdatastart.end())); - xml.EndElement(); // Value - xml.EndElement(); // NamedMeasurement - cxml.erase(cdatastart.start(), cdataend.end() - cdatastart.start()); - } else if (measurementfile.find(cxml)) { - const std::string& filename = - cmCTest::CleanString(measurementfile.match(5)); - if (cmSystemTools::FileExists(filename)) { + } else if (parser.ElementName == "CTestMeasurementFile" || + parser.ElementName == "DartMeasurementFile") { + const std::string& filename = cmCTest::CleanString(parser.CharacterData); + if (!cmSystemTools::FileExists(filename)) { + xml.StartElement("NamedMeasurement"); + xml.Attribute("name", parser.MeasurementName); + xml.Attribute("text", "text/string"); + xml.Element("Value", "File " + filename + " not found"); + xml.EndElement(); + cmCTestOptionalLog( + this->CTest, HANDLER_OUTPUT, + "File \"" << filename << "\" not found." << std::endl, this->Quiet); + } else { long len = cmSystemTools::FileLength(filename); - std::string k1 = measurementfile.match(1); - std::string v1 = measurementfile.match(2); - std::string k2 = measurementfile.match(3); - std::string v2 = measurementfile.match(4); if (len == 0) { - if (cmSystemTools::LowerCase(k1) == "type") { - v1 = "text/string"; - } - if (cmSystemTools::LowerCase(k2) == "type") { - v2 = "text/string"; - } - xml.StartElement("NamedMeasurement"); - xml.Attribute(k1.c_str(), v1); - xml.Attribute(k2.c_str(), v2); + xml.Attribute("name", parser.MeasurementName); + xml.Attribute("type", "text/string"); xml.Attribute("encoding", "none"); xml.Element("Value", "Image " + filename + " is empty"); xml.EndElement(); } else { - std::string type; - std::string name; - if (cmSystemTools::LowerCase(k1) == "type") { - type = v1; - } else if (cmSystemTools::LowerCase(k2) == "type") { - type = v2; - } - if (cmSystemTools::LowerCase(k1) == "name") { - name = v1; - } else if (cmSystemTools::LowerCase(k2) == "name") { - name = v2; - } - if (type == "file") { + if (parser.MeasurementType == "file") { // Treat this measurement like an "ATTACHED_FILE" when the type // is explicitly "file" (not an image). - this->AttachFile(xml, filename, name); + this->AttachFile(xml, filename, parser.MeasurementName); } else { cmsys::ifstream ifs(filename.c_str(), std::ios::in @@ -2110,10 +2059,8 @@ void cmCTestTestHandler::GenerateRegressionImages(cmXMLWriter& xml, encoded_buffer.get(), 1); xml.StartElement("NamedMeasurement"); - xml.Attribute(measurementfile.match(1).c_str(), - measurementfile.match(2)); - xml.Attribute(measurementfile.match(3).c_str(), - measurementfile.match(4)); + xml.Attribute("name", parser.MeasurementName); + xml.Attribute("type", parser.MeasurementType); xml.Attribute("encoding", "base64"); std::ostringstream ostr; for (size_t cc = 0; cc < rlen; cc++) { @@ -2126,48 +2073,34 @@ void cmCTestTestHandler::GenerateRegressionImages(cmXMLWriter& xml, xml.EndElement(); // NamedMeasurement } } - } else { - int idx = 4; - if (measurementfile.match(1) == "name") { - idx = 2; - } - xml.StartElement("NamedMeasurement"); - xml.Attribute("name", measurementfile.match(idx)); - xml.Attribute("text", "text/string"); - xml.Element("Value", "File " + filename + " not found"); - xml.EndElement(); - cmCTestOptionalLog( - this->CTest, HANDLER_OUTPUT, - "File \"" << filename << "\" not found." << std::endl, this->Quiet); } - cxml.erase(measurementfile.start(), - measurementfile.end() - measurementfile.start()); - } else { - done = true; } + + // Remove this element from content. + cmSystemTools::ReplaceString(content, measurement_str.c_str(), ""); } } -void cmCTestTestHandler::SetIncludeRegExp(const char* arg) +void cmCTestTestHandler::SetIncludeRegExp(const std::string& arg) { this->IncludeRegExp = arg; } -void cmCTestTestHandler::SetExcludeRegExp(const char* arg) +void cmCTestTestHandler::SetExcludeRegExp(const std::string& arg) { this->ExcludeRegExp = arg; } -void cmCTestTestHandler::SetTestsToRunInformation(const char* in) +void cmCTestTestHandler::SetTestsToRunInformation(cmValue in) { if (!in) { return; } - this->TestsToRunString = in; + this->TestsToRunString = *in; // if the argument is a file, then read it and use the contents as the // string if (cmSystemTools::FileExists(in)) { - cmsys::ifstream fin(in); + cmsys::ifstream fin(in->c_str()); unsigned long filelen = cmSystemTools::FileLength(in); auto buff = cm::make_unique<char[]>(filelen + 1); fin.getline(buff.get(), filelen); @@ -2247,7 +2180,7 @@ bool cmCTestTestHandler::SetTestsProperties( // Ensure we have complete triples otherwise the data is corrupt. if (triples.size() % 3 == 0) { - cmState state; + cmState state(cmState::Unknown); rt.Backtrace = cmListFileBacktrace(state.CreateBaseSnapshot()); // the first entry represents the top of the trace so we need to @@ -2327,6 +2260,8 @@ bool cmCTestTestHandler::SetTestsProperties( cmExpandList(val, rt.Depends); } else if (key == "ENVIRONMENT"_s) { cmExpandList(val, rt.Environment); + } else if (key == "ENVIRONMENT_MODIFICATION"_s) { + cmExpandList(val, rt.EnvironmentModification); } else if (key == "LABELS"_s) { std::vector<std::string> Labels = cmExpandedList(val); rt.Labels.insert(rt.Labels.end(), Labels.begin(), Labels.end()); diff --git a/Source/CTest/cmCTestTestHandler.h b/Source/CTest/cmCTestTestHandler.h index bd51738b8..3ac05e7bf 100644 --- a/Source/CTest/cmCTestTestHandler.h +++ b/Source/CTest/cmCTestTestHandler.h @@ -22,6 +22,7 @@ #include "cmCTestResourceSpec.h" #include "cmDuration.h" #include "cmListFileCache.h" +#include "cmValue.h" class cmMakefile; class cmXMLWriter; @@ -65,8 +66,8 @@ public: /// them on void UseIncludeRegExp(); void UseExcludeRegExp(); - void SetIncludeRegExp(const char*); - void SetExcludeRegExp(const char*); + void SetIncludeRegExp(const std::string&); + void SetExcludeRegExp(const std::string&); void SetMaxIndex(int n) { this->MaxIndex = n; } int GetMaxIndex() { return this->MaxIndex; } @@ -81,7 +82,7 @@ public: } //! pass the -I argument down - void SetTestsToRunInformation(const char*); + void SetTestsToRunInformation(cmValue); cmCTestTestHandler(); @@ -151,6 +152,7 @@ public: // return code of test which will mark test as "not run" int SkipReturnCode; std::vector<std::string> Environment; + std::vector<std::string> EnvironmentModification; std::vector<std::string> Labels; std::set<std::string> LockedResources; std::set<std::string> FixturesSetup; @@ -177,7 +179,7 @@ public: std::string CompletionStatus; std::string CustomCompletionStatus; std::string Output; - std::string DartString; + std::string TestMeasurementsOutput; int TestCount; cmCTestTestProperties* Properties; }; @@ -276,9 +278,9 @@ public: private: /** - * Generate the Dart compatible output + * Write test results in CTest's Test.xml format */ - virtual void GenerateDartOutput(cmXMLWriter& xml); + virtual void GenerateCTestXML(cmXMLWriter& xml); /** * Write test results in JUnit XML format @@ -348,8 +350,7 @@ private: cmCTestResourceSpec ResourceSpec; std::string ResourceSpecFile; - void GenerateRegressionImages(cmXMLWriter& xml, const std::string& dart); - cmsys::RegularExpression DartStuff1; + void RecordCustomTestMeasurements(cmXMLWriter& xml, std::string content); void CheckLabelFilter(cmCTestTestProperties& it); void CheckLabelFilterExclude(cmCTestTestProperties& it); void CheckLabelFilterInclude(cmCTestTestProperties& it); @@ -358,8 +359,10 @@ private: bool UseUnion; ListOfTests TestList; size_t TotalNumberOfTests; - cmsys::RegularExpression DartStuff; + cmsys::RegularExpression AllTestMeasurementsRegex; + cmsys::RegularExpression SingleTestMeasurementRegex; cmsys::RegularExpression CustomCompletionStatusRegex; + cmsys::RegularExpression CustomLabelRegex; std::ostream* LogFile; diff --git a/Source/CTest/cmCTestTestMeasurementXMLParser.cxx b/Source/CTest/cmCTestTestMeasurementXMLParser.cxx new file mode 100644 index 000000000..636be2451 --- /dev/null +++ b/Source/CTest/cmCTestTestMeasurementXMLParser.cxx @@ -0,0 +1,26 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#include "cmCTestTestMeasurementXMLParser.h" + +#include <cstring> + +void cmCTestTestMeasurementXMLParser::StartElement(const std::string& name, + const char** attributes) +{ + this->CharacterData.clear(); + this->ElementName = name; + for (const char** attr = attributes; *attr; attr += 2) { + if (strcmp(attr[0], "name") == 0) { + this->MeasurementName = attr[1]; + } else if (strcmp(attr[0], "type") == 0) { + this->MeasurementType = attr[1]; + } + } +} + +void cmCTestTestMeasurementXMLParser::CharacterDataHandler(const char* data, + int length) +{ + this->CharacterData.append(data, length); +} diff --git a/Source/CTest/cmCTestTestMeasurementXMLParser.h b/Source/CTest/cmCTestTestMeasurementXMLParser.h new file mode 100644 index 000000000..b2c3eb3f1 --- /dev/null +++ b/Source/CTest/cmCTestTestMeasurementXMLParser.h @@ -0,0 +1,21 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#include <string> + +#include "cmXMLParser.h" + +class cmCTestTestMeasurementXMLParser : public cmXMLParser +{ +public: + cmCTestTestMeasurementXMLParser() {} + std::string CharacterData; + std::string ElementName; + std::string MeasurementName; + std::string MeasurementType; + +protected: + void StartElement(const std::string& name, const char** atts) override; + void EndElement(const std::string& /*name*/) override {} + void CharacterDataHandler(const char* data, int length) override; +}; diff --git a/Source/CTest/cmCTestUpdateCommand.cxx b/Source/CTest/cmCTestUpdateCommand.cxx index 797cb014e..6655bf724 100644 --- a/Source/CTest/cmCTestUpdateCommand.cxx +++ b/Source/CTest/cmCTestUpdateCommand.cxx @@ -79,7 +79,7 @@ cmCTestGenericHandler* cmCTestUpdateCommand::InitializeHandler() this->SetError("source directory not specified. Please use SOURCE tag"); return nullptr; } - handler->SetOption("SourceDirectory", source_dir.c_str()); + handler->SetOption("SourceDirectory", source_dir); handler->SetQuiet(this->Quiet); return handler; } diff --git a/Source/CTest/cmCTestUpdateHandler.cxx b/Source/CTest/cmCTestUpdateHandler.cxx index 57cc02420..d448c769e 100644 --- a/Source/CTest/cmCTestUpdateHandler.cxx +++ b/Source/CTest/cmCTestUpdateHandler.cxx @@ -19,6 +19,7 @@ #include "cmGeneratedFileStream.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" #include "cmVersion.h" #include "cmXMLWriter.h" @@ -108,7 +109,7 @@ int cmCTestUpdateHandler::ProcessHandler() static_cast<void>(fixLocale); // Get source dir - const char* sourceDirectory = this->GetOption("SourceDirectory"); + cmValue sourceDirectory = this->GetOption("SourceDirectory"); if (!sourceDirectory) { cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot find SourceDirectory key in the DartConfiguration.tcl" @@ -257,7 +258,7 @@ int cmCTestUpdateHandler::ProcessHandler() return updated && loadedMods ? numUpdated : -1; } -int cmCTestUpdateHandler::DetectVCS(const char* dir) +int cmCTestUpdateHandler::DetectVCS(const std::string& dir) { std::string sourceDirectory = dir; cmCTestOptionalLog(this->CTest, DEBUG, diff --git a/Source/CTest/cmCTestUpdateHandler.h b/Source/CTest/cmCTestUpdateHandler.h index 25bbb2f5c..70269ea54 100644 --- a/Source/CTest/cmCTestUpdateHandler.h +++ b/Source/CTest/cmCTestUpdateHandler.h @@ -59,6 +59,6 @@ private: std::string UpdateCommand; int UpdateType; - int DetectVCS(const char* dir); + int DetectVCS(const std::string& dir); bool SelectVCS(); }; diff --git a/Source/CTest/cmCTestVC.cxx b/Source/CTest/cmCTestVC.cxx index 452d7143b..423b5064c 100644 --- a/Source/CTest/cmCTestVC.cxx +++ b/Source/CTest/cmCTestVC.cxx @@ -10,8 +10,8 @@ #include "cmsys/Process.h" #include "cmCTest.h" -#include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" #include "cmXMLWriter.h" cmCTestVC::cmCTestVC(cmCTest* ct, std::ostream& log) diff --git a/Source/CursesDialog/cmCursesCacheEntryComposite.cxx b/Source/CursesDialog/cmCursesCacheEntryComposite.cxx index 35f09fd6a..e9ec09ee2 100644 --- a/Source/CursesDialog/cmCursesCacheEntryComposite.cxx +++ b/Source/CursesDialog/cmCursesCacheEntryComposite.cxx @@ -15,11 +15,11 @@ #include "cmCursesPathWidget.h" #include "cmCursesStringWidget.h" #include "cmCursesWidget.h" -#include "cmProperty.h" #include "cmState.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" cmCursesCacheEntryComposite::cmCursesCacheEntryComposite( const std::string& key, int labelwidth, int entrywidth) @@ -49,7 +49,7 @@ cmCursesCacheEntryComposite::cmCursesCacheEntryComposite( this->IsNewLabel = cm::make_unique<cmCursesLabelWidget>(1, 1, 1, 1, " "); } - cmProp value = state->GetCacheEntryValue(key); + cmValue value = state->GetCacheEntryValue(key); assert(value); switch (state->GetCacheEntryType(key)) { case cmStateEnums::BOOL: { @@ -72,7 +72,7 @@ cmCursesCacheEntryComposite::cmCursesCacheEntryComposite( break; } case cmStateEnums::STRING: { - cmProp stringsProp = state->GetCacheEntryProperty(key, "STRINGS"); + cmValue stringsProp = state->GetCacheEntryProperty(key, "STRINGS"); if (stringsProp) { auto ow = cm::make_unique<cmCursesOptionsWidget>(this->EntryWidth, 1, 1, 1); diff --git a/Source/CursesDialog/cmCursesMainForm.cxx b/Source/CursesDialog/cmCursesMainForm.cxx index 069c02ef8..b28c5b7ac 100644 --- a/Source/CursesDialog/cmCursesMainForm.cxx +++ b/Source/CursesDialog/cmCursesMainForm.cxx @@ -17,11 +17,11 @@ #include "cmCursesStandardIncludes.h" #include "cmCursesStringWidget.h" #include "cmCursesWidget.h" -#include "cmProperty.h" #include "cmState.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" #include "cmVersion.h" #include "cmake.h" @@ -162,7 +162,7 @@ void cmCursesMainForm::RePost() // If normal mode, count only non-advanced entries this->NumberOfVisibleEntries = 0; for (cmCursesCacheEntryComposite& entry : this->Entries) { - cmProp existingValue = + cmValue existingValue = this->CMakeInstance->GetState()->GetCacheEntryValue(entry.GetValue()); bool advanced = this->CMakeInstance->GetState()->GetCacheEntryPropertyAsBool( @@ -183,7 +183,7 @@ void cmCursesMainForm::RePost() // Assign fields for (cmCursesCacheEntryComposite& entry : this->Entries) { - cmProp existingValue = + cmValue existingValue = this->CMakeInstance->GetState()->GetCacheEntryValue(entry.GetValue()); bool advanced = this->CMakeInstance->GetState()->GetCacheEntryPropertyAsBool( @@ -242,7 +242,7 @@ void cmCursesMainForm::Render(int left, int top, int width, int height) // If normal, display only non-advanced entries this->NumberOfVisibleEntries = 0; for (cmCursesCacheEntryComposite& entry : this->Entries) { - cmProp existingValue = + cmValue existingValue = this->CMakeInstance->GetState()->GetCacheEntryValue(entry.GetValue()); bool advanced = this->CMakeInstance->GetState()->GetCacheEntryPropertyAsBool( @@ -260,7 +260,7 @@ void cmCursesMainForm::Render(int left, int top, int width, int height) bool isNewPage; int i = 0; for (cmCursesCacheEntryComposite& entry : this->Entries) { - cmProp existingValue = + cmValue existingValue = this->CMakeInstance->GetState()->GetCacheEntryValue(entry.GetValue()); bool advanced = this->CMakeInstance->GetState()->GetCacheEntryPropertyAsBool( @@ -406,9 +406,9 @@ void cmCursesMainForm::UpdateStatusBar(cm::optional<std::string> message) // Get the help string of the current entry // and add it to the help string auto* cmakeState = this->CMakeInstance->GetState(); - cmProp existingValue = cmakeState->GetCacheEntryValue(labelValue); + cmValue existingValue = cmakeState->GetCacheEntryValue(labelValue); if (existingValue) { - cmProp help = + cmValue help = cmakeState->GetCacheEntryProperty(labelValue, "HELPSTRING"); if (help) { bar += *help; @@ -618,7 +618,7 @@ void cmCursesMainForm::FillCacheManagerFromUI() { for (cmCursesCacheEntryComposite& entry : this->Entries) { const std::string& cacheKey = entry.Key; - cmProp existingValue = + cmValue existingValue = this->CMakeInstance->GetState()->GetCacheEntryValue(cacheKey); if (existingValue) { std::string oldValue = *existingValue; @@ -804,9 +804,9 @@ void cmCursesMainForm::HandleInput() cmCursesWidget* lbl = reinterpret_cast<cmCursesWidget*>( field_userptr(this->Fields[findex - 2])); const char* curField = lbl->GetValue(); - cmProp helpString = nullptr; + cmValue helpString = nullptr; - cmProp existingValue = + cmValue existingValue = this->CMakeInstance->GetState()->GetCacheEntryValue(curField); if (existingValue) { helpString = this->CMakeInstance->GetState()->GetCacheEntryProperty( diff --git a/Source/LexerParser/cmFortranParser.cxx b/Source/LexerParser/cmFortranParser.cxx index 3f3dddeb4..50e97529b 100644 --- a/Source/LexerParser/cmFortranParser.cxx +++ b/Source/LexerParser/cmFortranParser.cxx @@ -600,12 +600,12 @@ static const yytype_int8 yytranslate[] = static const yytype_uint8 yyrline[] = { 0, 101, 101, 101, 104, 108, 113, 122, 128, 135, - 140, 144, 149, 157, 162, 167, 172, 177, 182, 187, - 192, 197, 201, 205, 209, 213, 214, 219, 219, 219, - 220, 220, 221, 221, 222, 222, 223, 223, 224, 224, - 225, 225, 226, 226, 227, 227, 228, 228, 231, 232, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - 243, 244, 245, 246, 247 + 140, 144, 149, 161, 166, 171, 176, 181, 186, 191, + 196, 201, 205, 209, 213, 217, 218, 223, 223, 223, + 224, 224, 225, 225, 226, 226, 227, 227, 228, 228, + 229, 229, 230, 230, 231, 231, 232, 232, 235, 236, + 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, + 247, 248, 249, 250, 251 }; #endif @@ -1747,142 +1747,146 @@ yyreduce: cmFortranParser* parser = cmFortran_yyget_extra(yyscanner); cmFortranParser_RuleUse(parser, (yyvsp[-2].string)); } + if (cmsysString_strcasecmp((yyvsp[-4].string), "intrinsic") == 0) { + cmFortranParser* parser = cmFortran_yyget_extra(yyscanner); + cmFortranParser_RuleUseIntrinsic(parser, (yyvsp[-2].string)); + } free((yyvsp[-4].string)); free((yyvsp[-2].string)); } -#line 1754 "cmFortranParser.cxx" +#line 1758 "cmFortranParser.cxx" break; case 13: /* stmt: INCLUDE STRING other EOSTMT */ -#line 157 "cmFortranParser.y" +#line 161 "cmFortranParser.y" { cmFortranParser* parser = cmFortran_yyget_extra(yyscanner); cmFortranParser_RuleInclude(parser, (yyvsp[-2].string)); free((yyvsp[-2].string)); } -#line 1764 "cmFortranParser.cxx" +#line 1768 "cmFortranParser.cxx" break; case 14: /* stmt: CPP_LINE_DIRECTIVE STRING other EOSTMT */ -#line 162 "cmFortranParser.y" +#line 166 "cmFortranParser.y" { cmFortranParser* parser = cmFortran_yyget_extra(yyscanner); cmFortranParser_RuleLineDirective(parser, (yyvsp[-2].string)); free((yyvsp[-2].string)); } -#line 1774 "cmFortranParser.cxx" +#line 1778 "cmFortranParser.cxx" break; case 15: /* stmt: CPP_INCLUDE_ANGLE other EOSTMT */ -#line 167 "cmFortranParser.y" +#line 171 "cmFortranParser.y" { cmFortranParser* parser = cmFortran_yyget_extra(yyscanner); cmFortranParser_RuleInclude(parser, (yyvsp[-2].string)); free((yyvsp[-2].string)); } -#line 1784 "cmFortranParser.cxx" +#line 1788 "cmFortranParser.cxx" break; case 16: /* stmt: include STRING other EOSTMT */ -#line 172 "cmFortranParser.y" +#line 176 "cmFortranParser.y" { cmFortranParser* parser = cmFortran_yyget_extra(yyscanner); cmFortranParser_RuleInclude(parser, (yyvsp[-2].string)); free((yyvsp[-2].string)); } -#line 1794 "cmFortranParser.cxx" +#line 1798 "cmFortranParser.cxx" break; case 17: /* stmt: define WORD other EOSTMT */ -#line 177 "cmFortranParser.y" +#line 181 "cmFortranParser.y" { cmFortranParser* parser = cmFortran_yyget_extra(yyscanner); cmFortranParser_RuleDefine(parser, (yyvsp[-2].string)); free((yyvsp[-2].string)); } -#line 1804 "cmFortranParser.cxx" +#line 1808 "cmFortranParser.cxx" break; case 18: /* stmt: undef WORD other EOSTMT */ -#line 182 "cmFortranParser.y" +#line 186 "cmFortranParser.y" { cmFortranParser* parser = cmFortran_yyget_extra(yyscanner); cmFortranParser_RuleUndef(parser, (yyvsp[-2].string)); free((yyvsp[-2].string)); } -#line 1814 "cmFortranParser.cxx" +#line 1818 "cmFortranParser.cxx" break; case 19: /* stmt: ifdef WORD other EOSTMT */ -#line 187 "cmFortranParser.y" +#line 191 "cmFortranParser.y" { cmFortranParser* parser = cmFortran_yyget_extra(yyscanner); cmFortranParser_RuleIfdef(parser, (yyvsp[-2].string)); free((yyvsp[-2].string)); } -#line 1824 "cmFortranParser.cxx" +#line 1828 "cmFortranParser.cxx" break; case 20: /* stmt: ifndef WORD other EOSTMT */ -#line 192 "cmFortranParser.y" +#line 196 "cmFortranParser.y" { cmFortranParser* parser = cmFortran_yyget_extra(yyscanner); cmFortranParser_RuleIfndef(parser, (yyvsp[-2].string)); free((yyvsp[-2].string)); } -#line 1834 "cmFortranParser.cxx" +#line 1838 "cmFortranParser.cxx" break; case 21: /* stmt: if other EOSTMT */ -#line 197 "cmFortranParser.y" +#line 201 "cmFortranParser.y" { cmFortranParser* parser = cmFortran_yyget_extra(yyscanner); cmFortranParser_RuleIf(parser); } -#line 1843 "cmFortranParser.cxx" +#line 1847 "cmFortranParser.cxx" break; case 22: /* stmt: elif other EOSTMT */ -#line 201 "cmFortranParser.y" +#line 205 "cmFortranParser.y" { cmFortranParser* parser = cmFortran_yyget_extra(yyscanner); cmFortranParser_RuleElif(parser); } -#line 1852 "cmFortranParser.cxx" +#line 1856 "cmFortranParser.cxx" break; case 23: /* stmt: else other EOSTMT */ -#line 205 "cmFortranParser.y" +#line 209 "cmFortranParser.y" { cmFortranParser* parser = cmFortran_yyget_extra(yyscanner); cmFortranParser_RuleElse(parser); } -#line 1861 "cmFortranParser.cxx" +#line 1865 "cmFortranParser.cxx" break; case 24: /* stmt: endif other EOSTMT */ -#line 209 "cmFortranParser.y" +#line 213 "cmFortranParser.y" { cmFortranParser* parser = cmFortran_yyget_extra(yyscanner); cmFortranParser_RuleEndif(parser); } -#line 1870 "cmFortranParser.cxx" +#line 1874 "cmFortranParser.cxx" break; case 48: /* misc_code: WORD */ -#line 231 "cmFortranParser.y" +#line 235 "cmFortranParser.y" { free ((yyvsp[0].string)); } -#line 1876 "cmFortranParser.cxx" +#line 1880 "cmFortranParser.cxx" break; case 55: /* misc_code: STRING */ -#line 238 "cmFortranParser.y" +#line 242 "cmFortranParser.y" { free ((yyvsp[0].string)); } -#line 1882 "cmFortranParser.cxx" +#line 1886 "cmFortranParser.cxx" break; -#line 1886 "cmFortranParser.cxx" +#line 1890 "cmFortranParser.cxx" default: break; } @@ -2107,6 +2111,6 @@ yyreturn: return yyresult; } -#line 250 "cmFortranParser.y" +#line 254 "cmFortranParser.y" /* End of grammar */ diff --git a/Source/LexerParser/cmFortranParser.y b/Source/LexerParser/cmFortranParser.y index a3e1c24b1..8ef19035c 100644 --- a/Source/LexerParser/cmFortranParser.y +++ b/Source/LexerParser/cmFortranParser.y @@ -151,6 +151,10 @@ stmt: cmFortranParser* parser = cmFortran_yyget_extra(yyscanner); cmFortranParser_RuleUse(parser, $5); } + if (cmsysString_strcasecmp($3, "intrinsic") == 0) { + cmFortranParser* parser = cmFortran_yyget_extra(yyscanner); + cmFortranParser_RuleUseIntrinsic(parser, $5); + } free($3); free($5); } diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx index c55604980..8ffa3e728 100644 --- a/Source/QtDialog/CMakeSetup.cxx +++ b/Source/QtDialog/CMakeSetup.cxx @@ -10,15 +10,6 @@ #include <QTranslator> #include <QtPlugin> -// FIXME(#23565): Qt6 has QTextCodec in Core5Compat, but using its -// `setCodecForLocale` does not make cmake-gui support non-ASCII chars -// on Windows. For now we only support them with Qt5. How do we support -// them with Qt6, preferably without Core5Compat? -#if defined(Q_OS_WIN) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) -# include <QTextCodec> -# define CMAKE_HAVE_QTEXTCODEC -#endif - #include "cmsys/CommandLineArguments.hxx" #include "cmsys/Encoding.hxx" #include "cmsys/SystemTools.hxx" @@ -133,11 +124,6 @@ int main(int argc, char** argv) setlocale(LC_NUMERIC, "C"); -#ifdef CMAKE_HAVE_QTEXTCODEC - QTextCodec* utf8_codec = QTextCodec::codecForName("UTF-8"); - QTextCodec::setCodecForLocale(utf8_codec); -#endif - // tell the cmake library where cmake is QDir cmExecDir(QApplication::applicationDirPath()); #if defined(Q_OS_MAC) diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx index e6faef470..8ab86564c 100644 --- a/Source/QtDialog/QCMake.cxx +++ b/Source/QtDialog/QCMake.cxx @@ -122,26 +122,26 @@ void QCMake::setBinaryDirectory(const QString& _dir) QCMakePropertyList props = this->properties(); emit this->propertiesChanged(props); - cmProp homeDir = state->GetCacheEntryValue("CMAKE_HOME_DIRECTORY"); + cmValue homeDir = state->GetCacheEntryValue("CMAKE_HOME_DIRECTORY"); if (homeDir) { setSourceDirectory(QString::fromLocal8Bit(homeDir->c_str())); } - cmProp gen = state->GetCacheEntryValue("CMAKE_GENERATOR"); + cmValue gen = state->GetCacheEntryValue("CMAKE_GENERATOR"); if (gen) { - const std::string* extraGen = + cmValue extraGen = state->GetInitializedCacheValue("CMAKE_EXTRA_GENERATOR"); std::string curGen = - cmExternalMakefileProjectGenerator::CreateFullGeneratorName( - *gen, extraGen ? *extraGen : ""); + cmExternalMakefileProjectGenerator::CreateFullGeneratorName(*gen, + *extraGen); this->setGenerator(QString::fromLocal8Bit(curGen.c_str())); } - cmProp platform = state->GetCacheEntryValue("CMAKE_GENERATOR_PLATFORM"); + cmValue platform = state->GetCacheEntryValue("CMAKE_GENERATOR_PLATFORM"); if (platform) { this->setPlatform(QString::fromLocal8Bit(platform->c_str())); } - cmProp toolset = state->GetCacheEntryValue("CMAKE_GENERATOR_TOOLSET"); + cmValue toolset = state->GetCacheEntryValue("CMAKE_GENERATOR_TOOLSET"); if (toolset) { this->setToolset(QString::fromLocal8Bit(toolset->c_str())); } @@ -396,11 +396,11 @@ QCMakePropertyList QCMake::properties() const continue; } - cmProp cachedValue = state->GetCacheEntryValue(key); + cmValue cachedValue = state->GetCacheEntryValue(key); QCMakeProperty prop; prop.Key = QString::fromLocal8Bit(key.c_str()); - if (cmProp hs = state->GetCacheEntryProperty(key, "HELPSTRING")) { + if (cmValue hs = state->GetCacheEntryProperty(key, "HELPSTRING")) { prop.Help = QString::fromLocal8Bit(hs->c_str()); } prop.Value = QString::fromLocal8Bit(cachedValue->c_str()); @@ -414,7 +414,7 @@ QCMakePropertyList QCMake::properties() const prop.Type = QCMakeProperty::FILEPATH; } else if (t == cmStateEnums::STRING) { prop.Type = QCMakeProperty::STRING; - cmProp stringsProperty = state->GetCacheEntryProperty(key, "STRINGS"); + cmValue stringsProperty = state->GetCacheEntryProperty(key, "STRINGS"); if (stringsProperty) { prop.Strings = QString::fromLocal8Bit(stringsProperty->c_str()).split(";"); @@ -550,17 +550,14 @@ void QCMake::loadPresets() } QCMakePreset preset; - preset.name = std::move(QString::fromLocal8Bit(p.Name.data())); - preset.displayName = - std::move(QString::fromLocal8Bit(p.DisplayName.data())); - preset.description = - std::move(QString::fromLocal8Bit(p.Description.data())); - preset.generator = std::move(QString::fromLocal8Bit(p.Generator.data())); - preset.architecture = - std::move(QString::fromLocal8Bit(p.Architecture.data())); + preset.name = QString::fromLocal8Bit(p.Name.data()); + preset.displayName = QString::fromLocal8Bit(p.DisplayName.data()); + preset.description = QString::fromLocal8Bit(p.Description.data()); + preset.generator = QString::fromLocal8Bit(p.Generator.data()); + preset.architecture = QString::fromLocal8Bit(p.Architecture.data()); preset.setArchitecture = !p.ArchitectureStrategy || p.ArchitectureStrategy == cmCMakePresetsFile::ArchToolsetStrategy::Set; - preset.toolset = std::move(QString::fromLocal8Bit(p.Toolset.data())); + preset.toolset = QString::fromLocal8Bit(p.Toolset.data()); preset.setToolset = !p.ToolsetStrategy || p.ToolsetStrategy == cmCMakePresetsFile::ArchToolsetStrategy::Set; preset.enabled = it.Expanded && it.Expanded->ConditionResult && diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx index 92e04e43c..a5d1f6a07 100644 --- a/Source/cmAddLibraryCommand.cxx +++ b/Source/cmAddLibraryCommand.cxx @@ -12,6 +12,7 @@ #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmTarget.h" +#include "cmValue.h" bool cmAddLibraryCommand(std::vector<std::string> const& args, cmExecutionStatus& status) diff --git a/Source/cmAddTestCommand.cxx b/Source/cmAddTestCommand.cxx index 205c1c7a5..a0d5732fd 100644 --- a/Source/cmAddTestCommand.cxx +++ b/Source/cmAddTestCommand.cxx @@ -140,7 +140,7 @@ bool cmAddTestCommandHandleNameMode(std::vector<std::string> const& args, test->SetOldStyle(false); test->SetCommand(command); if (!working_directory.empty()) { - test->SetProperty("WORKING_DIRECTORY", working_directory.c_str()); + test->SetProperty("WORKING_DIRECTORY", working_directory); } test->SetCommandExpandLists(command_expand_lists); mf.AddTestGenerator(cm::make_unique<cmTestGenerator>(test, configurations)); diff --git a/Source/cmAlgorithms.h b/Source/cmAlgorithms.h index c192e2a7b..a1830f9f8 100644 --- a/Source/cmAlgorithms.h +++ b/Source/cmAlgorithms.h @@ -60,6 +60,10 @@ class cmListFileBacktrace; using cmBacktraceRange = cmRange<std::vector<cmListFileBacktrace>::const_iterator>; +template <typename T> +class BT; +using cmBTStringRange = cmRange<std::vector<BT<std::string>>::const_iterator>; + template <typename Range> typename Range::const_iterator cmRemoveN(Range& r, size_t n) { @@ -133,7 +137,13 @@ ForwardIterator cmRemoveDuplicates(ForwardIterator first, ForwardIterator last) } template <typename Range> -typename Range::const_iterator cmRemoveDuplicates(Range& r) +typename Range::iterator cmRemoveDuplicates(Range& r) +{ + return cmRemoveDuplicates(r.begin(), r.end()); +} + +template <typename Range> +typename Range::const_iterator cmRemoveDuplicates(Range const& r) { return cmRemoveDuplicates(r.begin(), r.end()); } diff --git a/Source/cmArchiveWrite.cxx b/Source/cmArchiveWrite.cxx index 54b299824..9e0d80c09 100644 --- a/Source/cmArchiveWrite.cxx +++ b/Source/cmArchiveWrite.cxx @@ -250,6 +250,9 @@ cmArchiveWrite::cmArchiveWrite(std::ostream& os, Compress c, bool cmArchiveWrite::Open() { + if (!this->Error.empty()) { + return false; + } if (archive_write_open( this->Archive, this, nullptr, reinterpret_cast<archive_write_callback*>(&Callback::Write), diff --git a/Source/cmBinUtilsLinuxELFLinker.cxx b/Source/cmBinUtilsLinuxELFLinker.cxx index 99707a3f7..a69c00d30 100644 --- a/Source/cmBinUtilsLinuxELFLinker.cxx +++ b/Source/cmBinUtilsLinuxELFLinker.cxx @@ -11,6 +11,7 @@ #include <cmsys/RegularExpression.hxx> #include "cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool.h" +#include "cmELF.h" #include "cmLDConfigLDConfigTool.h" #include "cmMakefile.h" #include "cmMessageType.h" @@ -18,10 +19,6 @@ #include "cmStringAlgorithms.h" #include "cmSystemTools.h" -#ifdef CMake_USE_ELF_PARSER -# include "cmELF.h" -#endif - static std::string ReplaceOrigin(const std::string& rpath, const std::string& origin) { @@ -91,7 +88,6 @@ bool cmBinUtilsLinuxELFLinker::ScanDependencies( { std::vector<std::string> parentRpaths; -#ifdef CMake_USE_ELF_PARSER cmELF elf(file.c_str()); if (!elf) { return false; @@ -106,7 +102,6 @@ bool cmBinUtilsLinuxELFLinker::ScanDependencies( this->Machine = elf.GetMachine(); } } -#endif return this->ScanDependencies(file, parentRpaths); } @@ -175,15 +170,11 @@ bool cmBinUtilsLinuxELFLinker::ScanDependencies( namespace { bool FileHasArchitecture(const char* filename, std::uint16_t machine) { -#ifdef CMake_USE_ELF_PARSER cmELF elf(filename); if (!elf) { return false; } return machine == 0 || machine == elf.GetMachine(); -#else - return true; -#endif } } diff --git a/Source/cmBinUtilsMacOSMachOLinker.cxx b/Source/cmBinUtilsMacOSMachOLinker.cxx index 47f77d8b9..c0643776c 100644 --- a/Source/cmBinUtilsMacOSMachOLinker.cxx +++ b/Source/cmBinUtilsMacOSMachOLinker.cxx @@ -5,6 +5,8 @@ #include <sstream> #include <string> +#include <type_traits> +#include <utility> #include <vector> #include <cm/memory> @@ -52,6 +54,26 @@ bool cmBinUtilsMacOSMachOLinker::Prepare() return true; } +auto cmBinUtilsMacOSMachOLinker::GetFileInfo(std::string const& file) + -> const FileInfo* +{ + // Memoize processed rpaths and library dependencies to reduce the number + // of calls to otool, especially in the case of heavily recursive libraries + auto iter = ScannedFileInfo.find(file); + if (iter != ScannedFileInfo.end()) { + return &iter->second; + } + + FileInfo file_info; + if (!this->Tool->GetFileInfo(file, file_info.libs, file_info.rpaths)) { + // Call to otool failed + return nullptr; + } + + auto iter_inserted = ScannedFileInfo.insert({ file, std::move(file_info) }); + return &iter_inserted.first->second; +} + bool cmBinUtilsMacOSMachOLinker::ScanDependencies( std::string const& file, cmStateEnums::TargetType type) { @@ -65,12 +87,12 @@ bool cmBinUtilsMacOSMachOLinker::ScanDependencies( if (!executableFile.empty()) { executablePath = cmSystemTools::GetFilenamePath(executableFile); } - std::vector<std::string> libs; - std::vector<std::string> rpaths; - if (!this->Tool->GetFileInfo(file, libs, rpaths)) { + const FileInfo* file_info = this->GetFileInfo(file); + if (file_info == nullptr) { return false; } - return this->ScanDependencies(file, libs, rpaths, executablePath); + return this->ScanDependencies(file, file_info->libs, file_info->rpaths, + executablePath); } bool cmBinUtilsMacOSMachOLinker::ScanDependencies( @@ -98,14 +120,16 @@ bool cmBinUtilsMacOSMachOLinker::GetFileDependencies( !IsMissingSystemDylib(path)) { auto filename = cmSystemTools::GetFilenameName(path); bool unique; - std::vector<std::string> libs; - std::vector<std::string> depRpaths; - if (!this->Tool->GetFileInfo(path, libs, depRpaths)) { + const FileInfo* dep_file_info = this->GetFileInfo(path); + if (dep_file_info == nullptr) { return false; } - this->Archive->AddResolvedPath(filename, path, unique, depRpaths); + + this->Archive->AddResolvedPath(filename, path, unique, + dep_file_info->rpaths); if (unique && - !this->ScanDependencies(path, libs, depRpaths, executablePath)) { + !this->ScanDependencies(path, dep_file_info->libs, + dep_file_info->rpaths, executablePath)) { return false; } } diff --git a/Source/cmBinUtilsMacOSMachOLinker.h b/Source/cmBinUtilsMacOSMachOLinker.h index eae23cc88..ac1177bb5 100644 --- a/Source/cmBinUtilsMacOSMachOLinker.h +++ b/Source/cmBinUtilsMacOSMachOLinker.h @@ -5,6 +5,7 @@ #include <memory> #include <string> +#include <unordered_map> #include <vector> #include "cmBinUtilsLinker.h" @@ -24,7 +25,16 @@ public: cmStateEnums::TargetType type) override; private: + struct FileInfo + { + std::vector<std::string> libs; + std::vector<std::string> rpaths; + }; + std::unique_ptr<cmBinUtilsMacOSMachOGetRuntimeDependenciesTool> Tool; + std::unordered_map<std::string, FileInfo> ScannedFileInfo; + + const FileInfo* GetFileInfo(std::string const& file); bool ScanDependencies(std::string const& file, std::vector<std::string> const& libs, diff --git a/Source/cmBuildCommand.cxx b/Source/cmBuildCommand.cxx index 56b080aa6..415a12447 100644 --- a/Source/cmBuildCommand.cxx +++ b/Source/cmBuildCommand.cxx @@ -6,10 +6,10 @@ #include "cmGlobalGenerator.h" #include "cmMakefile.h" #include "cmMessageType.h" -#include "cmProperty.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" namespace { @@ -102,7 +102,7 @@ bool TwoArgsSignature(std::vector<std::string> const& args, cmMakefile& mf = status.GetMakefile(); std::string const& define = args[0]; - cmProp cacheValue = mf.GetDefinition(define); + cmValue cacheValue = mf.GetDefinition(define); std::string configType; if (!cmSystemTools::GetEnv("CMAKE_CONFIG_TYPE", configType) || diff --git a/Source/cmBuildNameCommand.cxx b/Source/cmBuildNameCommand.cxx index f9b8f8f5d..20d6089b9 100644 --- a/Source/cmBuildNameCommand.cxx +++ b/Source/cmBuildNameCommand.cxx @@ -8,9 +8,9 @@ #include "cmExecutionStatus.h" #include "cmMakefile.h" -#include "cmProperty.h" #include "cmStateTypes.h" #include "cmSystemTools.h" +#include "cmValue.h" bool cmBuildNameCommand(std::vector<std::string> const& args, cmExecutionStatus& status) @@ -20,7 +20,7 @@ bool cmBuildNameCommand(std::vector<std::string> const& args, return false; } cmMakefile& mf = status.GetMakefile(); - cmProp cacheValue = mf.GetDefinition(args[0]); + cmValue cacheValue = mf.GetDefinition(args[0]); if (cacheValue) { // do we need to correct the value? cmsys::RegularExpression reg("[()/]"); diff --git a/Source/cmCMakeHostSystemInformationCommand.cxx b/Source/cmCMakeHostSystemInformationCommand.cxx index 055056887..3922c565a 100644 --- a/Source/cmCMakeHostSystemInformationCommand.cxx +++ b/Source/cmCMakeHostSystemInformationCommand.cxx @@ -2,214 +2,517 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCMakeHostSystemInformationCommand.h" -#include <cstddef> +#include <algorithm> +#include <cassert> +#include <cctype> +#include <initializer_list> +#include <map> +#include <string> +#include <type_traits> +#include <utility> +#include <cm/optional> +#include <cm/string_view> +#include <cmext/string_view> + +#include "cmsys/FStream.hxx" +#include "cmsys/Glob.hxx" #include "cmsys/SystemInformation.hxx" #include "cmExecutionStatus.h" #include "cmMakefile.h" +#include "cmStringAlgorithms.h" +#include "cmSystemTools.h" -#if defined(_WIN32) +#ifdef _WIN32 # include "cmAlgorithms.h" # include "cmGlobalGenerator.h" +# include "cmGlobalVisualStudio10Generator.h" # include "cmGlobalVisualStudioVersionedGenerator.h" -# include "cmSystemTools.h" # include "cmVSSetupHelper.h" # define HAVE_VS_SETUP_HELPER #endif namespace { -bool GetValue(cmExecutionStatus& status, cmsys::SystemInformation& info, - std::string const& key, std::string& value); -std::string ValueToString(size_t value); -std::string ValueToString(const char* value); -std::string ValueToString(std::string const& value); -} +std::string const DELIM[2] = { {}, ";" }; -// cmCMakeHostSystemInformation -bool cmCMakeHostSystemInformationCommand(std::vector<std::string> const& args, - cmExecutionStatus& status) +// BEGIN Private functions +std::string ValueToString(std::size_t const value) { - size_t current_index = 0; - - if (args.size() < (current_index + 2) || args[current_index] != "RESULT") { - status.SetError("missing RESULT specification."); - return false; - } - - std::string const& variable = args[current_index + 1]; - current_index += 2; - - if (args.size() < (current_index + 2) || args[current_index] != "QUERY") { - status.SetError("missing QUERY specification"); - return false; - } - - cmsys::SystemInformation info; - info.RunCPUCheck(); - info.RunOSCheck(); - info.RunMemoryCheck(); - - std::string result_list; - for (size_t i = current_index + 1; i < args.size(); ++i) { - std::string const& key = args[i]; - if (i != current_index + 1) { - result_list += ";"; - } - std::string value; - if (!GetValue(status, info, key, value)) { - return false; - } - result_list += value; - } - - status.GetMakefile().AddDefinition(variable, result_list); + return std::to_string(value); +} - return true; +std::string ValueToString(const char* const value) +{ + return value ? value : std::string{}; } -namespace { +std::string ValueToString(std::string const& value) +{ + return value; +} -bool GetValue(cmExecutionStatus& status, cmsys::SystemInformation& info, - std::string const& key, std::string& value) +cm::optional<std::string> GetValue(cmsys::SystemInformation& info, + std::string const& key) { - if (key == "NUMBER_OF_LOGICAL_CORES") { - value = ValueToString(info.GetNumberOfLogicalCPU()); - } else if (key == "NUMBER_OF_PHYSICAL_CORES") { - value = ValueToString(info.GetNumberOfPhysicalCPU()); - } else if (key == "HOSTNAME") { - value = ValueToString(info.GetHostname()); - } else if (key == "FQDN") { - value = ValueToString(info.GetFullyQualifiedDomainName()); - } else if (key == "TOTAL_VIRTUAL_MEMORY") { - value = ValueToString(info.GetTotalVirtualMemory()); - } else if (key == "AVAILABLE_VIRTUAL_MEMORY") { - value = ValueToString(info.GetAvailableVirtualMemory()); - } else if (key == "TOTAL_PHYSICAL_MEMORY") { - value = ValueToString(info.GetTotalPhysicalMemory()); - } else if (key == "AVAILABLE_PHYSICAL_MEMORY") { - value = ValueToString(info.GetAvailablePhysicalMemory()); - } else if (key == "IS_64BIT") { - value = ValueToString(info.Is64Bits()); - } else if (key == "HAS_FPU") { - value = ValueToString( + if (key == "NUMBER_OF_LOGICAL_CORES"_s) { + return ValueToString(info.GetNumberOfLogicalCPU()); + } + if (key == "NUMBER_OF_PHYSICAL_CORES"_s) { + return ValueToString(info.GetNumberOfPhysicalCPU()); + } + if (key == "HOSTNAME"_s) { + return ValueToString(info.GetHostname()); + } + if (key == "FQDN"_s) { + return ValueToString(info.GetFullyQualifiedDomainName()); + } + if (key == "TOTAL_VIRTUAL_MEMORY"_s) { + return ValueToString(info.GetTotalVirtualMemory()); + } + if (key == "AVAILABLE_VIRTUAL_MEMORY"_s) { + return ValueToString(info.GetAvailableVirtualMemory()); + } + if (key == "TOTAL_PHYSICAL_MEMORY"_s) { + return ValueToString(info.GetTotalPhysicalMemory()); + } + if (key == "AVAILABLE_PHYSICAL_MEMORY"_s) { + return ValueToString(info.GetAvailablePhysicalMemory()); + } + if (key == "IS_64BIT"_s) { + return ValueToString(info.Is64Bits()); + } + if (key == "HAS_FPU"_s) { + return ValueToString( info.DoesCPUSupportFeature(cmsys::SystemInformation::CPU_FEATURE_FPU)); - } else if (key == "HAS_MMX") { - value = ValueToString( + } + if (key == "HAS_MMX"_s) { + return ValueToString( info.DoesCPUSupportFeature(cmsys::SystemInformation::CPU_FEATURE_MMX)); - } else if (key == "HAS_MMX_PLUS") { - value = ValueToString(info.DoesCPUSupportFeature( + } + if (key == "HAS_MMX_PLUS"_s) { + return ValueToString(info.DoesCPUSupportFeature( cmsys::SystemInformation::CPU_FEATURE_MMX_PLUS)); - } else if (key == "HAS_SSE") { - value = ValueToString( + } + if (key == "HAS_SSE"_s) { + return ValueToString( info.DoesCPUSupportFeature(cmsys::SystemInformation::CPU_FEATURE_SSE)); - } else if (key == "HAS_SSE2") { - value = ValueToString( + } + if (key == "HAS_SSE2"_s) { + return ValueToString( info.DoesCPUSupportFeature(cmsys::SystemInformation::CPU_FEATURE_SSE2)); - } else if (key == "HAS_SSE_FP") { - value = ValueToString(info.DoesCPUSupportFeature( + } + if (key == "HAS_SSE_FP"_s) { + return ValueToString(info.DoesCPUSupportFeature( cmsys::SystemInformation::CPU_FEATURE_SSE_FP)); - } else if (key == "HAS_SSE_MMX") { - value = ValueToString(info.DoesCPUSupportFeature( + } + if (key == "HAS_SSE_MMX"_s) { + return ValueToString(info.DoesCPUSupportFeature( cmsys::SystemInformation::CPU_FEATURE_SSE_MMX)); - } else if (key == "HAS_AMD_3DNOW") { - value = ValueToString(info.DoesCPUSupportFeature( + } + if (key == "HAS_AMD_3DNOW"_s) { + return ValueToString(info.DoesCPUSupportFeature( cmsys::SystemInformation::CPU_FEATURE_AMD_3DNOW)); - } else if (key == "HAS_AMD_3DNOW_PLUS") { - value = ValueToString(info.DoesCPUSupportFeature( + } + if (key == "HAS_AMD_3DNOW_PLUS"_s) { + return ValueToString(info.DoesCPUSupportFeature( cmsys::SystemInformation::CPU_FEATURE_AMD_3DNOW_PLUS)); - } else if (key == "HAS_IA64") { - value = ValueToString( + } + if (key == "HAS_IA64"_s) { + return ValueToString( info.DoesCPUSupportFeature(cmsys::SystemInformation::CPU_FEATURE_IA64)); - } else if (key == "HAS_SERIAL_NUMBER") { - value = ValueToString(info.DoesCPUSupportFeature( + } + if (key == "HAS_SERIAL_NUMBER"_s) { + return ValueToString(info.DoesCPUSupportFeature( cmsys::SystemInformation::CPU_FEATURE_SERIALNUMBER)); - } else if (key == "PROCESSOR_NAME") { - value = ValueToString(info.GetExtendedProcessorName()); - } else if (key == "PROCESSOR_DESCRIPTION") { - value = info.GetCPUDescription(); - } else if (key == "PROCESSOR_SERIAL_NUMBER") { - value = ValueToString(info.GetProcessorSerialNumber()); - } else if (key == "OS_NAME") { - value = ValueToString(info.GetOSName()); - } else if (key == "OS_RELEASE") { - value = ValueToString(info.GetOSRelease()); - } else if (key == "OS_VERSION") { - value = ValueToString(info.GetOSVersion()); - } else if (key == "OS_PLATFORM") { - value = ValueToString(info.GetOSPlatform()); -#ifdef HAVE_VS_SETUP_HELPER - } else if (key == "VS_15_DIR") { - // If generating for the VS 15 IDE, use the same instance. - cmGlobalGenerator* gg = status.GetMakefile().GetGlobalGenerator(); - if (cmHasLiteralPrefix(gg->GetName(), "Visual Studio 15 ")) { - cmGlobalVisualStudioVersionedGenerator* vs15gen = - static_cast<cmGlobalVisualStudioVersionedGenerator*>(gg); - if (vs15gen->GetVSInstance(value)) { - return true; - } + } + if (key == "PROCESSOR_NAME"_s) { + return ValueToString(info.GetExtendedProcessorName()); + } + if (key == "PROCESSOR_DESCRIPTION"_s) { + return info.GetCPUDescription(); + } + if (key == "PROCESSOR_SERIAL_NUMBER"_s) { + return ValueToString(info.GetProcessorSerialNumber()); + } + if (key == "OS_NAME"_s) { + return ValueToString(info.GetOSName()); + } + if (key == "OS_RELEASE"_s) { + return ValueToString(info.GetOSRelease()); + } + if (key == "OS_VERSION"_s) { + return ValueToString(info.GetOSVersion()); + } + if (key == "OS_PLATFORM"_s) { + return ValueToString(info.GetOSPlatform()); + } + return {}; +} + +cm::optional<std::pair<std::string, std::string>> ParseOSReleaseLine( + std::string const& line) +{ + std::string key; + std::string value; + + char prev = 0; + enum ParserState + { + PARSE_KEY_1ST, + PARSE_KEY, + FOUND_EQ, + PARSE_SINGLE_QUOTE_VALUE, + PARSE_DBL_QUOTE_VALUE, + PARSE_VALUE, + IGNORE_REST + } state = PARSE_KEY_1ST; + + for (auto ch : line) { + switch (state) { + case PARSE_KEY_1ST: + if (std::isalpha(ch) || ch == '_') { + key += ch; + state = PARSE_KEY; + } else if (!std::isspace(ch)) { + state = IGNORE_REST; + } + break; + + case PARSE_KEY: + if (ch == '=') { + state = FOUND_EQ; + } else if (std::isalnum(ch) || ch == '_') { + key += ch; + } else { + state = IGNORE_REST; + } + break; + + case FOUND_EQ: + switch (ch) { + case '\'': + state = PARSE_SINGLE_QUOTE_VALUE; + break; + case '"': + state = PARSE_DBL_QUOTE_VALUE; + break; + case '#': + case '\\': + state = IGNORE_REST; + break; + default: + value += ch; + state = PARSE_VALUE; + } + break; + + case PARSE_SINGLE_QUOTE_VALUE: + if (ch == '\'') { + if (prev != '\\') { + state = IGNORE_REST; + } else { + assert(!value.empty()); + value[value.size() - 1] = ch; + } + } else { + value += ch; + } + break; + + case PARSE_DBL_QUOTE_VALUE: + if (ch == '"') { + if (prev != '\\') { + state = IGNORE_REST; + } else { + assert(!value.empty()); + value[value.size() - 1] = ch; + } + } else { + value += ch; + } + break; + + case PARSE_VALUE: + if (ch == '#' || std::isspace(ch)) { + state = IGNORE_REST; + } else { + value += ch; + } + break; + + default: + // Unexpected os-release parser state! + state = IGNORE_REST; + break; } - // Otherwise, find a VS 15 instance ourselves. - cmVSSetupAPIHelper vsSetupAPIHelper(15); - if (vsSetupAPIHelper.GetVSInstanceInfo(value)) { - cmSystemTools::ConvertToUnixSlashes(value); + if (state == IGNORE_REST) { + break; } - } else if (key == "VS_16_DIR") { - // If generating for the VS 16 IDE, use the same instance. - cmGlobalGenerator* gg = status.GetMakefile().GetGlobalGenerator(); - if (cmHasLiteralPrefix(gg->GetName(), "Visual Studio 16 ")) { - cmGlobalVisualStudioVersionedGenerator* vs16gen = - static_cast<cmGlobalVisualStudioVersionedGenerator*>(gg); - if (vs16gen->GetVSInstance(value)) { - return true; + prev = ch; + } + if (!(key.empty() || value.empty())) { + return std::make_pair(key, value); + } + return {}; +} + +std::map<std::string, std::string> GetOSReleaseVariables( + cmExecutionStatus& status) +{ + auto& makefile = status.GetMakefile(); + const auto& sysroot = makefile.GetSafeDefinition("CMAKE_SYSROOT"); + + std::map<std::string, std::string> data; + // Based on + // https://www.freedesktop.org/software/systemd/man/os-release.html + for (auto name : { "/etc/os-release"_s, "/usr/lib/os-release"_s }) { + const auto& filename = cmStrCat(sysroot, name); + if (cmSystemTools::FileExists(filename)) { + cmsys::ifstream fin(filename.c_str()); + for (std::string line; !std::getline(fin, line).fail();) { + auto kv = ParseOSReleaseLine(line); + if (kv.has_value()) { + data.emplace(kv.value()); + } } + break; + } + } + // Got smth? + if (!data.empty()) { + return data; + } + + // Ugh, it could be some pre-os-release distro. + // Lets try some fallback getters. + // See also: + // - http://linuxmafia.com/faq/Admin/release-files.html + + // 1. CMake provided + cmsys::Glob gl; + std::vector<std::string> scripts; + auto const findExpr = cmStrCat(cmSystemTools::GetCMakeRoot(), + "/Modules/Internal/OSRelease/*.cmake"); + if (gl.FindFiles(findExpr)) { + scripts = gl.GetFiles(); + } + + // 2. User provided (append to the CMake prvided) + makefile.GetDefExpandList("CMAKE_GET_OS_RELEASE_FALLBACK_SCRIPTS", scripts); + + // Filter out files that are not in format `NNN-name.cmake` + auto checkName = [](std::string const& filepath) -> bool { + auto const& filename = cmSystemTools::GetFilenameName(filepath); + // NOTE Minimum filename length expected: + // NNN-<at-least-one-char-name>.cmake --> 11 + return (filename.size() < 11) || !std::isdigit(filename[0]) || + !std::isdigit(filename[1]) || !std::isdigit(filename[2]) || + filename[3] != '-'; + }; + scripts.erase(std::remove_if(scripts.begin(), scripts.end(), checkName), + scripts.end()); + + // Make sure scripts are running in desired order + std::sort(scripts.begin(), scripts.end(), + [](std::string const& lhs, std::string const& rhs) -> bool { + long lhs_order; + cmStrToLong(cmSystemTools::GetFilenameName(lhs).substr(0u, 3u), + &lhs_order); + long rhs_order; + cmStrToLong(cmSystemTools::GetFilenameName(rhs).substr(0u, 3u), + &rhs_order); + return lhs_order < rhs_order; + }); + + // Name of the variable to put the results + auto const result_variable = "CMAKE_GET_OS_RELEASE_FALLBACK_RESULT"_s; + + for (auto const& script : scripts) { + // Unset the result variable + makefile.RemoveDefinition(result_variable.data()); + + // include FATAL_ERROR and ERROR in the return status + if (!makefile.ReadListFile(script) || + cmSystemTools::GetErrorOccuredFlag()) { + // Ok, no worries... go try the next script. + continue; } - // Otherwise, find a VS 16 instance ourselves. - cmVSSetupAPIHelper vsSetupAPIHelper(16); - if (vsSetupAPIHelper.GetVSInstanceInfo(value)) { - cmSystemTools::ConvertToUnixSlashes(value); + std::vector<std::string> variables; + if (!makefile.GetDefExpandList(result_variable.data(), variables)) { + // Heh, this script didn't found anything... go try the next one. + continue; } - } else if (key == "VS_17_DIR") { - // If generating for the VS 17 IDE, use the same instance. - cmGlobalGenerator* gg = status.GetMakefile().GetGlobalGenerator(); - if (cmHasLiteralPrefix(gg->GetName(), "Visual Studio 17 ")) { - cmGlobalVisualStudioVersionedGenerator* vs17gen = - static_cast<cmGlobalVisualStudioVersionedGenerator*>(gg); - if (vs17gen->GetVSInstance(value)) { - return true; + + for (auto const& variable : variables) { + auto value = makefile.GetSafeDefinition(variable); + makefile.RemoveDefinition(variable); + + if (!cmHasPrefix(variable, cmStrCat(result_variable, '_'))) { + // Ignore unknown variable set by the script + continue; } + + auto key = variable.substr(result_variable.size() + 1, + variable.size() - result_variable.size() - 1); + data.emplace(std::move(key), std::move(value)); } - // Otherwise, find a VS 17 instance ourselves. - cmVSSetupAPIHelper vsSetupAPIHelper(17); - if (vsSetupAPIHelper.GetVSInstanceInfo(value)) { - cmSystemTools::ConvertToUnixSlashes(value); + // Try 'till some script can get anything + if (!data.empty()) { + data.emplace("USED_FALLBACK_SCRIPT", script); + break; } -#endif - } else { - std::string e = "does not recognize <key> " + key; - status.SetError(e); - return false; } - return true; + makefile.RemoveDefinition(result_variable.data()); + + return data; } -std::string ValueToString(size_t value) +cm::optional<std::string> GetValue(cmExecutionStatus& status, + std::string const& key, + std::string const& variable) { - return std::to_string(value); + const auto prefix = "DISTRIB_"_s; + if (!cmHasPrefix(key, prefix)) { + return {}; + } + + static const std::map<std::string, std::string> s_os_release = + GetOSReleaseVariables(status); + + auto& makefile = status.GetMakefile(); + + const std::string subkey = + key.substr(prefix.size(), key.size() - prefix.size()); + if (subkey == "INFO"_s) { + std::string vars; + for (const auto& kv : s_os_release) { + auto cmake_var_name = cmStrCat(variable, '_', kv.first); + vars += DELIM[!vars.empty()] + cmake_var_name; + makefile.AddDefinition(cmake_var_name, kv.second); + } + return cm::optional<std::string>(std::move(vars)); + } + + // Query individual variable + const auto it = s_os_release.find(subkey); + if (it != s_os_release.cend()) { + return it->second; + } + + // NOTE Empty string means requested variable not set + return std::string{}; } -std::string ValueToString(const char* value) +#ifdef HAVE_VS_SETUP_HELPER +cm::optional<std::string> GetValue(cmExecutionStatus& status, + std::string const& key) { - std::string safe_string = value ? value : ""; - return safe_string; + auto* const gg = status.GetMakefile().GetGlobalGenerator(); + for (auto vs : { 15, 16, 17 }) { + if (key == cmStrCat("VS_"_s, vs, "_DIR"_s)) { + std::string value; + // If generating for the VS nn IDE, use the same instance. + + if (cmHasPrefix(gg->GetName(), cmStrCat("Visual Studio "_s, vs, ' '))) { + cmGlobalVisualStudioVersionedGenerator* vsNNgen = + static_cast<cmGlobalVisualStudioVersionedGenerator*>(gg); + if (vsNNgen->GetVSInstance(value)) { + return value; + } + } + + // Otherwise, find a VS nn instance ourselves. + cmVSSetupAPIHelper vsSetupAPIHelper(vs); + if (vsSetupAPIHelper.GetVSInstanceInfo(value)) { + cmSystemTools::ConvertToUnixSlashes(value); + } + return value; + } + } + + if (key == "VS_MSBUILD_COMMAND"_s && gg->IsVisualStudioAtLeast10()) { + cmGlobalVisualStudio10Generator* vs10gen = + static_cast<cmGlobalVisualStudio10Generator*>(gg); + return vs10gen->FindMSBuildCommandEarly(&status.GetMakefile()); + } + + return {}; } +#endif -std::string ValueToString(std::string const& value) +cm::optional<std::string> GetValueChained() { - return value; + return {}; } + +template <typename GetterFn, typename... Next> +cm::optional<std::string> GetValueChained(GetterFn current, Next... chain) +{ + auto value = current(); + if (value.has_value()) { + return value; + } + return GetValueChained(chain...); +} +// END Private functions +} // anonymous namespace + +// cmCMakeHostSystemInformation +bool cmCMakeHostSystemInformationCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) +{ + std::size_t current_index = 0; + + if (args.size() < (current_index + 2) || args[current_index] != "RESULT"_s) { + status.SetError("missing RESULT specification."); + return false; + } + + auto const& variable = args[current_index + 1]; + current_index += 2; + + if (args.size() < (current_index + 2) || args[current_index] != "QUERY"_s) { + status.SetError("missing QUERY specification"); + return false; + } + + static cmsys::SystemInformation info; + static auto initialized = false; + if (!initialized) { + info.RunCPUCheck(); + info.RunOSCheck(); + info.RunMemoryCheck(); + initialized = true; + } + + std::string result_list; + for (auto i = current_index + 1; i < args.size(); ++i) { + result_list += DELIM[!result_list.empty()]; + + auto const& key = args[i]; + // clang-format off + auto value = + GetValueChained( + [&]() { return GetValue(info, key); } + , [&]() { return GetValue(status, key, variable); } +#ifdef HAVE_VS_SETUP_HELPER + , [&]() { return GetValue(status, key); } +#endif + ); + // clang-format on + if (!value) { + status.SetError("does not recognize <key> " + key); + return false; + } + result_list += value.value(); + } + + status.GetMakefile().AddDefinition(variable, result_list); + + return true; } diff --git a/Source/cmCMakePathCommand.cxx b/Source/cmCMakePathCommand.cxx index 9a5fa7bfc..bf94c2dce 100644 --- a/Source/cmCMakePathCommand.cxx +++ b/Source/cmCMakePathCommand.cxx @@ -18,11 +18,11 @@ #include "cmCMakePath.h" #include "cmExecutionStatus.h" #include "cmMakefile.h" -#include "cmProperty.h" #include "cmRange.h" #include "cmStringAlgorithms.h" #include "cmSubcommandTable.h" #include "cmSystemTools.h" +#include "cmValue.h" namespace { // Helper classes for argument parsing @@ -150,7 +150,7 @@ public: bool getInputPath(const std::string& arg, cmExecutionStatus& status, std::string& path) { - cmProp def = status.GetMakefile().GetDefinition(arg); + cmValue def = status.GetMakefile().GetDefinition(arg); if (!def) { status.SetError("undefined variable for input path."); return false; diff --git a/Source/cmCMakePolicyCommand.cxx b/Source/cmCMakePolicyCommand.cxx index 1f9904364..ebf639b74 100644 --- a/Source/cmCMakePolicyCommand.cxx +++ b/Source/cmCMakePolicyCommand.cxx @@ -9,6 +9,7 @@ #include "cmState.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" +#include "cmValue.h" namespace { bool HandleSetMode(std::vector<std::string> const& args, diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx index ace73825a..e46003117 100644 --- a/Source/cmCPluginAPI.cxx +++ b/Source/cmCPluginAPI.cxx @@ -140,7 +140,7 @@ const char* CCONV cmGetCurrentOutputDirectory(void* arg) const char* CCONV cmGetDefinition(void* arg, const char* def) { cmMakefile* mf = static_cast<cmMakefile*>(arg); - return cmToCStr(mf->GetDefinition(def)); + return mf->GetDefinition(def).GetCStr(); } int CCONV cmIsOn(void* arg, const char* name) @@ -173,7 +173,7 @@ void CCONV cmAddLinkDirectoryForTarget(void* arg, const char* tgt, std::string(tgt) + " for directory " + std::string(d)); return; } - t->InsertLinkDirectory(d, mf->GetBacktrace()); + t->InsertLinkDirectory(BT<std::string>(d, mf->GetBacktrace())); } void CCONV cmAddExecutable(void* arg, const char* exename, int numSrcs, @@ -592,12 +592,12 @@ const char* CCONV cmSourceFileGetProperty(void* arg, const char* prop) { cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg); if (cmSourceFile* rsf = sf->RealSourceFile) { - return cmToCStr(rsf->GetProperty(prop)); + return rsf->GetProperty(prop).GetCStr(); } if (!strcmp(prop, "LOCATION")) { return sf->FullPath.c_str(); } - return cmToCStr(sf->Properties.GetPropertyValue(prop)); + return sf->Properties.GetPropertyValue(prop).GetCStr(); } int CCONV cmSourceFileGetPropertyAsBool(void* arg, const char* prop) diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index 7c469c84a..dfd2b6c34 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -56,12 +56,12 @@ #include "cmGlobalGenerator.h" #include "cmMakefile.h" #include "cmProcessOutput.h" -#include "cmProperty.h" #include "cmState.h" #include "cmStateSnapshot.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" #include "cmVersion.h" #include "cmVersionConfig.h" #include "cmXMLWriter.h" @@ -1457,11 +1457,11 @@ void cmCTest::AddSiteProperties(cmXMLWriter& xml) return; } // This code should go when cdash is changed to use labels only - cmProp subproject = cm->GetState()->GetGlobalProperty("SubProject"); + cmValue subproject = cm->GetState()->GetGlobalProperty("SubProject"); if (subproject) { xml.StartElement("Subproject"); xml.Attribute("name", *subproject); - cmProp labels = + cmValue labels = ch->GetCMake()->GetState()->GetGlobalProperty("SubProjectLabels"); if (labels) { xml.StartElement("Labels"); @@ -1475,7 +1475,7 @@ void cmCTest::AddSiteProperties(cmXMLWriter& xml) } // This code should stay when cdash only does label based sub-projects - cmProp label = cm->GetState()->GetGlobalProperty("Label"); + cmValue label = cm->GetState()->GetGlobalProperty("Label"); if (label) { xml.StartElement("Labels"); xml.Element("Label", *label); @@ -2425,7 +2425,7 @@ bool cmCTest::SetArgsFromPreset(const std::string& presetName, case cmCMakePresetsFile::TestPreset::OutputOptions::VerbosityEnum:: Extra: this->Impl->ExtraVerbose = true; - // intentional fallthrough + CM_FALLTHROUGH; case cmCMakePresetsFile::TestPreset::OutputOptions::VerbosityEnum:: Verbose: this->Impl->Verbose = true; @@ -3056,7 +3056,7 @@ int cmCTest::ReadCustomConfigurationFileTree(const std::string& dir, void cmCTest::PopulateCustomVector(cmMakefile* mf, const std::string& def, std::vector<std::string>& vec) { - cmProp dval = mf->GetDefinition(def); + cmValue dval = mf->GetDefinition(def); if (!dval) { return; } @@ -3073,7 +3073,7 @@ void cmCTest::PopulateCustomVector(cmMakefile* mf, const std::string& def, void cmCTest::PopulateCustomInteger(cmMakefile* mf, const std::string& def, int& val) { - cmProp dval = mf->GetDefinition(def); + cmValue dval = mf->GetDefinition(def); if (!dval) { return; } @@ -3407,7 +3407,7 @@ bool cmCTest::SetCTestConfigurationFromCMakeVariable( cmMakefile* mf, const char* dconfig, const std::string& cmake_var, bool suppress) { - cmProp ctvar = mf->GetDefinition(cmake_var); + cmValue ctvar = mf->GetDefinition(cmake_var); if (!ctvar) { return false; } diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx index 1a950dfb0..b9d1f66d2 100644 --- a/Source/cmCacheManager.cxx +++ b/Source/cmCacheManager.cxx @@ -118,13 +118,13 @@ bool cmCacheManager::LoadCache(const std::string& path, bool internal, } this->CacheMajorVersion = 0; this->CacheMinorVersion = 0; - if (cmProp cmajor = + if (cmValue cmajor = this->GetInitializedCacheValue("CMAKE_CACHE_MAJOR_VERSION")) { unsigned int v = 0; if (sscanf(cmajor->c_str(), "%u", &v) == 1) { this->CacheMajorVersion = v; } - if (cmProp cminor = + if (cmValue cminor = this->GetInitializedCacheValue("CMAKE_CACHE_MINOR_VERSION")) { if (sscanf(cminor->c_str(), "%u", &v) == 1) { this->CacheMinorVersion = v; @@ -144,7 +144,7 @@ bool cmCacheManager::LoadCache(const std::string& path, bool internal, } // check to make sure the cache directory has not // been moved - cmProp oldDir = this->GetInitializedCacheValue("CMAKE_CACHEFILE_DIR"); + cmValue oldDir = this->GetInitializedCacheValue("CMAKE_CACHEFILE_DIR"); if (internal && oldDir) { std::string currentcwd = path; std::string oldcwd = *oldDir; @@ -152,7 +152,7 @@ bool cmCacheManager::LoadCache(const std::string& path, bool internal, currentcwd += "/CMakeCache.txt"; oldcwd += "/CMakeCache.txt"; if (!cmSystemTools::SameFile(oldcwd, currentcwd)) { - cmProp dir = this->GetInitializedCacheValue("CMAKE_CACHEFILE_DIR"); + cmValue dir = this->GetInitializedCacheValue("CMAKE_CACHEFILE_DIR"); std::ostringstream message; message << "The current CMakeCache.txt directory " << currentcwd << " is different than the directory " << (dir ? *dir : "") @@ -203,7 +203,7 @@ void cmCacheManager::WritePropertyEntries(std::ostream& os, cmMessenger* messenger) const { for (const char* p : cmCacheManager::PersistentProperties) { - if (cmProp value = e.GetProperty(p)) { + if (cmValue value = e.GetProperty(p)) { std::string helpstring = cmStrCat(p, " property for variable: ", entryKey); cmCacheManager::OutputHelpString(os, helpstring); @@ -232,17 +232,17 @@ bool cmCacheManager::SaveCache(const std::string& path, cmMessenger* messenger) // before writing the cache, update the version numbers // to the this->AddCacheEntry("CMAKE_CACHE_MAJOR_VERSION", - std::to_string(cmVersion::GetMajorVersion()).c_str(), + std::to_string(cmVersion::GetMajorVersion()), "Major version of cmake used to create the " "current loaded cache", cmStateEnums::INTERNAL); this->AddCacheEntry("CMAKE_CACHE_MINOR_VERSION", - std::to_string(cmVersion::GetMinorVersion()).c_str(), + std::to_string(cmVersion::GetMinorVersion()), "Minor version of cmake used to create the " "current loaded cache", cmStateEnums::INTERNAL); this->AddCacheEntry("CMAKE_CACHE_PATCH_VERSION", - std::to_string(cmVersion::GetPatchVersion()).c_str(), + std::to_string(cmVersion::GetPatchVersion()), "Patch version of cmake used to create the " "current loaded cache", cmStateEnums::INTERNAL); @@ -256,7 +256,7 @@ bool cmCacheManager::SaveCache(const std::string& path, cmMessenger* messenger) currentcwd[0] = static_cast<char>(currentcwd[0] - 'A' + 'a'); } cmSystemTools::ConvertToUnixSlashes(currentcwd); - this->AddCacheEntry("CMAKE_CACHEFILE_DIR", currentcwd.c_str(), + this->AddCacheEntry("CMAKE_CACHEFILE_DIR", currentcwd, "This is the directory where this CMakeCache.txt" " was created", cmStateEnums::INTERNAL); @@ -296,7 +296,7 @@ bool cmCacheManager::SaveCache(const std::string& path, cmMessenger* messenger) */ } else if (t != cmStateEnums::INTERNAL) { // Format is key:type=value - if (cmProp help = ce.GetProperty("HELPSTRING")) { + if (cmValue help = ce.GetProperty("HELPSTRING")) { cmCacheManager::OutputHelpString(fout, *help); } else { cmCacheManager::OutputHelpString(fout, "Missing description"); @@ -326,7 +326,7 @@ bool cmCacheManager::SaveCache(const std::string& path, cmMessenger* messenger) this->WritePropertyEntries(fout, i.first, i.second, messenger); if (t == cmStateEnums::INTERNAL) { // Format is key:type=value - if (cmProp help = i.second.GetProperty("HELPSTRING")) { + if (cmValue help = i.second.GetProperty("HELPSTRING")) { cmCacheManager::OutputHelpString(fout, *help); } cmCacheManager::OutputKey(fout, i.first); @@ -496,11 +496,11 @@ const cmCacheManager::CacheEntry* cmCacheManager::GetCacheEntry( return nullptr; } -cmProp cmCacheManager::GetInitializedCacheValue(const std::string& key) const +cmValue cmCacheManager::GetInitializedCacheValue(const std::string& key) const { if (const auto* entry = this->GetCacheEntry(key)) { if (entry->Initialized) { - return &entry->GetValue(); + return cmValue(entry->GetValue()); } } return nullptr; @@ -521,7 +521,7 @@ void cmCacheManager::PrintCache(std::ostream& out) const "=================================================\n"; } -void cmCacheManager::AddCacheEntry(const std::string& key, const char* value, +void cmCacheManager::AddCacheEntry(const std::string& key, cmValue value, const char* helpString, cmStateEnums::CacheEntryType type) { @@ -550,10 +550,10 @@ void cmCacheManager::AddCacheEntry(const std::string& key, const char* value, : "(This variable does not exist and should not be used)"); } -void cmCacheManager::CacheEntry::SetValue(const char* value) +void cmCacheManager::CacheEntry::SetValue(cmValue value) { if (value) { - this->Value = value; + this->Value = *value; this->Initialized = true; } else { this->Value.clear(); @@ -565,13 +565,13 @@ std::vector<std::string> cmCacheManager::CacheEntry::GetPropertyList() const return this->Properties.GetKeys(); } -cmProp cmCacheManager::CacheEntry::GetProperty(const std::string& prop) const +cmValue cmCacheManager::CacheEntry::GetProperty(const std::string& prop) const { if (prop == "TYPE") { - return &cmState::CacheEntryTypeToString(this->Type); + return cmValue(cmState::CacheEntryTypeToString(this->Type)); } if (prop == "VALUE") { - return &this->Value; + return cmValue(this->Value); } return this->Properties.GetPropertyValue(prop); } diff --git a/Source/cmCacheManager.h b/Source/cmCacheManager.h index 7a9a7dc41..bc3fb510a 100644 --- a/Source/cmCacheManager.h +++ b/Source/cmCacheManager.h @@ -11,9 +11,9 @@ #include <utility> #include <vector> -#include "cmProperty.h" #include "cmPropertyMap.h" #include "cmStateTypes.h" +#include "cmValue.h" class cmMessenger; @@ -31,13 +31,13 @@ class cmCacheManager public: const std::string& GetValue() const { return this->Value; } - void SetValue(const char*); + void SetValue(cmValue); cmStateEnums::CacheEntryType GetType() const { return this->Type; } void SetType(cmStateEnums::CacheEntryType ty) { this->Type = ty; } std::vector<std::string> GetPropertyList() const; - cmProp GetProperty(const std::string& property) const; + cmValue GetProperty(const std::string& property) const; bool GetPropertyAsBool(const std::string& property) const; void SetProperty(const std::string& property, const char* value); void SetProperty(const std::string& property, bool value); @@ -70,12 +70,12 @@ public: bool IsCacheLoaded() const { return this->CacheLoaded; } //! Get a value from the cache given a key - cmProp GetInitializedCacheValue(const std::string& key) const; + cmValue GetInitializedCacheValue(const std::string& key) const; - cmProp GetCacheEntryValue(const std::string& key) const + cmValue GetCacheEntryValue(const std::string& key) const { if (const auto* entry = this->GetCacheEntry(key)) { - return &entry->GetValue(); + return cmValue(entry->GetValue()); } return nullptr; } @@ -83,7 +83,7 @@ public: void SetCacheEntryValue(std::string const& key, std::string const& value) { if (auto* entry = this->GetCacheEntry(key)) { - entry->SetValue(value.c_str()); + entry->SetValue(cmValue(value)); } } @@ -104,8 +104,8 @@ public: return {}; } - cmProp GetCacheEntryProperty(std::string const& key, - std::string const& propName) const + cmValue GetCacheEntryProperty(std::string const& key, + std::string const& propName) const { if (const auto* entry = this->GetCacheEntry(key)) { return entry->GetProperty(propName); @@ -173,6 +173,18 @@ public: //! Add an entry into the cache void AddCacheEntry(const std::string& key, const char* value, + const char* helpString, cmStateEnums::CacheEntryType type) + { + this->AddCacheEntry(key, + value ? cmValue(std::string(value)) : cmValue(nullptr), + helpString, type); + } + void AddCacheEntry(const std::string& key, const std::string& value, + const char* helpString, cmStateEnums::CacheEntryType type) + { + this->AddCacheEntry(key, cmValue(value), helpString, type); + } + void AddCacheEntry(const std::string& key, cmValue value, const char* helpString, cmStateEnums::CacheEntryType type); diff --git a/Source/cmCommand.h b/Source/cmCommand.h index 68c56d90c..f5a519022 100644 --- a/Source/cmCommand.h +++ b/Source/cmCommand.h @@ -44,7 +44,7 @@ public: cmMakefile* GetMakefile() { return this->Makefile; } void SetExecutionStatus(cmExecutionStatus* s); - cmExecutionStatus* GetExecutionStatus() { return this->Status; }; + cmExecutionStatus* GetExecutionStatus() { return this->Status; } /** * This is called by the cmMakefile when the command is first diff --git a/Source/cmCommandArgumentParserHelper.cxx b/Source/cmCommandArgumentParserHelper.cxx index deddba8ef..2ed04e5c4 100644 --- a/Source/cmCommandArgumentParserHelper.cxx +++ b/Source/cmCommandArgumentParserHelper.cxx @@ -14,10 +14,10 @@ #include "cmCommandArgumentLexer.h" #include "cmListFileCache.h" #include "cmMakefile.h" -#include "cmProperty.h" #include "cmState.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" int cmCommandArgument_yyparse(yyscan_t yyscanner); // @@ -73,7 +73,8 @@ const char* cmCommandArgumentParserHelper::ExpandSpecialVariable( return ""; } if (strcmp(key, "CACHE") == 0) { - if (cmProp c = this->Makefile->GetState()->GetInitializedCacheValue(var)) { + if (cmValue c = + this->Makefile->GetState()->GetInitializedCacheValue(var)) { if (this->EscapeQuotes) { return this->AddString(cmEscapeQuotes(*c)); } @@ -103,7 +104,7 @@ const char* cmCommandArgumentParserHelper::ExpandVariable(const char* var) } return this->AddString(line); } - cmProp value = this->Makefile->GetDefinition(var); + cmValue value = this->Makefile->GetDefinition(var); if (!value) { this->Makefile->MaybeWarnUninitialized(var, this->FileName); if (!this->RemoveEmpty) { @@ -113,7 +114,7 @@ const char* cmCommandArgumentParserHelper::ExpandVariable(const char* var) if (this->EscapeQuotes && value) { return this->AddString(cmEscapeQuotes(*value)); } - return this->AddString(cmToCStrSafe(value)); + return this->AddString(value); } const char* cmCommandArgumentParserHelper::ExpandVariableForAt(const char* var) diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx index 7c2e20c01..8d5ce7ed0 100644 --- a/Source/cmCommonTargetGenerator.cxx +++ b/Source/cmCommonTargetGenerator.cxx @@ -14,12 +14,12 @@ #include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmOutputConverter.h" -#include "cmProperty.h" #include "cmRange.h" #include "cmSourceFile.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmTarget.h" +#include "cmValue.h" cmCommonTargetGenerator::cmCommonTargetGenerator(cmGeneratorTarget* gt) : GeneratorTarget(gt) @@ -39,10 +39,10 @@ std::vector<std::string> const& cmCommonTargetGenerator::GetConfigNames() const return this->ConfigNames; } -const char* cmCommonTargetGenerator::GetFeature(const std::string& feature, - const std::string& config) +cmValue cmCommonTargetGenerator::GetFeature(const std::string& feature, + const std::string& config) { - return this->GeneratorTarget->GetFeature(feature, config)->c_str(); + return this->GeneratorTarget->GetFeature(feature, config); } void cmCommonTargetGenerator::AddModuleDefinitionFlag( @@ -56,7 +56,7 @@ void cmCommonTargetGenerator::AddModuleDefinitionFlag( } // TODO: Create a per-language flag variable. - cmProp defFileFlag = + cmValue defFileFlag = this->Makefile->GetDefinition("CMAKE_LINK_DEF_FILE_FLAG"); if (!defFileFlag) { return; @@ -240,11 +240,16 @@ std::string cmCommonTargetGenerator::GetManifests(const std::string& config) std::vector<std::string> manifests; manifests.reserve(manifest_srcs.size()); + + std::string lang = this->GeneratorTarget->GetLinkerLanguage(config); + std::string const& manifestFlag = + this->Makefile->GetDefinition("CMAKE_" + lang + "_LINKER_MANIFEST_FLAG"); for (cmSourceFile const* manifest_src : manifest_srcs) { - manifests.push_back(this->LocalCommonGenerator->ConvertToOutputFormat( - this->LocalCommonGenerator->MaybeRelativeToWorkDir( - manifest_src->GetFullPath()), - cmOutputConverter::SHELL)); + manifests.push_back(manifestFlag + + this->LocalCommonGenerator->ConvertToOutputFormat( + this->LocalCommonGenerator->MaybeRelativeToWorkDir( + manifest_src->GetFullPath()), + cmOutputConverter::SHELL)); } return cmJoin(manifests, " "); @@ -254,7 +259,7 @@ std::string cmCommonTargetGenerator::GetAIXExports(std::string const&) { std::string aixExports; if (this->GeneratorTarget->Target->IsAIX()) { - if (cmProp exportAll = + if (cmValue exportAll = this->GeneratorTarget->GetProperty("AIX_EXPORT_ALL_SYMBOLS")) { if (cmIsOff(*exportAll)) { aixExports = "-n"; @@ -270,7 +275,7 @@ void cmCommonTargetGenerator::AppendOSXVerFlag(std::string& flags, { // Lookup the flag to specify the version. std::string fvar = cmStrCat("CMAKE_", lang, "_OSX_", name, "_VERSION_FLAG"); - cmProp flag = this->Makefile->GetDefinition(fvar); + cmValue flag = this->Makefile->GetDefinition(fvar); // Skip if no such flag. if (!flag) { @@ -297,7 +302,7 @@ std::string cmCommonTargetGenerator::GetLinkerLauncher( const std::string& config) { std::string lang = this->GeneratorTarget->GetLinkerLanguage(config); - cmProp launcherProp = + cmValue launcherProp = this->GeneratorTarget->GetProperty(lang + "_LINKER_LAUNCHER"); if (cmNonempty(launcherProp)) { // Convert ;-delimited list to single string diff --git a/Source/cmCommonTargetGenerator.h b/Source/cmCommonTargetGenerator.h index a156a41af..baa36c9e2 100644 --- a/Source/cmCommonTargetGenerator.h +++ b/Source/cmCommonTargetGenerator.h @@ -8,6 +8,8 @@ #include <string> #include <vector> +#include "cmValue.h" + class cmGeneratorTarget; class cmGlobalCommonGenerator; class cmLinkLineComputer; @@ -28,8 +30,7 @@ public: protected: // Feature query methods. - const char* GetFeature(const std::string& feature, - const std::string& config); + cmValue GetFeature(const std::string& feature, const std::string& config); // Helper to add flag for windows .def file. void AddModuleDefinitionFlag(cmLinkLineComputer* linkLineComputer, @@ -40,6 +41,7 @@ protected: cmLocalCommonGenerator* LocalCommonGenerator; cmGlobalCommonGenerator* GlobalCommonGenerator; std::vector<std::string> ConfigNames; + bool UseLWYU = false; void AppendFortranFormatFlags(std::string& flags, cmSourceFile const& source); diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx index 0b27e34c2..370ddff5c 100644 --- a/Source/cmComputeLinkDepends.cxx +++ b/Source/cmComputeLinkDepends.cxx @@ -18,11 +18,11 @@ #include "cmListFileCache.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" -#include "cmProperty.h" #include "cmRange.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmTarget.h" +#include "cmValue.h" #include "cmake.h" /* @@ -322,7 +322,7 @@ int cmComputeLinkDepends::AddLinkEntry(cmLinkItem const& item) } else { // Look for an old-style <item>_LIB_DEPENDS variable. std::string var = cmStrCat(entry.Item.Value, "_LIB_DEPENDS"); - if (cmProp val = this->Makefile->GetDefinition(var)) { + if (cmValue val = this->Makefile->GetDefinition(var)) { // The item dependencies are known. Follow them. BFSEntry qe = { index, val->c_str() }; this->BFSQueue.push(qe); @@ -489,7 +489,7 @@ void cmComputeLinkDepends::AddVarLinkEntries(int depender_index, // lower. if (!haveLLT) { std::string var = cmStrCat(d, "_LINK_TYPE"); - if (cmProp val = this->Makefile->GetDefinition(var)) { + if (cmValue val = this->Makefile->GetDefinition(var)) { if (*val == "debug") { llt = DEBUG_LibraryType; } else if (*val == "optimized") { @@ -607,7 +607,7 @@ cmLinkItem cmComputeLinkDepends::ResolveLinkItem(int depender_index, from = depender; } } - return from->ResolveLinkItem(name, cmListFileBacktrace()); + return from->ResolveLinkItem(BT<std::string>(name)); } void cmComputeLinkDepends::InferDependencies() diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index d15da0c96..831a81fd2 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -20,12 +20,12 @@ #include "cmOrderDirectories.h" #include "cmOutputConverter.h" #include "cmPolicies.h" -#include "cmProperty.h" #include "cmState.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" +#include "cmValue.h" #include "cmake.h" //#define CM_COMPUTE_LINK_INFO_DEBUG @@ -278,38 +278,36 @@ cmComputeLinkInformation::cmComputeLinkInformation( // On platforms without import libraries there may be a special flag // to use when creating a plugin (module) that obtains symbols from // the program that will load it. - this->LoaderFlag = nullptr; if (!this->Target->IsDLLPlatform() && this->Target->GetType() == cmStateEnums::MODULE_LIBRARY) { std::string loader_flag_var = cmStrCat("CMAKE_SHARED_MODULE_LOADER_", this->LinkLanguage, "_FLAG"); - this->LoaderFlag = - cmToCStr(this->Makefile->GetDefinition(loader_flag_var)); + this->LoaderFlag = this->Makefile->GetDefinition(loader_flag_var); } // Get options needed to link libraries. - if (cmProp flag = this->Makefile->GetDefinition( + if (cmValue flag = this->Makefile->GetDefinition( "CMAKE_" + this->LinkLanguage + "_LINK_LIBRARY_FLAG")) { this->LibLinkFlag = *flag; } else { this->LibLinkFlag = this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_FLAG"); } - if (cmProp flag = this->Makefile->GetDefinition( + if (cmValue flag = this->Makefile->GetDefinition( "CMAKE_" + this->LinkLanguage + "_LINK_LIBRARY_FILE_FLAG")) { this->LibLinkFileFlag = *flag; } else { this->LibLinkFileFlag = this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_FILE_FLAG"); } - if (cmProp suffix = this->Makefile->GetDefinition( + if (cmValue suffix = this->Makefile->GetDefinition( "CMAKE_" + this->LinkLanguage + "_LINK_LIBRARY_SUFFIX")) { this->LibLinkSuffix = *suffix; } else { this->LibLinkSuffix = this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_SUFFIX"); } - if (cmProp flag = this->Makefile->GetDefinition( + if (cmValue flag = this->Makefile->GetDefinition( "CMAKE_" + this->LinkLanguage + "_LINK_OBJECT_FILE_FLAG")) { this->ObjLinkFileFlag = *flag; } else { @@ -528,7 +526,7 @@ bool cmComputeLinkInformation::Compute() // Restore the target link type so the correct system runtime // libraries are found. - cmProp lss = this->Target->GetProperty("LINK_SEARCH_END_STATIC"); + cmValue lss = this->Target->GetProperty("LINK_SEARCH_END_STATIC"); if (cmIsOn(lss)) { this->SetCurrentLinkType(LinkStatic); } else { @@ -607,7 +605,7 @@ void cmComputeLinkInformation::AddRuntimeLinkLibrary(std::string const& lang) if (runtimeLibrary.empty()) { return; } - if (cmProp runtimeLinkOptions = this->Makefile->GetDefinition( + if (cmValue runtimeLinkOptions = this->Makefile->GetDefinition( "CMAKE_" + lang + "_RUNTIME_LIBRARY_LINK_OPTIONS_" + runtimeLibrary)) { std::vector<std::string> libsVec = cmExpandedList(*runtimeLinkOptions); for (std::string const& i : libsVec) { @@ -623,7 +621,7 @@ void cmComputeLinkInformation::AddImplicitLinkInfo(std::string const& lang) // Add libraries for this language that are not implied by the // linker language. std::string libVar = cmStrCat("CMAKE_", lang, "_IMPLICIT_LINK_LIBRARIES"); - if (cmProp libs = this->Makefile->GetDefinition(libVar)) { + if (cmValue libs = this->Makefile->GetDefinition(libVar)) { std::vector<std::string> libsVec = cmExpandedList(*libs); for (std::string const& i : libsVec) { if (!cm::contains(this->ImplicitLinkLibs, i)) { @@ -635,7 +633,7 @@ void cmComputeLinkInformation::AddImplicitLinkInfo(std::string const& lang) // Add linker search paths for this language that are not // implied by the linker language. std::string dirVar = cmStrCat("CMAKE_", lang, "_IMPLICIT_LINK_DIRECTORIES"); - if (cmProp dirs = this->Makefile->GetDefinition(dirVar)) { + if (cmValue dirs = this->Makefile->GetDefinition(dirVar)) { std::vector<std::string> dirsVec = cmExpandedList(*dirs); this->OrderLinkerSearchPath->AddLanguageDirectories(dirsVec); } @@ -660,8 +658,7 @@ void cmComputeLinkInformation::AddItem(BT<std::string> const& item, // This link item is an executable that may provide symbols // used by this target. A special flag is needed on this // platform. Add it now. - std::string linkItem; - linkItem = this->LoaderFlag; + std::string linkItem = this->LoaderFlag; cmStateEnums::ArtifactType artifact = tgt->HasImportLibrary(config) ? cmStateEnums::ImportLibraryArtifact : cmStateEnums::RuntimeBinaryArtifact; @@ -839,8 +836,8 @@ void cmComputeLinkInformation::ComputeLinkTypeInfo() this->LinkTypeEnabled = false; // Lookup link type selection flags. - cmProp static_link_type_flag = nullptr; - cmProp shared_link_type_flag = nullptr; + cmValue static_link_type_flag = nullptr; + cmValue shared_link_type_flag = nullptr; const char* target_type_str = nullptr; switch (this->Target->GetType()) { case cmStateEnums::EXECUTABLE: @@ -878,7 +875,7 @@ void cmComputeLinkInformation::ComputeLinkTypeInfo() } // Lookup the starting link type from the target (linked statically?). - cmProp lss = this->Target->GetProperty("LINK_SEARCH_START_STATIC"); + cmValue lss = this->Target->GetProperty("LINK_SEARCH_START_STATIC"); this->StartLinkType = cmIsOn(lss) ? LinkStatic : LinkShared; this->CurrentLinkType = this->StartLinkType; } @@ -900,13 +897,14 @@ void cmComputeLinkInformation::ComputeItemParserInfo() LinkShared); this->AddLinkExtension(mf->GetSafeDefinition("CMAKE_LINK_LIBRARY_SUFFIX"), LinkUnknown); - if (cmProp linkSuffixes = mf->GetDefinition("CMAKE_EXTRA_LINK_EXTENSIONS")) { + if (cmValue linkSuffixes = + mf->GetDefinition("CMAKE_EXTRA_LINK_EXTENSIONS")) { std::vector<std::string> linkSuffixVec = cmExpandedList(*linkSuffixes); for (std::string const& i : linkSuffixVec) { this->AddLinkExtension(i, LinkUnknown); } } - if (cmProp sharedSuffixes = + if (cmValue sharedSuffixes = mf->GetDefinition("CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES")) { std::vector<std::string> sharedSuffixVec = cmExpandedList(*sharedSuffixes); for (std::string const& i : sharedSuffixVec) { @@ -1187,6 +1185,7 @@ bool cmComputeLinkInformation::CheckImplicitDirItem(std::string const& item) this->CMP0060WarnItems.insert(item); } } + CM_FALLTHROUGH; case cmPolicies::OLD: break; case cmPolicies::REQUIRED_ALWAYS: @@ -1456,8 +1455,10 @@ void cmComputeLinkInformation::HandleBadFullItem(std::string const& item, this->Target->GetBacktrace()); } } - case cmPolicies::OLD: + CM_FALLTHROUGH; + case cmPolicies::OLD: // NOLINT(bugprone-branch-clone) // OLD behavior does not warn. + break; case cmPolicies::NEW: // NEW behavior will not get here. break; @@ -1496,6 +1497,7 @@ bool cmComputeLinkInformation::FinishLinkerSearchDirectories() this->CMakeInstance->IssueMessage(MessageType::AUTHOR_WARNING, w.str(), this->Target->GetBacktrace()); } + CM_FALLTHROUGH; case cmPolicies::OLD: // OLD behavior is to add the paths containing libraries with // known full paths as link directories. @@ -1592,7 +1594,7 @@ void cmComputeLinkInformation::LoadImplicitLinkInfo() // Append library architecture to all implicit platform directories // and add them to the set - if (cmProp libraryArch = + if (cmValue libraryArch = this->Makefile->GetDefinition("CMAKE_LIBRARY_ARCHITECTURE")) { for (std::string const& i : implicitDirVec) { this->ImplicitLinkDirs.insert(i + "/" + *libraryArch); @@ -1785,13 +1787,13 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs, } if (use_build_rpath || use_link_rpath) { std::string rootPath; - if (cmProp sysrootLink = + if (cmValue sysrootLink = this->Makefile->GetDefinition("CMAKE_SYSROOT_LINK")) { rootPath = *sysrootLink; } else { rootPath = this->Makefile->GetSafeDefinition("CMAKE_SYSROOT"); } - cmProp stagePath = this->Makefile->GetDefinition("CMAKE_STAGING_PREFIX"); + cmValue stagePath = this->Makefile->GetDefinition("CMAKE_STAGING_PREFIX"); std::string const& installPrefix = this->Makefile->GetSafeDefinition("CMAKE_INSTALL_PREFIX"); cmSystemTools::ConvertToUnixSlashes(rootPath); @@ -1859,7 +1861,7 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs, "CMAKE_" + li + "_USE_IMPLICIT_LINK_DIRECTORIES_IN_RUNTIME_PATH"; if (this->Makefile->IsOn(useVar)) { std::string dirVar = "CMAKE_" + li + "_IMPLICIT_LINK_DIRECTORIES"; - if (cmProp dirs = this->Makefile->GetDefinition(dirVar)) { + if (cmValue dirs = this->Makefile->GetDefinition(dirVar)) { cmCLI_ExpandListUnique(*dirs, runtimeDirs, emitted); } } diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h index 7fe30b3bb..90a699ebb 100644 --- a/Source/cmComputeLinkInformation.h +++ b/Source/cmComputeLinkInformation.h @@ -14,6 +14,7 @@ #include "cmsys/RegularExpression.hxx" #include "cmListFileCache.h" +#include "cmValue.h" class cmGeneratorTarget; class cmGlobalGenerator; @@ -137,7 +138,7 @@ private: SharedDepModeLink // List file on link line }; - const char* LoaderFlag; + cmValue LoaderFlag; std::string LibLinkFlag; std::string LibLinkFileFlag; std::string ObjLinkFileFlag; diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx index 76712f4eb..ef89c8b5c 100644 --- a/Source/cmComputeTargetDepends.cxx +++ b/Source/cmComputeTargetDepends.cxx @@ -17,16 +17,15 @@ #include "cmMakefile.h" #include "cmMessageType.h" #include "cmPolicies.h" -#include "cmProperty.h" #include "cmRange.h" #include "cmSourceFile.h" #include "cmSourceFileLocationKind.h" #include "cmState.h" #include "cmStateTypes.h" -#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" #include "cmTargetDepend.h" +#include "cmValue.h" #include "cmake.h" /* @@ -323,7 +322,7 @@ void cmComputeTargetDepends::AddObjectDepends(int depender_index, } cmGeneratorTarget const* depender = this->Targets[depender_index]; cmLinkItem const& objItem = - depender->ResolveLinkItem(objLib, cmListFileBacktrace()); + depender->ResolveLinkItem(BT<std::string>(objLib)); if (emitted.insert(objItem).second) { if (depender->GetType() != cmStateEnums::EXECUTABLE && depender->GetType() != cmStateEnums::STATIC_LIBRARY && @@ -360,6 +359,7 @@ void cmComputeTargetDepends::AddTargetDepend(int depender_index, case cmPolicies::WARN: e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0046) << "\n"; issueMessage = true; + CM_FALLTHROUGH; case cmPolicies::OLD: break; case cmPolicies::NEW: @@ -367,6 +367,7 @@ void cmComputeTargetDepends::AddTargetDepend(int depender_index, case cmPolicies::REQUIRED_ALWAYS: issueMessage = true; messageType = MessageType::FATAL_ERROR; + break; } if (issueMessage) { cmake* cm = this->GlobalGenerator->GetCMakeInstance(); @@ -469,7 +470,7 @@ void cmComputeTargetDepends::ComputeIntermediateGraph() gt->GetType() != cmStateEnums::OBJECT_LIBRARY) { intermediateEdges = initialEdges; } else { - if (cmProp optimizeDependencies = + if (cmValue optimizeDependencies = gt->GetProperty("OPTIMIZE_DEPENDENCIES")) { if (cmIsOn(optimizeDependencies)) { this->OptimizeLinkDependencies(gt, intermediateEdges, initialEdges); diff --git a/Source/cmConditionEvaluator.cxx b/Source/cmConditionEvaluator.cxx index f99592cc0..8e479c545 100644 --- a/Source/cmConditionEvaluator.cxx +++ b/Source/cmConditionEvaluator.cxx @@ -2,58 +2,207 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmConditionEvaluator.h" +#include <array> #include <cstdio> #include <cstdlib> #include <functional> +#include <iterator> +#include <list> #include <sstream> #include <utility> +#include <cm/string_view> #include <cmext/algorithm> #include "cmsys/RegularExpression.hxx" +#include "cmExpandedCommandArgument.h" #include "cmMakefile.h" #include "cmMessageType.h" -#include "cmProperty.h" #include "cmState.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" #include "cmake.h" -class cmTest; - -static std::string const keyAND = "AND"; -static std::string const keyCOMMAND = "COMMAND"; -static std::string const keyDEFINED = "DEFINED"; -static std::string const keyEQUAL = "EQUAL"; -static std::string const keyEXISTS = "EXISTS"; -static std::string const keyGREATER = "GREATER"; -static std::string const keyGREATER_EQUAL = "GREATER_EQUAL"; -static std::string const keyIN_LIST = "IN_LIST"; -static std::string const keyIS_ABSOLUTE = "IS_ABSOLUTE"; -static std::string const keyIS_DIRECTORY = "IS_DIRECTORY"; -static std::string const keyIS_NEWER_THAN = "IS_NEWER_THAN"; -static std::string const keyIS_SYMLINK = "IS_SYMLINK"; -static std::string const keyLESS = "LESS"; -static std::string const keyLESS_EQUAL = "LESS_EQUAL"; -static std::string const keyMATCHES = "MATCHES"; -static std::string const keyNOT = "NOT"; -static std::string const keyOR = "OR"; -static std::string const keyParenL = "("; -static std::string const keyParenR = ")"; -static std::string const keyPOLICY = "POLICY"; -static std::string const keySTREQUAL = "STREQUAL"; -static std::string const keySTRGREATER = "STRGREATER"; -static std::string const keySTRGREATER_EQUAL = "STRGREATER_EQUAL"; -static std::string const keySTRLESS = "STRLESS"; -static std::string const keySTRLESS_EQUAL = "STRLESS_EQUAL"; -static std::string const keyTARGET = "TARGET"; -static std::string const keyTEST = "TEST"; -static std::string const keyVERSION_EQUAL = "VERSION_EQUAL"; -static std::string const keyVERSION_GREATER = "VERSION_GREATER"; -static std::string const keyVERSION_GREATER_EQUAL = "VERSION_GREATER_EQUAL"; -static std::string const keyVERSION_LESS = "VERSION_LESS"; -static std::string const keyVERSION_LESS_EQUAL = "VERSION_LESS_EQUAL"; +namespace { +auto const keyAND = "AND"_s; +auto const keyCOMMAND = "COMMAND"_s; +auto const keyDEFINED = "DEFINED"_s; +auto const keyEQUAL = "EQUAL"_s; +auto const keyEXISTS = "EXISTS"_s; +auto const keyGREATER = "GREATER"_s; +auto const keyGREATER_EQUAL = "GREATER_EQUAL"_s; +auto const keyIN_LIST = "IN_LIST"_s; +auto const keyIS_ABSOLUTE = "IS_ABSOLUTE"_s; +auto const keyIS_DIRECTORY = "IS_DIRECTORY"_s; +auto const keyIS_NEWER_THAN = "IS_NEWER_THAN"_s; +auto const keyIS_SYMLINK = "IS_SYMLINK"_s; +auto const keyLESS = "LESS"_s; +auto const keyLESS_EQUAL = "LESS_EQUAL"_s; +auto const keyMATCHES = "MATCHES"_s; +auto const keyNOT = "NOT"_s; +auto const keyOR = "OR"_s; +auto const keyParenL = "("_s; +auto const keyParenR = ")"_s; +auto const keyPOLICY = "POLICY"_s; +auto const keySTREQUAL = "STREQUAL"_s; +auto const keySTRGREATER = "STRGREATER"_s; +auto const keySTRGREATER_EQUAL = "STRGREATER_EQUAL"_s; +auto const keySTRLESS = "STRLESS"_s; +auto const keySTRLESS_EQUAL = "STRLESS_EQUAL"_s; +auto const keyTARGET = "TARGET"_s; +auto const keyTEST = "TEST"_s; +auto const keyVERSION_EQUAL = "VERSION_EQUAL"_s; +auto const keyVERSION_GREATER = "VERSION_GREATER"_s; +auto const keyVERSION_GREATER_EQUAL = "VERSION_GREATER_EQUAL"_s; +auto const keyVERSION_LESS = "VERSION_LESS"_s; +auto const keyVERSION_LESS_EQUAL = "VERSION_LESS_EQUAL"_s; + +cmSystemTools::CompareOp const MATCH2CMPOP[5] = { + cmSystemTools::OP_LESS, cmSystemTools::OP_LESS_EQUAL, + cmSystemTools::OP_GREATER, cmSystemTools::OP_GREATER_EQUAL, + cmSystemTools::OP_EQUAL +}; + +// Run-Time to Compile-Time template selector +template <template <typename> class Comp, template <typename> class... Ops> +struct cmRt2CtSelector +{ + template <typename T> + static bool eval(int r, T lhs, T rhs) + { + switch (r) { + case 0: + return false; + case 1: + return Comp<T>()(lhs, rhs); + default: + return cmRt2CtSelector<Ops...>::eval(r - 1, lhs, rhs); + } + } +}; + +template <template <typename> class Comp> +struct cmRt2CtSelector<Comp> +{ + template <typename T> + static bool eval(int r, T lhs, T rhs) + { + return r == 1 && Comp<T>()(lhs, rhs); + } +}; + +std::string bool2string(bool const value) +{ + return std::string(std::size_t(1), static_cast<char>('0' + int(value))); +} + +bool looksLikeSpecialVariable(const std::string& var, + cm::static_string_view prefix, + const std::size_t varNameLen) +{ + // NOTE Expecting a variable name at least 1 char length: + // <prefix> + `{` + <varname> + `}` + return ((prefix.size() + 3) <= varNameLen) && + cmHasPrefix(var, cmStrCat(prefix, '{')) && var[varNameLen - 1] == '}'; +} +} // anonymous namespace + +#if defined(__SUNPRO_CC) +# define CM_INHERIT_CTOR(Class, Base, Tpl) \ + template <typename... Args> \ + Class(Args&&... args) \ + : Base Tpl(std::forward<Args>(args)...) \ + { \ + } +#else +# define CM_INHERIT_CTOR(Class, Base, Tpl) using Base Tpl ::Base +#endif + +// BEGIN cmConditionEvaluator::cmArgumentList +class cmConditionEvaluator::cmArgumentList + : public std::list<cmExpandedCommandArgument> +{ + using base_t = std::list<cmExpandedCommandArgument>; + +public: + CM_INHERIT_CTOR(cmArgumentList, list, <cmExpandedCommandArgument>); + + class CurrentAndNextIter + { + friend class cmConditionEvaluator::cmArgumentList; + + public: + base_t::iterator current; + base_t::iterator next; + + CurrentAndNextIter advance(base_t& args) + { + this->current = std::next(this->current); + this->next = + std::next(this->current, difference_type(this->current != args.end())); + return *this; + } + + private: + CurrentAndNextIter(base_t& args) + : current(args.begin()) + , next(std::next(this->current, + difference_type(this->current != args.end()))) + { + } + }; + + class CurrentAndTwoMoreIter + { + friend class cmConditionEvaluator::cmArgumentList; + + public: + base_t::iterator current; + base_t::iterator next; + base_t::iterator nextnext; + + CurrentAndTwoMoreIter advance(base_t& args) + { + this->current = std::next(this->current); + this->next = + std::next(this->current, difference_type(this->current != args.end())); + this->nextnext = + std::next(this->next, difference_type(this->next != args.end())); + return *this; + } + + private: + CurrentAndTwoMoreIter(base_t& args) + : current(args.begin()) + , next(std::next(this->current, + difference_type(this->current != args.end()))) + , nextnext( + std::next(this->next, difference_type(this->next != args.end()))) + { + } + }; + + CurrentAndNextIter make2ArgsIterator() { return *this; } + CurrentAndTwoMoreIter make3ArgsIterator() { return *this; } + + template <typename Iter> + void ReduceOneArg(const bool value, Iter args) + { + *args.current = cmExpandedCommandArgument(bool2string(value), true); + this->erase(args.next); + } + + void ReduceTwoArgs(const bool value, CurrentAndTwoMoreIter args) + { + *args.current = cmExpandedCommandArgument(bool2string(value), true); + this->erase(args.nextnext); + this->erase(args.next); + } +}; + +// END cmConditionEvaluator::cmArgumentList cmConditionEvaluator::cmConditionEvaluator(cmMakefile& makefile, cmListFileBacktrace bt) @@ -99,25 +248,29 @@ bool cmConditionEvaluator::IsTrue( // now loop through the arguments and see if we can reduce any of them // we do this multiple times. Once for each level of precedence // parens - if (!this->HandleLevel0(newArgs, errorString, status)) { - return false; - } - // predicates - if (!this->HandleLevel1(newArgs, errorString, status)) { - return false; - } - // binary ops - if (!this->HandleLevel2(newArgs, errorString, status)) { - return false; - } + using handlerFn_t = bool (cmConditionEvaluator::*)( + cmArgumentList&, std::string&, MessageType&); + const std::array<handlerFn_t, 5> handlers = { { + &cmConditionEvaluator::HandleLevel0, // parenthesis + &cmConditionEvaluator::HandleLevel1, // predicates + &cmConditionEvaluator::HandleLevel2, // binary ops + &cmConditionEvaluator::HandleLevel3, // NOT + &cmConditionEvaluator::HandleLevel4 // AND OR + } }; + for (auto fn : handlers) { + // Call the reducer 'till there is anything to reduce... + // (i.e., if after an iteration the size becomes smaller) + auto levelResult = true; + for (auto beginSize = newArgs.size(); + (levelResult = (this->*fn)(newArgs, errorString, status)) && + newArgs.size() < beginSize; + beginSize = newArgs.size()) { + } - // NOT - if (!this->HandleLevel3(newArgs, errorString, status)) { - return false; - } - // AND OR - if (!this->HandleLevel4(newArgs, errorString, status)) { - return false; + if (!levelResult) { + // NOTE `errorString` supposed to be set already + return false; + } } // now at the end there should only be one argument left @@ -132,7 +285,7 @@ bool cmConditionEvaluator::IsTrue( } //========================================================================= -cmProp cmConditionEvaluator::GetDefinitionIfUnquoted( +cmValue cmConditionEvaluator::GetDefinitionIfUnquoted( cmExpandedCommandArgument const& argument) const { if ((this->Policy54Status != cmPolicies::WARN && @@ -141,17 +294,19 @@ cmProp cmConditionEvaluator::GetDefinitionIfUnquoted( return nullptr; } - cmProp def = this->Makefile.GetDefinition(argument.GetValue()); + cmValue def = this->Makefile.GetDefinition(argument.GetValue()); if (def && argument.WasQuoted() && this->Policy54Status == cmPolicies::WARN) { if (!this->Makefile.HasCMP0054AlreadyBeenReported(this->Backtrace.Top())) { std::ostringstream e; - e << (cmPolicies::GetPolicyWarning(cmPolicies::CMP0054)) << "\n"; - e << "Quoted variables like \"" << argument.GetValue() - << "\" will no longer be dereferenced " - "when the policy is set to NEW. " + // clang-format off + e << (cmPolicies::GetPolicyWarning(cmPolicies::CMP0054)) + << "\n" + "Quoted variables like \"" << argument.GetValue() << "\" " + "will no longer be dereferenced when the policy is set to NEW. " "Since the policy is not set the OLD behavior will be used."; + // clang-format on this->Makefile.GetCMakeInstance()->IssueMessage( MessageType::AUTHOR_WARNING, e.str(), this->Backtrace); @@ -162,21 +317,22 @@ cmProp cmConditionEvaluator::GetDefinitionIfUnquoted( } //========================================================================= -cmProp cmConditionEvaluator::GetVariableOrString( +cmValue cmConditionEvaluator::GetVariableOrString( const cmExpandedCommandArgument& argument) const { - cmProp def = this->GetDefinitionIfUnquoted(argument); + cmValue def = this->GetDefinitionIfUnquoted(argument); if (!def) { - def = &argument.GetValue(); + def = cmValue(argument.GetValue()); } return def; } //========================================================================= -bool cmConditionEvaluator::IsKeyword(std::string const& keyword, - cmExpandedCommandArgument& argument) const +bool cmConditionEvaluator::IsKeyword( + cm::static_string_view keyword, + const cmExpandedCommandArgument& argument) const { if ((this->Policy54Status != cmPolicies::WARN && this->Policy54Status != cmPolicies::OLD) && @@ -184,17 +340,20 @@ bool cmConditionEvaluator::IsKeyword(std::string const& keyword, return false; } - bool isKeyword = argument.GetValue() == keyword; + const auto isKeyword = argument.GetValue() == keyword; if (isKeyword && argument.WasQuoted() && this->Policy54Status == cmPolicies::WARN) { if (!this->Makefile.HasCMP0054AlreadyBeenReported(this->Backtrace.Top())) { std::ostringstream e; - e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0054) << "\n"; - e << "Quoted keywords like \"" << argument.GetValue() - << "\" will no longer be interpreted as keywords " + // clang-format off + e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0054) + << "\n" + "Quoted keywords like \"" << argument.GetValue() << "\" " + "will no longer be interpreted as keywords " "when the policy is set to NEW. " "Since the policy is not set the OLD behavior will be used."; + // clang-format on this->Makefile.GetCMakeInstance()->IssueMessage( MessageType::AUTHOR_WARNING, e.str(), this->Backtrace); @@ -208,15 +367,7 @@ bool cmConditionEvaluator::IsKeyword(std::string const& keyword, bool cmConditionEvaluator::GetBooleanValue( cmExpandedCommandArgument& arg) const { - // Check basic constants. - if (arg == "0") { - return false; - } - if (arg == "1") { - return true; - } - - // Check named constants. + // Check basic and named constants. if (cmIsOn(arg.GetValue())) { return true; } @@ -227,7 +378,7 @@ bool cmConditionEvaluator::GetBooleanValue( // Check for numbers. if (!arg.empty()) { char* end; - double d = strtod(arg.GetValue().c_str(), &end); + const double d = std::strtod(arg.GetValue().c_str(), &end); if (*end == '\0') { // The whole string is a number. Use C conversion to bool. return static_cast<bool>(d); @@ -235,14 +386,14 @@ bool cmConditionEvaluator::GetBooleanValue( } // Check definition. - cmProp def = this->GetDefinitionIfUnquoted(arg); + cmValue def = this->GetDefinitionIfUnquoted(arg); return !cmIsOff(def); } //========================================================================= // Boolean value behavior from CMake 2.6.4 and below. bool cmConditionEvaluator::GetBooleanValueOld( - cmExpandedCommandArgument const& arg, bool one) const + cmExpandedCommandArgument const& arg, bool const one) const { if (one) { // Old IsTrue behavior for single argument. @@ -252,13 +403,13 @@ bool cmConditionEvaluator::GetBooleanValueOld( if (arg == "1") { return true; } - cmProp def = this->GetDefinitionIfUnquoted(arg); + cmValue def = this->GetDefinitionIfUnquoted(arg); return !cmIsOff(def); } // Old GetVariableOrNumber behavior. - cmProp def = this->GetDefinitionIfUnquoted(arg); - if (!def && atoi(arg.GetValue().c_str())) { - def = &arg.GetValue(); + cmValue def = this->GetDefinitionIfUnquoted(arg); + if (!def && std::atoi(arg.GetValue().c_str())) { + def = cmValue(arg.GetValue()); } return !cmIsOff(def); } @@ -267,7 +418,7 @@ bool cmConditionEvaluator::GetBooleanValueOld( // returns the resulting boolean value bool cmConditionEvaluator::GetBooleanValueWithAutoDereference( cmExpandedCommandArgument& newArg, std::string& errorString, - MessageType& status, bool oneArg) const + MessageType& status, bool const oneArg) const { // Use the policy if it is set. if (this->Policy12Status == cmPolicies::NEW) { @@ -278,8 +429,8 @@ bool cmConditionEvaluator::GetBooleanValueWithAutoDereference( } // Check policy only if old and new results differ. - bool newResult = this->GetBooleanValue(newArg); - bool oldResult = this->GetBooleanValueOld(newArg, oneArg); + const auto newResult = this->GetBooleanValue(newArg); + const auto oldResult = this->GetBooleanValueOld(newArg, oneArg); if (newResult != oldResult) { switch (this->Policy12Status) { case cmPolicies::WARN: @@ -296,6 +447,7 @@ bool cmConditionEvaluator::GetBooleanValueWithAutoDereference( "\" appears in a conditional statement. " + cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0012); status = MessageType::FATAL_ERROR; + break; } case cmPolicies::NEW: break; @@ -304,56 +456,31 @@ bool cmConditionEvaluator::GetBooleanValueWithAutoDereference( return newResult; } -//========================================================================= -void cmConditionEvaluator::IncrementArguments( - cmArgumentList& newArgs, cmArgumentList::iterator& argP1, - cmArgumentList::iterator& argP2) const +template <int N> +inline int cmConditionEvaluator::matchKeysImpl( + const cmExpandedCommandArgument&) { - if (argP1 != newArgs.end()) { - argP1++; - argP2 = argP1; - if (argP1 != newArgs.end()) { - argP2++; - } - } + // Zero means "not found" + return 0; } -//========================================================================= -// helper function to reduce code duplication -void cmConditionEvaluator::HandlePredicate( - bool value, int& reducible, cmArgumentList::iterator& arg, - cmArgumentList& newArgs, cmArgumentList::iterator& argP1, - cmArgumentList::iterator& argP2) const +template <int N, typename T, typename... Keys> +inline int cmConditionEvaluator::matchKeysImpl( + const cmExpandedCommandArgument& arg, T current, Keys... key) { - if (value) { - *arg = cmExpandedCommandArgument("1", true); - } else { - *arg = cmExpandedCommandArgument("0", true); + if (this->IsKeyword(current, arg)) { + // Stop searching as soon as smth has found + return N; } - newArgs.erase(argP1); - argP1 = arg; - this->IncrementArguments(newArgs, argP1, argP2); - reducible = 1; + return matchKeysImpl<N + 1>(arg, key...); } -//========================================================================= -// helper function to reduce code duplication -void cmConditionEvaluator::HandleBinaryOp(bool value, int& reducible, - cmArgumentList::iterator& arg, - cmArgumentList& newArgs, - cmArgumentList::iterator& argP1, - cmArgumentList::iterator& argP2) +template <typename... Keys> +inline int cmConditionEvaluator::matchKeys( + const cmExpandedCommandArgument& arg, Keys... key) { - if (value) { - *arg = cmExpandedCommandArgument("1", true); - } else { - *arg = cmExpandedCommandArgument("0", true); - } - newArgs.erase(argP2); - newArgs.erase(argP1); - argP1 = arg; - this->IncrementArguments(newArgs, argP1, argP2); - reducible = 1; + // Get index of the matched key (1-based) + return matchKeysImpl<1>(arg, key...); } //========================================================================= @@ -362,55 +489,35 @@ bool cmConditionEvaluator::HandleLevel0(cmArgumentList& newArgs, std::string& errorString, MessageType& status) { - int reducible; - do { - reducible = 0; - auto arg = newArgs.begin(); - while (arg != newArgs.end()) { - if (this->IsKeyword(keyParenL, *arg)) { - // search for the closing paren for this opening one - cmArgumentList::iterator argClose; - argClose = arg; - argClose++; - unsigned int depth = 1; - while (argClose != newArgs.end() && depth) { - if (this->IsKeyword(keyParenL, *argClose)) { - depth++; - } - if (this->IsKeyword(keyParenR, *argClose)) { - depth--; - } - argClose++; - } - if (depth) { - errorString = "mismatched parenthesis in condition"; - status = MessageType::FATAL_ERROR; - return false; - } - // store the reduced args in this vector - std::vector<cmExpandedCommandArgument> newArgs2; - - // copy to the list structure - auto argP1 = arg; - argP1++; - cm::append(newArgs2, argP1, argClose); - newArgs2.pop_back(); - // now recursively invoke IsTrue to handle the values inside the - // parenthetical expression - bool value = this->IsTrue(newArgs2, errorString, status); - if (value) { - *arg = cmExpandedCommandArgument("1", true); - } else { - *arg = cmExpandedCommandArgument("0", true); - } - argP1 = arg; - argP1++; - // remove the now evaluated parenthetical expression - newArgs.erase(argP1, argClose); + for (auto arg = newArgs.begin(); arg != newArgs.end(); ++arg) { + if (this->IsKeyword(keyParenL, *arg)) { + // search for the closing paren for this opening one + auto depth = 1; + auto argClose = std::next(arg); + for (; argClose != newArgs.end() && depth; ++argClose) { + depth += int(this->IsKeyword(keyParenL, *argClose)) - + int(this->IsKeyword(keyParenR, *argClose)); } - ++arg; + if (depth) { + errorString = "mismatched parenthesis in condition"; + status = MessageType::FATAL_ERROR; + return false; + } + + // store the reduced args in this vector + auto argOpen = std::next(arg); + const std::vector<cmExpandedCommandArgument> subExpr( + argOpen, std::prev(argClose)); + + // now recursively invoke IsTrue to handle the values inside the + // parenthetical expression + const auto value = this->IsTrue(subExpr, errorString, status); + *arg = cmExpandedCommandArgument(bool2string(value), true); + argOpen = std::next(arg); + // remove the now evaluated parenthetical expression + newArgs.erase(argOpen, argClose); } - } while (reducible); + } return true; } @@ -419,96 +526,104 @@ bool cmConditionEvaluator::HandleLevel0(cmArgumentList& newArgs, bool cmConditionEvaluator::HandleLevel1(cmArgumentList& newArgs, std::string&, MessageType&) { - int reducible; - do { - reducible = 0; - auto arg = newArgs.begin(); - cmArgumentList::iterator argP1; - cmArgumentList::iterator argP2; - while (arg != newArgs.end()) { - argP1 = arg; - this->IncrementArguments(newArgs, argP1, argP2); - // does a file exist - if (this->IsKeyword(keyEXISTS, *arg) && argP1 != newArgs.end()) { - this->HandlePredicate(cmSystemTools::FileExists(argP1->GetValue()), - reducible, arg, newArgs, argP1, argP2); - } - // does a directory with this name exist - if (this->IsKeyword(keyIS_DIRECTORY, *arg) && argP1 != newArgs.end()) { - this->HandlePredicate( - cmSystemTools::FileIsDirectory(argP1->GetValue()), reducible, arg, - newArgs, argP1, argP2); - } - // does a symlink with this name exist - if (this->IsKeyword(keyIS_SYMLINK, *arg) && argP1 != newArgs.end()) { - this->HandlePredicate(cmSystemTools::FileIsSymlink(argP1->GetValue()), - reducible, arg, newArgs, argP1, argP2); - } - // is the given path an absolute path ? - if (this->IsKeyword(keyIS_ABSOLUTE, *arg) && argP1 != newArgs.end()) { - this->HandlePredicate(cmSystemTools::FileIsFullPath(argP1->GetValue()), - reducible, arg, newArgs, argP1, argP2); - } - // does a command exist - if (this->IsKeyword(keyCOMMAND, *arg) && argP1 != newArgs.end()) { - cmState::Command command = - this->Makefile.GetState()->GetCommand(argP1->GetValue()); - this->HandlePredicate(command != nullptr, reducible, arg, newArgs, - argP1, argP2); - } - // does a policy exist - if (this->IsKeyword(keyPOLICY, *arg) && argP1 != newArgs.end()) { - cmPolicies::PolicyID pid; - this->HandlePredicate( - cmPolicies::GetPolicyID(argP1->GetValue().c_str(), pid), reducible, - arg, newArgs, argP1, argP2); - } - // does a target exist - if (this->IsKeyword(keyTARGET, *arg) && argP1 != newArgs.end()) { - this->HandlePredicate( - this->Makefile.FindTargetToUse(argP1->GetValue()) != nullptr, - reducible, arg, newArgs, argP1, argP2); - } - // does a test exist - if (this->Policy64Status != cmPolicies::OLD && - this->Policy64Status != cmPolicies::WARN) { - if (this->IsKeyword(keyTEST, *arg) && argP1 != newArgs.end()) { - const cmTest* haveTest = this->Makefile.GetTest(argP1->GetValue()); - this->HandlePredicate(haveTest != nullptr, reducible, arg, newArgs, - argP1, argP2); - } - } else if (this->Policy64Status == cmPolicies::WARN && - this->IsKeyword(keyTEST, *arg)) { + const auto policy64IsOld = this->Policy64Status == cmPolicies::OLD || + this->Policy64Status == cmPolicies::WARN; + + for (auto args = newArgs.make2ArgsIterator(); args.current != newArgs.end(); + args.advance(newArgs)) { + + auto policyCheck = [&, this](const cmPolicies::PolicyID id, + const cmPolicies::PolicyStatus status, + const cm::static_string_view kw) { + if (status == cmPolicies::WARN && this->IsKeyword(kw, *args.current)) { std::ostringstream e; - e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0064) << "\n"; - e << "TEST will be interpreted as an operator " + e << cmPolicies::GetPolicyWarning(id) << "\n" + << kw + << " will be interpreted as an operator " "when the policy is set to NEW. " "Since the policy is not set the OLD behavior will be used."; this->Makefile.IssueMessage(MessageType::AUTHOR_WARNING, e.str()); } - // is a variable defined - if (this->IsKeyword(keyDEFINED, *arg) && argP1 != newArgs.end()) { - size_t argP1len = argP1->GetValue().size(); - bool bdef = false; - if (argP1len > 4 && cmHasLiteralPrefix(argP1->GetValue(), "ENV{") && - argP1->GetValue().operator[](argP1len - 1) == '}') { - std::string env = argP1->GetValue().substr(4, argP1len - 5); - bdef = cmSystemTools::HasEnv(env); - } else if (argP1len > 6 && - cmHasLiteralPrefix(argP1->GetValue(), "CACHE{") && - argP1->GetValue().operator[](argP1len - 1) == '}') { - std::string cache = argP1->GetValue().substr(6, argP1len - 7); - bdef = - this->Makefile.GetState()->GetCacheEntryValue(cache) != nullptr; - } else { - bdef = this->Makefile.IsDefinitionSet(argP1->GetValue()); - } - this->HandlePredicate(bdef, reducible, arg, newArgs, argP1, argP2); + }; + + // NOTE Checking policies for warnings are not require an access to the + // next arg. Check them first! + policyCheck(cmPolicies::CMP0064, this->Policy64Status, keyTEST); + + // NOTE Fail fast: All the predicates below require the next arg to be + // valid + if (args.next == newArgs.end()) { + continue; + } + + // does a file exist + if (this->IsKeyword(keyEXISTS, *args.current)) { + newArgs.ReduceOneArg(cmSystemTools::FileExists(args.next->GetValue()), + args); + } + // does a directory with this name exist + else if (this->IsKeyword(keyIS_DIRECTORY, *args.current)) { + newArgs.ReduceOneArg( + cmSystemTools::FileIsDirectory(args.next->GetValue()), args); + } + // does a symlink with this name exist + else if (this->IsKeyword(keyIS_SYMLINK, *args.current)) { + newArgs.ReduceOneArg(cmSystemTools::FileIsSymlink(args.next->GetValue()), + args); + } + // is the given path an absolute path ? + else if (this->IsKeyword(keyIS_ABSOLUTE, *args.current)) { + newArgs.ReduceOneArg( + cmSystemTools::FileIsFullPath(args.next->GetValue()), args); + } + // does a command exist + else if (this->IsKeyword(keyCOMMAND, *args.current)) { + newArgs.ReduceOneArg( + bool(this->Makefile.GetState()->GetCommand(args.next->GetValue())), + args); + } + // does a policy exist + else if (this->IsKeyword(keyPOLICY, *args.current)) { + cmPolicies::PolicyID pid; + newArgs.ReduceOneArg( + cmPolicies::GetPolicyID(args.next->GetValue().c_str(), pid), args); + } + // does a target exist + else if (this->IsKeyword(keyTARGET, *args.current)) { + newArgs.ReduceOneArg( + bool(this->Makefile.FindTargetToUse(args.next->GetValue())), args); + } + // is a variable defined + else if (this->IsKeyword(keyDEFINED, *args.current)) { + const auto& var = args.next->GetValue(); + const auto varNameLen = var.size(); + + auto result = false; + if (looksLikeSpecialVariable(var, "ENV"_s, varNameLen)) { + const auto env = args.next->GetValue().substr(4, varNameLen - 5); + result = cmSystemTools::HasEnv(env); + } + + else if (looksLikeSpecialVariable(var, "CACHE"_s, varNameLen)) { + const auto cache = args.next->GetValue().substr(6, varNameLen - 7); + result = bool(this->Makefile.GetState()->GetCacheEntryValue(cache)); } - ++arg; + + else { + result = this->Makefile.IsDefinitionSet(args.next->GetValue()); + } + newArgs.ReduceOneArg(result, args); + } + // does a test exist + else if (this->IsKeyword(keyTEST, *args.current)) { + if (policy64IsOld) { + continue; + } + newArgs.ReduceOneArg(bool(this->Makefile.GetTest(args.next->GetValue())), + args); } - } while (reducible); + } return true; } @@ -518,178 +633,142 @@ bool cmConditionEvaluator::HandleLevel2(cmArgumentList& newArgs, std::string& errorString, MessageType& status) { - int reducible; - std::string def_buf; - cmProp def; - cmProp def2; - do { - reducible = 0; - auto arg = newArgs.begin(); - cmArgumentList::iterator argP1; - cmArgumentList::iterator argP2; - while (arg != newArgs.end()) { - argP1 = arg; - this->IncrementArguments(newArgs, argP1, argP2); - if (argP1 != newArgs.end() && argP2 != newArgs.end() && - this->IsKeyword(keyMATCHES, *argP1)) { - def = this->GetDefinitionIfUnquoted(*arg); - if (!def) { - def = &arg->GetValue(); - } else if (cmHasLiteralPrefix(arg->GetValue(), "CMAKE_MATCH_")) { - // The string to match is owned by our match result variables. - // Move it to our own buffer before clearing them. - def_buf = *def; - def = &def_buf; - } - const std::string& rex = argP2->GetValue(); - this->Makefile.ClearMatches(); - cmsys::RegularExpression regEntry; - if (!regEntry.compile(rex)) { - std::ostringstream error; - error << "Regular expression \"" << rex << "\" cannot compile"; - errorString = error.str(); - status = MessageType::FATAL_ERROR; - return false; - } - if (regEntry.find(*def)) { - this->Makefile.StoreMatches(regEntry); - *arg = cmExpandedCommandArgument("1", true); - } else { - *arg = cmExpandedCommandArgument("0", true); - } - newArgs.erase(argP2); - newArgs.erase(argP1); - argP1 = arg; - this->IncrementArguments(newArgs, argP1, argP2); - reducible = 1; - } + for (auto args = newArgs.make3ArgsIterator(); args.current != newArgs.end(); + args.advance(newArgs)) { - if (argP1 != newArgs.end() && this->IsKeyword(keyMATCHES, *arg)) { - *arg = cmExpandedCommandArgument("0", true); - newArgs.erase(argP1); - argP1 = arg; - this->IncrementArguments(newArgs, argP1, argP2); - reducible = 1; - } + int matchNo; - if (argP1 != newArgs.end() && argP2 != newArgs.end() && - (this->IsKeyword(keyLESS, *argP1) || - this->IsKeyword(keyLESS_EQUAL, *argP1) || - this->IsKeyword(keyGREATER, *argP1) || - this->IsKeyword(keyGREATER_EQUAL, *argP1) || - this->IsKeyword(keyEQUAL, *argP1))) { - def = this->GetVariableOrString(*arg); - def2 = this->GetVariableOrString(*argP2); - double lhs; - double rhs; - bool result; - if (sscanf(def->c_str(), "%lg", &lhs) != 1 || - sscanf(def2->c_str(), "%lg", &rhs) != 1) { - result = false; - } else if (*(argP1) == keyLESS) { - result = (lhs < rhs); - } else if (*(argP1) == keyLESS_EQUAL) { - result = (lhs <= rhs); - } else if (*(argP1) == keyGREATER) { - result = (lhs > rhs); - } else if (*(argP1) == keyGREATER_EQUAL) { - result = (lhs >= rhs); - } else { - result = (lhs == rhs); - } - this->HandleBinaryOp(result, reducible, arg, newArgs, argP1, argP2); - } + // NOTE Handle special case `if(... BLAH_BLAH MATCHES)` + // (i.e., w/o regex to match which is possibly result of + // variable expansion to an empty string) + if (args.next != newArgs.end() && + this->IsKeyword(keyMATCHES, *args.current)) { + newArgs.ReduceOneArg(false, args); + } + + // NOTE Fail fast: All the binary ops below require 2 arguments. + else if (args.next == newArgs.end() || args.nextnext == newArgs.end()) { + continue; + } - if (argP1 != newArgs.end() && argP2 != newArgs.end() && - (this->IsKeyword(keySTRLESS, *argP1) || - this->IsKeyword(keySTRLESS_EQUAL, *argP1) || - this->IsKeyword(keySTRGREATER, *argP1) || - this->IsKeyword(keySTRGREATER_EQUAL, *argP1) || - this->IsKeyword(keySTREQUAL, *argP1))) { - def = this->GetVariableOrString(*arg); - def2 = this->GetVariableOrString(*argP2); - int val = (*def).compare(*def2); - bool result; - if (*(argP1) == keySTRLESS) { - result = (val < 0); - } else if (*(argP1) == keySTRLESS_EQUAL) { - result = (val <= 0); - } else if (*(argP1) == keySTRGREATER) { - result = (val > 0); - } else if (*(argP1) == keySTRGREATER_EQUAL) { - result = (val >= 0); - } else // strequal - { - result = (val == 0); - } - this->HandleBinaryOp(result, reducible, arg, newArgs, argP1, argP2); + else if (this->IsKeyword(keyMATCHES, *args.next)) { + cmValue def = this->GetDefinitionIfUnquoted(*args.current); + + std::string def_buf; + if (!def) { + def = cmValue(args.current->GetValue()); + } else if (cmHasLiteralPrefix(args.current->GetValue(), + "CMAKE_MATCH_")) { + // The string to match is owned by our match result variables. + // Move it to our own buffer before clearing them. + def_buf = *def; + def = cmValue(def_buf); } - if (argP1 != newArgs.end() && argP2 != newArgs.end() && - (this->IsKeyword(keyVERSION_LESS, *argP1) || - this->IsKeyword(keyVERSION_LESS_EQUAL, *argP1) || - this->IsKeyword(keyVERSION_GREATER, *argP1) || - this->IsKeyword(keyVERSION_GREATER_EQUAL, *argP1) || - this->IsKeyword(keyVERSION_EQUAL, *argP1))) { - def = this->GetVariableOrString(*arg); - def2 = this->GetVariableOrString(*argP2); - cmSystemTools::CompareOp op; - if (*argP1 == keyVERSION_LESS) { - op = cmSystemTools::OP_LESS; - } else if (*argP1 == keyVERSION_LESS_EQUAL) { - op = cmSystemTools::OP_LESS_EQUAL; - } else if (*argP1 == keyVERSION_GREATER) { - op = cmSystemTools::OP_GREATER; - } else if (*argP1 == keyVERSION_GREATER_EQUAL) { - op = cmSystemTools::OP_GREATER_EQUAL; - } else { // version_equal - op = cmSystemTools::OP_EQUAL; - } - bool result = - cmSystemTools::VersionCompare(op, def->c_str(), def2->c_str()); - this->HandleBinaryOp(result, reducible, arg, newArgs, argP1, argP2); + this->Makefile.ClearMatches(); + + const auto& rex = args.nextnext->GetValue(); + cmsys::RegularExpression regEntry; + if (!regEntry.compile(rex)) { + std::ostringstream error; + error << "Regular expression \"" << rex << "\" cannot compile"; + errorString = error.str(); + status = MessageType::FATAL_ERROR; + return false; } - // is file A newer than file B - if (argP1 != newArgs.end() && argP2 != newArgs.end() && - this->IsKeyword(keyIS_NEWER_THAN, *argP1)) { - int fileIsNewer = 0; - cmsys::Status ftcStatus = cmSystemTools::FileTimeCompare( - arg->GetValue(), (argP2)->GetValue(), &fileIsNewer); - this->HandleBinaryOp( - (!ftcStatus || fileIsNewer == 1 || fileIsNewer == 0), reducible, arg, - newArgs, argP1, argP2); + const auto match = regEntry.find(*def); + if (match) { + this->Makefile.StoreMatches(regEntry); } + newArgs.ReduceTwoArgs(match, args); + } + + else if ((matchNo = + this->matchKeys(*args.next, keyLESS, keyLESS_EQUAL, keyGREATER, + keyGREATER_EQUAL, keyEQUAL))) { + + cmValue ldef = this->GetVariableOrString(*args.current); + cmValue rdef = this->GetVariableOrString(*args.nextnext); + + double lhs; + double rhs; + auto parseDoubles = [&]() { + return std::sscanf(ldef->c_str(), "%lg", &lhs) == 1 && + std::sscanf(rdef->c_str(), "%lg", &rhs) == 1; + }; + // clang-format off + const auto result = parseDoubles() && + cmRt2CtSelector< + std::less, std::less_equal, + std::greater, std::greater_equal, + std::equal_to + >::eval(matchNo, lhs, rhs); + // clang-format on + newArgs.ReduceTwoArgs(result, args); + } + + else if ((matchNo = this->matchKeys(*args.next, keySTRLESS, + keySTRLESS_EQUAL, keySTRGREATER, + keySTRGREATER_EQUAL, keySTREQUAL))) { + + const cmValue lhs = this->GetVariableOrString(*args.current); + const cmValue rhs = this->GetVariableOrString(*args.nextnext); + const auto val = (*lhs).compare(*rhs); + // clang-format off + const auto result = cmRt2CtSelector< + std::less, std::less_equal, + std::greater, std::greater_equal, + std::equal_to + >::eval(matchNo, val, 0); + // clang-format on + newArgs.ReduceTwoArgs(result, args); + } + + else if ((matchNo = + this->matchKeys(*args.next, keyVERSION_LESS, + keyVERSION_LESS_EQUAL, keyVERSION_GREATER, + keyVERSION_GREATER_EQUAL, keyVERSION_EQUAL))) { + const auto op = MATCH2CMPOP[matchNo - 1]; + const std::string& lhs = this->GetVariableOrString(*args.current); + const std::string& rhs = this->GetVariableOrString(*args.nextnext); + const auto result = cmSystemTools::VersionCompare(op, lhs, rhs); + newArgs.ReduceTwoArgs(result, args); + } + + // is file A newer than file B + else if (this->IsKeyword(keyIS_NEWER_THAN, *args.next)) { + auto fileIsNewer = 0; + cmsys::Status ftcStatus = cmSystemTools::FileTimeCompare( + args.current->GetValue(), args.nextnext->GetValue(), &fileIsNewer); + newArgs.ReduceTwoArgs( + (!ftcStatus || fileIsNewer == 1 || fileIsNewer == 0), args); + } + + else if (this->IsKeyword(keyIN_LIST, *args.next)) { - if (argP1 != newArgs.end() && argP2 != newArgs.end() && - this->IsKeyword(keyIN_LIST, *argP1)) { - if (this->Policy57Status != cmPolicies::OLD && - this->Policy57Status != cmPolicies::WARN) { - bool result = false; - - def = this->GetVariableOrString(*arg); - def2 = this->Makefile.GetDefinition(argP2->GetValue()); - - if (def2) { - std::vector<std::string> list = cmExpandedList(*def2, true); - result = cm::contains(list, *def); - } - - this->HandleBinaryOp(result, reducible, arg, newArgs, argP1, argP2); - } else if (this->Policy57Status == cmPolicies::WARN) { - std::ostringstream e; - e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0057) << "\n"; - e << "IN_LIST will be interpreted as an operator " - "when the policy is set to NEW. " - "Since the policy is not set the OLD behavior will be used."; - - this->Makefile.IssueMessage(MessageType::AUTHOR_WARNING, e.str()); - } + if (this->Policy57Status != cmPolicies::OLD && + this->Policy57Status != cmPolicies::WARN) { + + cmValue lhs = this->GetVariableOrString(*args.current); + cmValue rhs = this->Makefile.GetDefinition(args.nextnext->GetValue()); + + newArgs.ReduceTwoArgs( + rhs && cm::contains(cmExpandedList(*rhs, true), *lhs), args); } - ++arg; + else if (this->Policy57Status == cmPolicies::WARN) { + std::ostringstream e; + e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0057) + << "\n" + "IN_LIST will be interpreted as an operator " + "when the policy is set to NEW. " + "Since the policy is not set the OLD behavior will be used."; + + this->Makefile.IssueMessage(MessageType::AUTHOR_WARNING, e.str()); + } } - } while (reducible); + } return true; } @@ -699,23 +778,14 @@ bool cmConditionEvaluator::HandleLevel3(cmArgumentList& newArgs, std::string& errorString, MessageType& status) { - int reducible; - do { - reducible = 0; - auto arg = newArgs.begin(); - cmArgumentList::iterator argP1; - cmArgumentList::iterator argP2; - while (arg != newArgs.end()) { - argP1 = arg; - this->IncrementArguments(newArgs, argP1, argP2); - if (argP1 != newArgs.end() && this->IsKeyword(keyNOT, *arg)) { - bool rhs = this->GetBooleanValueWithAutoDereference( - *argP1, errorString, status); - this->HandlePredicate(!rhs, reducible, arg, newArgs, argP1, argP2); - } - ++arg; + for (auto args = newArgs.make2ArgsIterator(); args.next != newArgs.end(); + args.advance(newArgs)) { + if (this->IsKeyword(keyNOT, *args.current)) { + const auto rhs = this->GetBooleanValueWithAutoDereference( + *args.next, errorString, status); + newArgs.ReduceOneArg(!rhs, args); } - } while (reducible); + } return true; } @@ -725,38 +795,24 @@ bool cmConditionEvaluator::HandleLevel4(cmArgumentList& newArgs, std::string& errorString, MessageType& status) { - int reducible; - bool lhs; - bool rhs; - do { - reducible = 0; - auto arg = newArgs.begin(); - cmArgumentList::iterator argP1; - cmArgumentList::iterator argP2; - while (arg != newArgs.end()) { - argP1 = arg; - this->IncrementArguments(newArgs, argP1, argP2); - if (argP1 != newArgs.end() && this->IsKeyword(keyAND, *argP1) && - argP2 != newArgs.end()) { - lhs = - this->GetBooleanValueWithAutoDereference(*arg, errorString, status); - rhs = this->GetBooleanValueWithAutoDereference(*argP2, errorString, - status); - this->HandleBinaryOp((lhs && rhs), reducible, arg, newArgs, argP1, - argP2); - } - - if (argP1 != newArgs.end() && this->IsKeyword(keyOR, *argP1) && - argP2 != newArgs.end()) { - lhs = - this->GetBooleanValueWithAutoDereference(*arg, errorString, status); - rhs = this->GetBooleanValueWithAutoDereference(*argP2, errorString, - status); - this->HandleBinaryOp((lhs || rhs), reducible, arg, newArgs, argP1, - argP2); - } - ++arg; + for (auto args = newArgs.make3ArgsIterator(); args.nextnext != newArgs.end(); + args.advance(newArgs)) { + + int matchNo; + + if ((matchNo = this->matchKeys(*args.next, keyAND, keyOR))) { + const auto lhs = this->GetBooleanValueWithAutoDereference( + *args.current, errorString, status); + const auto rhs = this->GetBooleanValueWithAutoDereference( + *args.nextnext, errorString, status); + // clang-format off + const auto result = + cmRt2CtSelector< + std::logical_and, std::logical_or + >::eval(matchNo, lhs, rhs); + // clang-format on + newArgs.ReduceTwoArgs(result, args); } - } while (reducible); + } return true; } diff --git a/Source/cmConditionEvaluator.h b/Source/cmConditionEvaluator.h index cf00ede35..37b7825b3 100644 --- a/Source/cmConditionEvaluator.h +++ b/Source/cmConditionEvaluator.h @@ -4,23 +4,22 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include <list> #include <string> #include <vector> -#include "cmExpandedCommandArgument.h" +#include <cmext/string_view> + #include "cmListFileCache.h" #include "cmMessageType.h" #include "cmPolicies.h" -#include "cmProperty.h" +#include "cmValue.h" +class cmExpandedCommandArgument; class cmMakefile; class cmConditionEvaluator { public: - using cmArgumentList = std::list<cmExpandedCommandArgument>; - cmConditionEvaluator(cmMakefile& makefile, cmListFileBacktrace bt); // this is a shared function for both If and Else to determine if the @@ -30,14 +29,16 @@ public: std::string& errorString, MessageType& status); private: + class cmArgumentList; + // Filter the given variable definition based on policy CMP0054. - cmProp GetDefinitionIfUnquoted( + cmValue GetDefinitionIfUnquoted( const cmExpandedCommandArgument& argument) const; - cmProp GetVariableOrString(const cmExpandedCommandArgument& argument) const; + cmValue GetVariableOrString(const cmExpandedCommandArgument& argument) const; - bool IsKeyword(std::string const& keyword, - cmExpandedCommandArgument& argument) const; + bool IsKeyword(cm::static_string_view keyword, + const cmExpandedCommandArgument& argument) const; bool GetBooleanValue(cmExpandedCommandArgument& arg) const; @@ -49,19 +50,14 @@ private: MessageType& status, bool oneArg = false) const; - void IncrementArguments(cmArgumentList& newArgs, - cmArgumentList::iterator& argP1, - cmArgumentList::iterator& argP2) const; + template <int N> + int matchKeysImpl(const cmExpandedCommandArgument&); - void HandlePredicate(bool value, int& reducible, - cmArgumentList::iterator& arg, cmArgumentList& newArgs, - cmArgumentList::iterator& argP1, - cmArgumentList::iterator& argP2) const; + template <int N, typename T, typename... Keys> + int matchKeysImpl(const cmExpandedCommandArgument&, T, Keys...); - void HandleBinaryOp(bool value, int& reducible, - cmArgumentList::iterator& arg, cmArgumentList& newArgs, - cmArgumentList::iterator& argP1, - cmArgumentList::iterator& argP2); + template <typename... Keys> + int matchKeys(const cmExpandedCommandArgument&, Keys...); bool HandleLevel0(cmArgumentList& newArgs, std::string& errorString, MessageType& status); diff --git a/Source/cmConfigure.cmake.h.in b/Source/cmConfigure.cmake.h.in index aeca6b42a..6a419f681 100644 --- a/Source/cmConfigure.cmake.h.in +++ b/Source/cmConfigure.cmake.h.in @@ -16,7 +16,6 @@ #cmakedefine HAVE_ENVIRON_NOT_REQUIRE_PROTOTYPE #cmakedefine HAVE_UNSETENV -#cmakedefine CMake_USE_ELF_PARSER #cmakedefine CMake_USE_MACH_PARSER #cmakedefine CMake_USE_XCOFF_PARSER #define CMake_DEFAULT_RECURSION_LIMIT @CMake_DEFAULT_RECURSION_LIMIT@ diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx index bf181433b..971c86e59 100644 --- a/Source/cmCoreTryCompile.cxx +++ b/Source/cmCoreTryCompile.cxx @@ -19,11 +19,11 @@ #include "cmMessageType.h" #include "cmOutputConverter.h" #include "cmPolicies.h" -#include "cmProperty.h" #include "cmState.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" +#include "cmValue.h" #include "cmVersion.h" #include "cmake.h" @@ -246,7 +246,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv, this->SrcFileSignature = true; cmStateEnums::TargetType targetType = cmStateEnums::EXECUTABLE; - cmProp tt = this->Makefile->GetDefinition("CMAKE_TRY_COMPILE_TARGET_TYPE"); + cmValue tt = this->Makefile->GetDefinition("CMAKE_TRY_COMPILE_TARGET_TYPE"); if (!isTryRun && cmNonempty(tt)) { if (*tt == cmState::GetTargetTypeName(cmStateEnums::EXECUTABLE)) { targetType = cmStateEnums::EXECUTABLE; @@ -540,7 +540,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv, return -1; } - cmProp def = this->Makefile->GetDefinition("CMAKE_MODULE_PATH"); + cmValue def = this->Makefile->GetDefinition("CMAKE_MODULE_PATH"); fprintf(fout, "cmake_minimum_required(VERSION %u.%u.%u.%u)\n", cmVersion::GetMajorVersion(), cmVersion::GetMinorVersion(), cmVersion::GetPatchVersion(), cmVersion::GetTweakVersion()); @@ -549,7 +549,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv, } /* Set MSVC runtime library policy to match our selection. */ - if (cmProp msvcRuntimeLibraryDefault = + if (cmValue msvcRuntimeLibraryDefault = this->Makefile->GetDefinition(kCMAKE_MSVC_RUNTIME_LIBRARY_DEFAULT)) { fprintf(fout, "cmake_policy(SET CMP0091 %s)\n", !msvcRuntimeLibraryDefault->empty() ? "NEW" : "OLD"); @@ -564,7 +564,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv, } /* Set ARMClang cpu/arch policy to match outer project. */ - if (cmProp cmp0123 = + if (cmValue cmp0123 = this->Makefile->GetDefinition(kCMAKE_ARMClang_CMP0123)) { fprintf(fout, "cmake_policy(SET CMP0123 %s)\n", *cmp0123 == "NEW"_s ? "NEW" : "OLD"); @@ -582,11 +582,11 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv, projectLangs += " " + li; std::string rulesOverrideBase = "CMAKE_USER_MAKE_RULES_OVERRIDE"; std::string rulesOverrideLang = cmStrCat(rulesOverrideBase, "_", li); - if (cmProp rulesOverridePath = + if (cmValue rulesOverridePath = this->Makefile->GetDefinition(rulesOverrideLang)) { fprintf(fout, "set(%s \"%s\")\n", rulesOverrideLang.c_str(), rulesOverridePath->c_str()); - } else if (cmProp rulesOverridePath2 = + } else if (cmValue rulesOverridePath2 = this->Makefile->GetDefinition(rulesOverrideBase)) { fprintf(fout, "set(%s \"%s\")\n", rulesOverrideBase.c_str(), rulesOverridePath2->c_str()); @@ -604,9 +604,9 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv, fprintf(fout, "set(CMAKE_VERBOSE_MAKEFILE 1)\n"); for (std::string const& li : testLangs) { std::string langFlags = "CMAKE_" + li + "_FLAGS"; - cmProp flags = this->Makefile->GetDefinition(langFlags); + cmValue flags = this->Makefile->GetDefinition(langFlags); fprintf(fout, "set(CMAKE_%s_FLAGS %s)\n", li.c_str(), - cmOutputConverter::EscapeForCMake(cmToCStrSafe(flags)).c_str()); + cmOutputConverter::EscapeForCMake(*flags).c_str()); fprintf(fout, "set(CMAKE_%s_FLAGS \"${CMAKE_%s_FLAGS}" " ${COMPILE_DEFINITIONS}\")\n", @@ -626,6 +626,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv, /* clang-format on */ this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, w.str()); } + CM_FALLTHROUGH; case cmPolicies::OLD: // OLD behavior is to do nothing. break; @@ -643,10 +644,9 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv, for (std::string const& li : testLangs) { std::string const langFlagsCfg = cmStrCat("CMAKE_", li, "_FLAGS_", cfg); - cmProp flagsCfg = this->Makefile->GetDefinition(langFlagsCfg); - fprintf( - fout, "set(%s %s)\n", langFlagsCfg.c_str(), - cmOutputConverter::EscapeForCMake(cmToCStrSafe(flagsCfg)).c_str()); + cmValue flagsCfg = this->Makefile->GetDefinition(langFlagsCfg); + fprintf(fout, "set(%s %s)\n", langFlagsCfg.c_str(), + cmOutputConverter::EscapeForCMake(*flagsCfg).c_str()); } } break; } @@ -664,6 +664,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv, /* clang-format on */ this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, w.str()); } + CM_FALLTHROUGH; case cmPolicies::OLD: // OLD behavior is to do nothing. break; @@ -676,11 +677,10 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv, case cmPolicies::NEW: // NEW behavior is to pass linker flags. { - cmProp exeLinkFlags = + cmValue exeLinkFlags = this->Makefile->GetDefinition("CMAKE_EXE_LINKER_FLAGS"); fprintf(fout, "set(CMAKE_EXE_LINKER_FLAGS %s)\n", - cmOutputConverter::EscapeForCMake(cmToCStrSafe(exeLinkFlags)) - .c_str()); + cmOutputConverter::EscapeForCMake(*exeLinkFlags).c_str()); } break; } @@ -762,7 +762,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv, vars.insert(kCMAKE_WARN_DEPRECATED); vars.emplace("CMAKE_MSVC_RUNTIME_LIBRARY"_s); - if (cmProp varListStr = this->Makefile->GetDefinition( + if (cmValue varListStr = this->Makefile->GetDefinition( kCMAKE_TRY_COMPILE_PLATFORM_VARIABLES)) { std::vector<std::string> varList = cmExpandedList(*varListStr); vars.insert(varList.begin(), varList.end()); @@ -801,7 +801,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv, cmLocalGenerator doesn't allow building for "the other" architecture only via CMAKE_OSX_ARCHITECTURES. */ - if (cmProp tcArchs = this->Makefile->GetDefinition( + if (cmValue tcArchs = this->Makefile->GetDefinition( kCMAKE_TRY_COMPILE_OSX_ARCHITECTURES)) { vars.erase(kCMAKE_OSX_ARCHITECTURES); std::string flag = "-DCMAKE_OSX_ARCHITECTURES=" + *tcArchs; @@ -809,7 +809,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv, } for (std::string const& var : vars) { - if (cmProp val = this->Makefile->GetDefinition(var)) { + if (cmValue val = this->Makefile->GetDefinition(var)) { std::string flag = "-D" + var + "=" + *val; cmakeFlags.push_back(std::move(flag)); } @@ -880,6 +880,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv, this->Makefile->IssueMessage( MessageType::FATAL_ERROR, cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0067)); + break; case cmPolicies::NEW: // NEW behavior is to honor the language standard variables. // We already initialized honorStandard to true. @@ -954,7 +955,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv, if (this->Makefile->GetState()->UseGhsMultiIDE()) { // Forward the GHS variables to the inner project cache. for (std::string const& var : ghs_platform_vars) { - if (cmProp val = this->Makefile->GetDefinition(var)) { + if (cmValue val = this->Makefile->GetDefinition(var)) { std::string flag = "-D" + var + "=" + "'" + *val + "'"; cmakeFlags.push_back(std::move(flag)); } @@ -1096,7 +1097,7 @@ void cmCoreTryCompile::FindOutputFile(const std::string& targetName, std::vector<std::string> searchDirs; searchDirs.emplace_back(); - cmProp config = + cmValue config = this->Makefile->GetDefinition("CMAKE_TRY_COMPILE_CONFIGURATION"); // if a config was specified try that first if (cmNonempty(config)) { diff --git a/Source/cmCurl.cxx b/Source/cmCurl.cxx index 233790e54..28ee24dfe 100644 --- a/Source/cmCurl.cxx +++ b/Source/cmCurl.cxx @@ -5,9 +5,17 @@ #if !defined(CMAKE_USE_SYSTEM_CURL) && !defined(_WIN32) && \ !defined(__APPLE__) && !defined(CURL_CA_BUNDLE) && !defined(CURL_CA_PATH) # define CMAKE_FIND_CAFILE -# include "cmSystemTools.h" #endif #include "cmStringAlgorithms.h" +#include "cmSystemTools.h" + +#if defined(_WIN32) +# include <vector> + +# include <windows.h> + +# include "cmsys/Encoding.hxx" +#endif // curl versions before 7.21.5 did not provide this error code #if defined(LIBCURL_VERSION_NUM) && LIBCURL_VERSION_NUM < 0x071505 @@ -23,11 +31,11 @@ } \ } while (false) -std::string cmCurlSetCAInfo(::CURL* curl, const char* cafile) +std::string cmCurlSetCAInfo(::CURL* curl, const std::string& cafile) { std::string e; - if (cafile && *cafile) { - ::CURLcode res = ::curl_easy_setopt(curl, CURLOPT_CAINFO, cafile); + if (!cafile.empty()) { + ::CURLcode res = ::curl_easy_setopt(curl, CURLOPT_CAINFO, cafile.c_str()); check_curl_result(res, "Unable to set TLS/SSL Verify CAINFO: "); } #ifdef CMAKE_FIND_CAFILE @@ -95,3 +103,35 @@ std::string cmCurlSetNETRCOption(::CURL* curl, const std::string& netrc_level, } return e; } + +std::string cmCurlFixFileURL(std::string url) +{ + if (!cmHasLiteralPrefix(url, "file://")) { + return url; + } + + // libcurl 7.77 and below accidentally allowed spaces in URLs in some cases. + // One such case was file:// URLs, which CMake has long accepted as a result. + // Explicitly encode spaces for a URL. + cmSystemTools::ReplaceString(url, " ", "%20"); + +#if defined(_WIN32) + // libcurl doesn't support file:// urls for unicode filenames on Windows. + // Convert string from UTF-8 to ACP if this is a file:// URL. + std::wstring wurl = cmsys::Encoding::ToWide(url); + if (!wurl.empty()) { + int mblen = + WideCharToMultiByte(CP_ACP, 0, wurl.c_str(), -1, NULL, 0, NULL, NULL); + if (mblen > 0) { + std::vector<char> chars(mblen); + mblen = WideCharToMultiByte(CP_ACP, 0, wurl.c_str(), -1, &chars[0], + mblen, NULL, NULL); + if (mblen > 0) { + url = &chars[0]; + } + } + } +#endif + + return url; +} diff --git a/Source/cmCurl.h b/Source/cmCurl.h index fb716f80c..b5134f466 100644 --- a/Source/cmCurl.h +++ b/Source/cmCurl.h @@ -8,6 +8,7 @@ #include <cm3p/curl/curl.h> -std::string cmCurlSetCAInfo(::CURL* curl, const char* cafile = nullptr); +std::string cmCurlSetCAInfo(::CURL* curl, const std::string& cafile = {}); std::string cmCurlSetNETRCOption(::CURL* curl, const std::string& netrc_level, const std::string& netrc_file); +std::string cmCurlFixFileURL(std::string url); diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx index 5a2683bb8..fd0a63c29 100644 --- a/Source/cmCustomCommandGenerator.cxx +++ b/Source/cmCustomCommandGenerator.cxx @@ -19,11 +19,11 @@ #include "cmGlobalGenerator.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" -#include "cmProperty.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTransformDepfile.h" +#include "cmValue.h" namespace { std::string EvaluateSplitConfigGenex( @@ -91,7 +91,7 @@ std::string EvaluateSplitConfigGenex( // Record targets referenced by the genex. if (utils) { - // FIXME: What is the proper condition for a cross-dependency? + // Use a cross-dependency if we referenced the command config. bool const cross = !useOutputConfig; for (cmGeneratorTarget* gt : cge->GetTargets()) { utils->emplace(BT<std::pair<std::string, bool>>( @@ -176,6 +176,8 @@ cmCustomCommandGenerator::cmCustomCommandGenerator( cmGeneratorTarget const* target{ lg->FindGeneratorTargetToUse( this->Target) }; + bool const distinctConfigs = this->OutputConfig != this->CommandConfig; + const cmCustomCommandLines& cmdlines = this->CC->GetCommandLines(); for (cmCustomCommandLine const& cmdline : cmdlines) { cmCustomCommandLine argv; @@ -191,8 +193,10 @@ cmCustomCommandGenerator::cmCustomCommandGenerator( argv.push_back(std::move(parsed_arg)); } - // For remaining arguments, we default to the OUTPUT_CONFIG. - useOutputConfig = true; + if (distinctConfigs) { + // For remaining arguments, we default to the OUTPUT_CONFIG. + useOutputConfig = true; + } } if (!argv.empty()) { @@ -200,7 +204,7 @@ cmCustomCommandGenerator::cmCustomCommandGenerator( // collect the target to add a target-level dependency on it. cmGeneratorTarget* gt = this->LG->FindGeneratorTargetToUse(argv.front()); if (gt && gt->GetType() == cmStateEnums::EXECUTABLE) { - // FIXME: What is the proper condition for a cross-dependency? + // GetArgv0Location uses the command config, so use a cross-dependency. bool const cross = true; this->Utilities.emplace(BT<std::pair<std::string, bool>>( { gt->GetName(), cross }, cc.GetBacktrace())); @@ -284,7 +288,7 @@ void cmCustomCommandGenerator::FillEmulatorsWithArguments() if (target && target->GetType() == cmStateEnums::EXECUTABLE && !target->IsImported()) { - cmProp emulator_property = + cmValue emulator_property = target->GetProperty("CROSSCOMPILING_EMULATOR"); if (!emulator_property) { continue; diff --git a/Source/cmDefinitions.cxx b/Source/cmDefinitions.cxx index 4a4f87d8b..a5f8aabec 100644 --- a/Source/cmDefinitions.cxx +++ b/Source/cmDefinitions.cxx @@ -34,11 +34,11 @@ cmDefinitions::Def const& cmDefinitions::GetInternal(const std::string& key, return begin->Map.emplace(key, def).first->second; } -const std::string* cmDefinitions::Get(const std::string& key, StackIter begin, - StackIter end) +cmValue cmDefinitions::Get(const std::string& key, StackIter begin, + StackIter end) { Def const& def = cmDefinitions::GetInternal(key, begin, end, false); - return def.Value ? def.Value.str_if_stable() : nullptr; + return def.Value ? cmValue(def.Value.str_if_stable()) : nullptr; } void cmDefinitions::Raise(const std::string& key, StackIter begin, diff --git a/Source/cmDefinitions.h b/Source/cmDefinitions.h index b650aa860..22fef807a 100644 --- a/Source/cmDefinitions.h +++ b/Source/cmDefinitions.h @@ -13,6 +13,7 @@ #include "cmLinkedTree.h" #include "cmString.hxx" +#include "cmValue.h" /** \class cmDefinitions * \brief Store a scope of variable definitions for CMake language. @@ -28,8 +29,7 @@ class cmDefinitions public: // -- Static member functions - static const std::string* Get(const std::string& key, StackIter begin, - StackIter end); + static cmValue Get(const std::string& key, StackIter begin, StackIter end); static void Raise(const std::string& key, StackIter begin, StackIter end); diff --git a/Source/cmDepends.cxx b/Source/cmDepends.cxx index 46c7e3e77..eca1abdaa 100644 --- a/Source/cmDepends.cxx +++ b/Source/cmDepends.cxx @@ -11,9 +11,9 @@ #include "cmGeneratedFileStream.h" #include "cmLocalUnixMakefileGenerator3.h" #include "cmMakefile.h" -#include "cmProperty.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" cmDepends::cmDepends(cmLocalUnixMakefileGenerator3* lg, std::string targetDir) : LocalGenerator(lg) @@ -232,7 +232,7 @@ void cmDepends::SetIncludePathFromLanguage(const std::string& lang) std::string includePathVar = cmStrCat("CMAKE_", lang, "_TARGET_INCLUDE_PATH"); cmMakefile* mf = this->LocalGenerator->GetMakefile(); - cmProp includePath = mf->GetDefinition(includePathVar); + cmValue includePath = mf->GetDefinition(includePathVar); if (includePath) { cmExpandList(*includePath, this->IncludePath); } else { diff --git a/Source/cmDependsC.cxx b/Source/cmDependsC.cxx index da37d4531..25278090a 100644 --- a/Source/cmDependsC.cxx +++ b/Source/cmDependsC.cxx @@ -10,9 +10,9 @@ #include "cmGlobalUnixMakefileGenerator3.h" #include "cmLocalUnixMakefileGenerator3.h" #include "cmMakefile.h" -#include "cmProperty.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" #define INCLUDE_REGEX_LINE \ "^[ \t]*[#%][ \t]*(include|import)[ \t]*[<\"]([^\">]+)([\">])" @@ -40,12 +40,12 @@ cmDependsC::cmDependsC(cmLocalUnixMakefileGenerator3* lg, std::string complainRegex = "^$"; { std::string scanRegexVar = cmStrCat("CMAKE_", lang, "_INCLUDE_REGEX_SCAN"); - if (cmProp sr = mf->GetDefinition(scanRegexVar)) { + if (cmValue sr = mf->GetDefinition(scanRegexVar)) { scanRegex = *sr; } std::string complainRegexVar = cmStrCat("CMAKE_", lang, "_INCLUDE_REGEX_COMPLAIN"); - if (cmProp cr = mf->GetDefinition(complainRegexVar)) { + if (cmValue cr = mf->GetDefinition(complainRegexVar)) { complainRegex = *cr; } } diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx index a64dc27a9..d5e54ae37 100644 --- a/Source/cmDependsFortran.cxx +++ b/Source/cmDependsFortran.cxx @@ -16,9 +16,9 @@ #include "cmLocalUnixMakefileGenerator3.h" #include "cmMakefile.h" #include "cmOutputConverter.h" -#include "cmProperty.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" // TODO: Test compiler for the case of the mod file. Some always // use lower case and some always use upper case. I do not know if any @@ -163,12 +163,17 @@ bool cmDependsFortran::Finalize(std::ostream& makeDepends, mod_dir = this->LocalGenerator->GetCurrentBinaryDirectory(); } + bool building_intrinsics = + !mf->GetSafeDefinition("CMAKE_Fortran_TARGET_BUILDING_INSTRINSIC_MODULES") + .empty(); + // Actually write dependencies to the streams. using ObjectInfoMap = cmDependsFortranInternals::ObjectInfoMap; ObjectInfoMap const& objInfo = this->Internal->ObjectInfo; for (auto const& i : objInfo) { if (!this->WriteDependenciesReal(i.first, i.second, mod_dir, stamp_dir, - makeDepends, internalDepends)) { + makeDepends, internalDepends, + building_intrinsics)) { return false; } } @@ -307,7 +312,8 @@ bool cmDependsFortran::WriteDependenciesReal(std::string const& obj, std::string const& mod_dir, std::string const& stamp_dir, std::ostream& makeDepends, - std::ostream& internalDepends) + std::ostream& internalDepends, + bool buildingIntrinsics) { // Get the source file for this object. std::string const& src = info.Source; @@ -339,8 +345,13 @@ bool cmDependsFortran::WriteDependenciesReal(std::string const& obj, makeDepends << '\n'; } + std::set<std::string> req = info.Requires; + if (buildingIntrinsics) { + req.insert(info.Intrinsics.begin(), info.Intrinsics.end()); + } + // Write module requirements to the output stream. - for (std::string const& i : info.Requires) { + for (std::string const& i : req) { // Require only modules not provided in the same source. if (info.Provides.find(i) != info.Provides.cend()) { continue; @@ -405,7 +416,7 @@ bool cmDependsFortran::WriteDependenciesReal(std::string const& obj, makeDepends << "\t$(CMAKE_COMMAND) -E cmake_copy_f90_mod " << modFile << ' ' << stampFileForShell; cmMakefile* mf = this->LocalGenerator->GetMakefile(); - cmProp cid = mf->GetDefinition("CMAKE_Fortran_COMPILER_ID"); + cmValue cid = mf->GetDefinition("CMAKE_Fortran_COMPILER_ID"); if (cmNonempty(cid)) { makeDepends << ' ' << *cid; } diff --git a/Source/cmDependsFortran.h b/Source/cmDependsFortran.h index 0d407bc3b..a74db91f3 100644 --- a/Source/cmDependsFortran.h +++ b/Source/cmDependsFortran.h @@ -72,7 +72,8 @@ protected: std::string const& mod_dir, std::string const& stamp_dir, std::ostream& makeDepends, - std::ostream& internalDepends); + std::ostream& internalDepends, + bool buildingIntrinsics); // The source file from which to start scanning. std::string SourceFile; diff --git a/Source/cmELF.cxx b/Source/cmELF.cxx index 9a474e32c..1678ce8c6 100644 --- a/Source/cmELF.cxx +++ b/Source/cmELF.cxx @@ -17,41 +17,9 @@ #include "cmsys/FStream.hxx" -// Include the ELF format information system header. -#if defined(__OpenBSD__) -# include <elf_abi.h> -#elif defined(__HAIKU__) -# include <elf32.h> -# include <elf64.h> -using Elf32_Ehdr = struct Elf32_Ehdr; -using Elf32_Shdr = struct Elf32_Shdr; -using Elf32_Sym = struct Elf32_Sym; -using Elf32_Rel = struct Elf32_Rel; -using Elf32_Rela = struct Elf32_Rela; -# define ELFMAG0 0x7F -# define ELFMAG1 'E' -# define ELFMAG2 'L' -# define ELFMAG3 'F' -# define ET_NONE 0 -# define ET_REL 1 -# define ET_EXEC 2 -# define ET_DYN 3 -# define ET_CORE 4 -# define EM_386 3 -# define EM_SPARC 2 -# define EM_PPC 20 -#else -# include <elf.h> -#endif -#if defined(__sun) -# include <sys/link.h> // For dynamic section information -#endif -#ifdef _SCO_DS -# include <link.h> // For DT_SONAME etc. -#endif -#ifndef DT_RUNPATH -# define DT_RUNPATH 29 -#endif +#include "cmelf/elf32.h" +#include "cmelf/elf64.h" +#include "cmelf/elf_common.h" // Low-level byte swapping implementation. template <size_t s> @@ -145,6 +113,7 @@ public: virtual std::vector<char> EncodeDynamicEntries( const cmELF::DynamicEntryList&) = 0; virtual StringEntry const* GetDynamicSectionString(unsigned int tag) = 0; + virtual bool IsMips() const = 0; virtual void PrintInfo(std::ostream& os) const = 0; // Lookup the SONAME in the DYNAMIC section. @@ -218,7 +187,6 @@ struct cmELFTypes32 }; // Configure the implementation template for 64-bit ELF files. -#ifndef _SCO_DS struct cmELFTypes64 { using ELF_Ehdr = Elf64_Ehdr; @@ -228,7 +196,6 @@ struct cmELFTypes64 using tagtype = ::uint64_t; static const char* GetName() { return "64-bit"; } }; -#endif // Parser implementation template. template <class Types> @@ -262,6 +229,8 @@ public: // Lookup a string from the dynamic section with the given tag. StringEntry const* GetDynamicSectionString(unsigned int tag) override; + bool IsMips() const override { return this->ELFHeader.e_machine == EM_MIPS; } + // Print information about the ELF file. void PrintInfo(std::ostream& os) const override { @@ -345,16 +314,12 @@ private: eti == ET_CORE) { return true; } -#if defined(ET_LOOS) && defined(ET_HIOS) if (eti >= ET_LOOS && eti <= ET_HIOS) { return true; } -#endif -#if defined(ET_LOPROC) && defined(ET_HIPROC) if (eti >= ET_LOPROC && eti <= ET_HIPROC) { return true; } -#endif return false; } @@ -465,18 +430,14 @@ cmELFInternalImpl<Types>::cmELFInternalImpl(cmELF* external, break; default: { unsigned int eti = static_cast<unsigned int>(this->ELFHeader.e_type); -#if defined(ET_LOOS) && defined(ET_HIOS) if (eti >= ET_LOOS && eti <= ET_HIOS) { this->ELFType = cmELF::FileTypeSpecificOS; break; } -#endif -#if defined(ET_LOPROC) && defined(ET_HIPROC) if (eti >= ET_LOPROC && eti <= ET_HIPROC) { this->ELFType = cmELF::FileTypeSpecificProc; break; } -#endif std::ostringstream e; e << "Unknown ELF file type " << eti; this->SetErrorMessage(e.str().c_str()); @@ -681,17 +642,12 @@ cmELF::StringEntry const* cmELFInternalImpl<Types>::GetDynamicSectionString( const long cmELF::TagRPath = DT_RPATH; const long cmELF::TagRunPath = DT_RUNPATH; - -#ifdef DT_MIPS_RLD_MAP_REL const long cmELF::TagMipsRldMapRel = DT_MIPS_RLD_MAP_REL; -#else -const long cmELF::TagMipsRldMapRel = 0; -#endif cmELF::cmELF(const char* fname) { // Try to open the file. - auto fin = cm::make_unique<cmsys::ifstream>(fname); + auto fin = cm::make_unique<cmsys::ifstream>(fname, std::ios::binary); // Quit now if the file could not be opened. if (!fin || !*fin) { @@ -736,15 +692,11 @@ cmELF::cmELF(const char* fname) // 32-bit ELF this->Internal = cm::make_unique<cmELFInternalImpl<cmELFTypes32>>( this, std::move(fin), order); - } -#ifndef _SCO_DS - else if (ident[EI_CLASS] == ELFCLASS64) { + } else if (ident[EI_CLASS] == ELFCLASS64) { // 64-bit ELF this->Internal = cm::make_unique<cmELFInternalImpl<cmELFTypes64>>( this, std::move(fin), order); - } -#endif - else { + } else { this->ErrorMessage = "ELF file class is not 32-bit or 64-bit."; return; } @@ -846,6 +798,14 @@ cmELF::StringEntry const* cmELF::GetRunPath() return nullptr; } +bool cmELF::IsMIPS() const +{ + if (this->Valid()) { + return this->Internal->IsMips(); + } + return false; +} + void cmELF::PrintInfo(std::ostream& os) const { if (this->Valid()) { diff --git a/Source/cmELF.h b/Source/cmELF.h index f88ebe992..ce8bd7fb9 100644 --- a/Source/cmELF.h +++ b/Source/cmELF.h @@ -11,10 +11,6 @@ #include <utility> #include <vector> -#if !defined(CMake_USE_ELF_PARSER) -# error "This file may be included only if CMake_USE_ELF_PARSER is enabled." -#endif - class cmELFInternal; /** \class cmELF @@ -102,6 +98,9 @@ public: /** Get the RUNPATH field if any. */ StringEntry const* GetRunPath(); + /** Returns true if the ELF file targets a MIPS CPU. */ + bool IsMIPS() const; + /** Print human-readable information about the ELF file. */ void PrintInfo(std::ostream& os) const; diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx index 1a31ae4af..aa968dc38 100644 --- a/Source/cmExportBuildFileGenerator.cxx +++ b/Source/cmExportBuildFileGenerator.cxx @@ -22,6 +22,7 @@ #include "cmStringAlgorithms.h" #include "cmTarget.h" #include "cmTargetExport.h" +#include "cmValue.h" #include "cmake.h" class cmSourceFile; @@ -254,7 +255,7 @@ void cmExportBuildFileGenerator::SetImportLocationProperty( void cmExportBuildFileGenerator::HandleMissingTarget( std::string& link_libs, std::vector<std::string>& missingTargets, - cmGeneratorTarget* depender, cmGeneratorTarget* dependee) + cmGeneratorTarget const* depender, cmGeneratorTarget* dependee) { // The target is not in the export. if (!this->AppendMode) { @@ -321,7 +322,7 @@ cmExportBuildFileGenerator::FindBuildExportInfo(cmGlobalGenerator* gg, } void cmExportBuildFileGenerator::ComplainAboutMissingTarget( - cmGeneratorTarget* depender, cmGeneratorTarget* dependee, + cmGeneratorTarget const* depender, cmGeneratorTarget const* dependee, std::vector<std::string> const& exportFiles) { std::ostringstream e; @@ -344,7 +345,7 @@ void cmExportBuildFileGenerator::ComplainAboutMissingTarget( } std::string cmExportBuildFileGenerator::InstallNameDir( - cmGeneratorTarget* target, const std::string& config) + cmGeneratorTarget const* target, const std::string& config) { std::string install_name_dir; diff --git a/Source/cmExportBuildFileGenerator.h b/Source/cmExportBuildFileGenerator.h index 264494dc5..244f526db 100644 --- a/Source/cmExportBuildFileGenerator.h +++ b/Source/cmExportBuildFileGenerator.h @@ -60,11 +60,11 @@ protected: cmGeneratorTarget const* target) const; void HandleMissingTarget(std::string& link_libs, std::vector<std::string>& missingTargets, - cmGeneratorTarget* depender, + cmGeneratorTarget const* depender, cmGeneratorTarget* dependee) override; - void ComplainAboutMissingTarget(cmGeneratorTarget* depender, - cmGeneratorTarget* dependee, + void ComplainAboutMissingTarget(cmGeneratorTarget const* depender, + cmGeneratorTarget const* dependee, std::vector<std::string> const& namespaces); /** Fill in properties indicating built file locations. */ @@ -73,7 +73,7 @@ protected: cmGeneratorTarget* target, ImportPropertyMap& properties); - std::string InstallNameDir(cmGeneratorTarget* target, + std::string InstallNameDir(cmGeneratorTarget const* target, const std::string& config) override; std::pair<std::vector<std::string>, std::string> FindBuildExportInfo( diff --git a/Source/cmExportCommand.cxx b/Source/cmExportCommand.cxx index 352eaf291..63440a317 100644 --- a/Source/cmExportCommand.cxx +++ b/Source/cmExportCommand.cxx @@ -282,6 +282,7 @@ static bool HandlePackage(std::vector<std::string> const& args, // CMP0090 decides both the default and what variable changes it. switch (mf.GetPolicyStatus(cmPolicies::CMP0090)) { case cmPolicies::WARN: + CM_FALLTHROUGH; case cmPolicies::OLD: // Default is to export, but can be disabled. if (mf.IsOn("CMAKE_EXPORT_NO_PACKAGE_REGISTRY")) { diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index dd611de6b..8ca9a66cd 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -21,13 +21,12 @@ #include "cmMessageType.h" #include "cmOutputConverter.h" #include "cmPolicies.h" -#include "cmProperty.h" #include "cmPropertyMap.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" -#include "cmTargetExport.h" +#include "cmValue.h" static std::string cmExportFileGeneratorEscape(std::string const& str) { @@ -123,10 +122,10 @@ void cmExportFileGenerator::GenerateImportConfig( } void cmExportFileGenerator::PopulateInterfaceProperty( - const std::string& propName, cmGeneratorTarget* target, + const std::string& propName, cmGeneratorTarget const* target, ImportPropertyMap& properties) { - cmProp input = target->GetProperty(propName); + cmValue input = target->GetProperty(propName); if (input) { properties[propName] = *input; } @@ -134,11 +133,11 @@ void cmExportFileGenerator::PopulateInterfaceProperty( void cmExportFileGenerator::PopulateInterfaceProperty( const std::string& propName, const std::string& outputName, - cmGeneratorTarget* target, + cmGeneratorTarget const* target, cmGeneratorExpression::PreprocessContext preprocessRule, ImportPropertyMap& properties, std::vector<std::string>& missingTargets) { - cmProp input = target->GetProperty(propName); + cmValue input = target->GetProperty(propName); if (input) { if (input->empty()) { // Set to empty @@ -168,14 +167,14 @@ void cmExportFileGenerator::GenerateRequiredCMakeVersion( } bool cmExportFileGenerator::PopulateInterfaceLinkLibrariesProperty( - cmGeneratorTarget* target, + cmGeneratorTarget const* target, cmGeneratorExpression::PreprocessContext preprocessRule, ImportPropertyMap& properties, std::vector<std::string>& missingTargets) { if (!target->IsLinkable()) { return false; } - cmProp input = target->GetProperty("INTERFACE_LINK_LIBRARIES"); + cmValue input = target->GetProperty("INTERFACE_LINK_LIBRARIES"); if (input) { std::string prepro = cmGeneratorExpression::Preprocess(*input, preprocessRule); @@ -196,7 +195,7 @@ static bool isSubDirectory(std::string const& a, std::string const& b) } static bool checkInterfaceDirs(const std::string& prepro, - cmGeneratorTarget* target, + cmGeneratorTarget const* target, const std::string& prop) { std::string const& installDir = @@ -335,14 +334,14 @@ static void prefixItems(std::string& exportDirs) } void cmExportFileGenerator::PopulateSourcesInterface( - cmTargetExport* tei, cmGeneratorExpression::PreprocessContext preprocessRule, + cmGeneratorTarget const* gt, + cmGeneratorExpression::PreprocessContext preprocessRule, ImportPropertyMap& properties, std::vector<std::string>& missingTargets) { - cmGeneratorTarget* gt = tei->Target; assert(preprocessRule == cmGeneratorExpression::InstallInterface); const char* propName = "INTERFACE_SOURCES"; - cmProp input = gt->GetProperty(propName); + cmValue input = gt->GetProperty(propName); if (!input) { return; @@ -366,19 +365,20 @@ void cmExportFileGenerator::PopulateSourcesInterface( } void cmExportFileGenerator::PopulateIncludeDirectoriesInterface( - cmTargetExport* tei, cmGeneratorExpression::PreprocessContext preprocessRule, + cmGeneratorTarget const* target, + cmGeneratorExpression::PreprocessContext preprocessRule, ImportPropertyMap& properties, std::vector<std::string>& missingTargets) { - cmGeneratorTarget* target = tei->Target; assert(preprocessRule == cmGeneratorExpression::InstallInterface); const char* propName = "INTERFACE_INCLUDE_DIRECTORIES"; - cmProp input = target->GetProperty(propName); + cmValue input = target->GetProperty(propName); cmGeneratorExpression ge; std::string dirs = cmGeneratorExpression::Preprocess( - tei->InterfaceIncludeDirectories, preprocessRule, true); + cmJoin(target->Target->GetInstallIncludeDirectoriesEntries(), ";"), + preprocessRule, true); this->ReplaceInstallPrefix(dirs); std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(dirs); std::string exportDirs = @@ -424,14 +424,14 @@ void cmExportFileGenerator::PopulateIncludeDirectoriesInterface( } void cmExportFileGenerator::PopulateLinkDependsInterface( - cmTargetExport* tei, cmGeneratorExpression::PreprocessContext preprocessRule, + cmGeneratorTarget const* gt, + cmGeneratorExpression::PreprocessContext preprocessRule, ImportPropertyMap& properties, std::vector<std::string>& missingTargets) { - cmGeneratorTarget* gt = tei->Target; assert(preprocessRule == cmGeneratorExpression::InstallInterface); const char* propName = "INTERFACE_LINK_DEPENDS"; - cmProp input = gt->GetProperty(propName); + cmValue input = gt->GetProperty(propName); if (!input) { return; @@ -455,14 +455,14 @@ void cmExportFileGenerator::PopulateLinkDependsInterface( } void cmExportFileGenerator::PopulateLinkDirectoriesInterface( - cmTargetExport* tei, cmGeneratorExpression::PreprocessContext preprocessRule, + cmGeneratorTarget const* gt, + cmGeneratorExpression::PreprocessContext preprocessRule, ImportPropertyMap& properties, std::vector<std::string>& missingTargets) { - cmGeneratorTarget* gt = tei->Target; assert(preprocessRule == cmGeneratorExpression::InstallInterface); const char* propName = "INTERFACE_LINK_DIRECTORIES"; - cmProp input = gt->GetProperty(propName); + cmValue input = gt->GetProperty(propName); if (!input) { return; @@ -486,7 +486,7 @@ void cmExportFileGenerator::PopulateLinkDirectoriesInterface( } void cmExportFileGenerator::PopulateInterfaceProperty( - const std::string& propName, cmGeneratorTarget* target, + const std::string& propName, cmGeneratorTarget const* target, cmGeneratorExpression::PreprocessContext preprocessRule, ImportPropertyMap& properties, std::vector<std::string>& missingTargets) { @@ -497,7 +497,7 @@ void cmExportFileGenerator::PopulateInterfaceProperty( void getPropertyContents(cmGeneratorTarget const* tgt, const std::string& prop, std::set<std::string>& ifaceProperties) { - cmProp p = tgt->GetProperty(prop); + cmValue p = tgt->GetProperty(prop); if (!p) { return; } @@ -505,7 +505,7 @@ void getPropertyContents(cmGeneratorTarget const* tgt, const std::string& prop, ifaceProperties.insert(content.begin(), content.end()); } -void getCompatibleInterfaceProperties(cmGeneratorTarget* target, +void getCompatibleInterfaceProperties(cmGeneratorTarget const* target, std::set<std::string>& ifaceProperties, const std::string& config) { @@ -544,7 +544,7 @@ void getCompatibleInterfaceProperties(cmGeneratorTarget* target, } void cmExportFileGenerator::PopulateCompatibleInterfaceProperties( - cmGeneratorTarget* gtarget, ImportPropertyMap& properties) + cmGeneratorTarget const* gtarget, ImportPropertyMap& properties) { this->PopulateInterfaceProperty("COMPATIBLE_INTERFACE_BOOL", gtarget, properties); @@ -596,7 +596,7 @@ void cmExportFileGenerator::GenerateInterfaceProperties( } bool cmExportFileGenerator::AddTargetNamespace( - std::string& input, cmGeneratorTarget* target, + std::string& input, cmGeneratorTarget const* target, std::vector<std::string>& missingTargets) { cmGeneratorTarget::TargetOrString resolved = @@ -627,7 +627,7 @@ bool cmExportFileGenerator::AddTargetNamespace( } void cmExportFileGenerator::ResolveTargetsInGeneratorExpressions( - std::string& input, cmGeneratorTarget* target, + std::string& input, cmGeneratorTarget const* target, std::vector<std::string>& missingTargets, FreeTargetsReplace replace) { if (replace == NoReplaceFreeTargets) { @@ -654,7 +654,7 @@ void cmExportFileGenerator::ResolveTargetsInGeneratorExpressions( } void cmExportFileGenerator::ResolveTargetsInGeneratorExpression( - std::string& input, cmGeneratorTarget* target, + std::string& input, cmGeneratorTarget const* target, std::vector<std::string>& missingTargets) { std::string::size_type pos = 0; @@ -744,7 +744,7 @@ void cmExportFileGenerator::ReplaceInstallPrefix(std::string& /*unused*/) void cmExportFileGenerator::SetImportLinkInterface( const std::string& config, std::string const& suffix, cmGeneratorExpression::PreprocessContext preprocessRule, - cmGeneratorTarget* target, ImportPropertyMap& properties, + cmGeneratorTarget const* target, ImportPropertyMap& properties, std::vector<std::string>& missingTargets) { // Add the transitive link dependencies for this configuration. @@ -761,12 +761,12 @@ void cmExportFileGenerator::SetImportLinkInterface( return; } - cmProp propContent; + cmValue propContent; - if (cmProp prop_suffixed = + if (cmValue prop_suffixed = target->GetProperty("LINK_INTERFACE_LIBRARIES" + suffix)) { propContent = prop_suffixed; - } else if (cmProp prop = target->GetProperty("LINK_INTERFACE_LIBRARIES")) { + } else if (cmValue prop = target->GetProperty("LINK_INTERFACE_LIBRARIES")) { propContent = prop; } else { return; @@ -854,7 +854,7 @@ void cmExportFileGenerator::SetImportDetailProperties( cmGeneratorTarget::ManagedType::Native) { std::string prop = cmStrCat("IMPORTED_COMMON_LANGUAGE_RUNTIME", suffix); std::string propval; - if (cmProp p = target->GetProperty("COMMON_LANGUAGE_RUNTIME")) { + if (cmValue p = target->GetProperty("COMMON_LANGUAGE_RUNTIME")) { propval = *p; } else if (target->IsCSharpOnly()) { // C# projects do not have the /clr flag, so we set the property @@ -880,7 +880,7 @@ static std::string const& asString(cmLinkItem const& l) template <typename T> void cmExportFileGenerator::SetImportLinkProperty( - std::string const& suffix, cmGeneratorTarget* target, + std::string const& suffix, cmGeneratorTarget const* target, const std::string& propName, std::vector<T> const& entries, ImportPropertyMap& properties, std::vector<std::string>& missingTargets, ImportLinkPropertyTargetNames targetNames) @@ -917,20 +917,20 @@ void cmExportFileGenerator::GeneratePolicyHeaderCode(std::ostream& os) // Protect that file against use with older CMake versions. /* clang-format off */ os << "# Generated by CMake\n\n"; - os << "if(\"${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}\" LESS 2.5)\n" + os << "if(\"${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}\" LESS 2.6)\n" << " message(FATAL_ERROR \"CMake >= 2.6.0 required\")\n" << "endif()\n"; /* clang-format on */ // 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.19 (this upper limit may be reviewed + // policy settings for up to CMake 3.20 (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.19)\n"; + << "cmake_policy(VERSION 2.6...3.20)\n"; /* clang-format on */ } @@ -1211,11 +1211,11 @@ void cmExportFileGenerator::GenerateImportedFileChecksCode( } bool cmExportFileGenerator::PopulateExportProperties( - cmGeneratorTarget* gte, ImportPropertyMap& properties, + cmGeneratorTarget const* gte, ImportPropertyMap& properties, std::string& errorMessage) { const auto& targetProperties = gte->Target->GetProperties(); - if (cmProp exportProperties = + if (cmValue exportProperties = targetProperties.GetPropertyValue("EXPORT_PROPERTIES")) { for (auto& prop : cmExpandedList(*exportProperties)) { /* Black list reserved properties */ @@ -1228,7 +1228,7 @@ bool cmExportFileGenerator::PopulateExportProperties( errorMessage = e.str(); return false; } - cmProp propertyValue = targetProperties.GetPropertyValue(prop); + cmValue propertyValue = targetProperties.GetPropertyValue(prop); 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. diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h index 45eaed04f..24e048bca 100644 --- a/Source/cmExportFileGenerator.h +++ b/Source/cmExportFileGenerator.h @@ -27,8 +27,6 @@ class cmGeneratorTarget; CMake_VERSION_MINOR) "." STRINGIFY(CMake_VERSION_PATCH) \ : #major "." #minor ".0") -class cmTargetExport; - /** \class cmExportFileGenerator * \brief Generate a file exporting targets from a build or install tree. * @@ -108,7 +106,7 @@ protected: }; template <typename T> void SetImportLinkProperty(std::string const& suffix, - cmGeneratorTarget* target, + cmGeneratorTarget const* target, const std::string& propName, std::vector<T> const& entries, ImportPropertyMap& properties, @@ -127,44 +125,45 @@ protected: * export set. */ virtual void HandleMissingTarget(std::string& link_libs, std::vector<std::string>& missingTargets, - cmGeneratorTarget* depender, + cmGeneratorTarget const* depender, cmGeneratorTarget* dependee) = 0; - void PopulateInterfaceProperty(const std::string&, cmGeneratorTarget* target, + void PopulateInterfaceProperty(const std::string&, + cmGeneratorTarget const* target, cmGeneratorExpression::PreprocessContext, ImportPropertyMap& properties, std::vector<std::string>& missingTargets); bool PopulateInterfaceLinkLibrariesProperty( - cmGeneratorTarget* target, cmGeneratorExpression::PreprocessContext, + cmGeneratorTarget const* target, cmGeneratorExpression::PreprocessContext, ImportPropertyMap& properties, std::vector<std::string>& missingTargets); void PopulateInterfaceProperty(const std::string& propName, - cmGeneratorTarget* target, + cmGeneratorTarget const* target, ImportPropertyMap& properties); - void PopulateCompatibleInterfaceProperties(cmGeneratorTarget* target, + void PopulateCompatibleInterfaceProperties(cmGeneratorTarget const* target, ImportPropertyMap& properties); virtual void GenerateInterfaceProperties( cmGeneratorTarget const* target, std::ostream& os, const ImportPropertyMap& properties); void PopulateIncludeDirectoriesInterface( - cmTargetExport* target, + cmGeneratorTarget const* target, cmGeneratorExpression::PreprocessContext preprocessRule, ImportPropertyMap& properties, std::vector<std::string>& missingTargets); void PopulateSourcesInterface( - cmTargetExport* target, + cmGeneratorTarget const* target, cmGeneratorExpression::PreprocessContext preprocessRule, ImportPropertyMap& properties, std::vector<std::string>& missingTargets); void PopulateLinkDirectoriesInterface( - cmTargetExport* target, + cmGeneratorTarget const* target, cmGeneratorExpression::PreprocessContext preprocessRule, ImportPropertyMap& properties, std::vector<std::string>& missingTargets); void PopulateLinkDependsInterface( - cmTargetExport* target, + cmGeneratorTarget const* target, cmGeneratorExpression::PreprocessContext preprocessRule, ImportPropertyMap& properties, std::vector<std::string>& missingTargets); void SetImportLinkInterface( const std::string& config, std::string const& suffix, cmGeneratorExpression::PreprocessContext preprocessRule, - cmGeneratorTarget* target, ImportPropertyMap& properties, + cmGeneratorTarget const* target, ImportPropertyMap& properties, std::vector<std::string>& missingTargets); enum FreeTargetsReplace @@ -174,14 +173,14 @@ protected: }; void ResolveTargetsInGeneratorExpressions( - std::string& input, cmGeneratorTarget* target, + std::string& input, cmGeneratorTarget const* target, std::vector<std::string>& missingTargets, FreeTargetsReplace replace = NoReplaceFreeTargets); virtual void GenerateRequiredCMakeVersion(std::ostream& os, const char* versionString); - bool PopulateExportProperties(cmGeneratorTarget* gte, + bool PopulateExportProperties(cmGeneratorTarget const* gte, ImportPropertyMap& properties, std::string& errorMessage); @@ -205,20 +204,20 @@ protected: private: void PopulateInterfaceProperty(const std::string&, const std::string&, - cmGeneratorTarget* target, + cmGeneratorTarget const* target, cmGeneratorExpression::PreprocessContext, ImportPropertyMap& properties, std::vector<std::string>& missingTargets); - bool AddTargetNamespace(std::string& input, cmGeneratorTarget* target, + bool AddTargetNamespace(std::string& input, cmGeneratorTarget const* target, std::vector<std::string>& missingTargets); void ResolveTargetsInGeneratorExpression( - std::string& input, cmGeneratorTarget* target, + std::string& input, cmGeneratorTarget const* target, std::vector<std::string>& missingTargets); virtual void ReplaceInstallPrefix(std::string& input); - virtual std::string InstallNameDir(cmGeneratorTarget* target, + virtual std::string InstallNameDir(cmGeneratorTarget const* target, const std::string& config) = 0; }; diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index 3c69c5001..e9ac8752f 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -21,6 +21,7 @@ #include "cmSystemTools.h" #include "cmTarget.h" #include "cmTargetExport.h" +#include "cmValue.h" cmExportInstallFileGenerator::cmExportInstallFileGenerator( cmInstallExportGenerator* iegen) @@ -85,8 +86,8 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) ImportPropertyMap properties; this->PopulateIncludeDirectoriesInterface( - te, cmGeneratorExpression::InstallInterface, properties, missingTargets); - this->PopulateSourcesInterface(te, cmGeneratorExpression::InstallInterface, + gt, cmGeneratorExpression::InstallInterface, properties, missingTargets); + this->PopulateSourcesInterface(gt, cmGeneratorExpression::InstallInterface, properties, missingTargets); this->PopulateInterfaceProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES", gt, cmGeneratorExpression::InstallInterface, @@ -110,9 +111,9 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) cmGeneratorExpression::InstallInterface, properties, missingTargets); this->PopulateLinkDirectoriesInterface( - te, cmGeneratorExpression::InstallInterface, properties, missingTargets); + gt, cmGeneratorExpression::InstallInterface, properties, missingTargets); this->PopulateLinkDependsInterface( - te, cmGeneratorExpression::InstallInterface, properties, missingTargets); + gt, cmGeneratorExpression::InstallInterface, properties, missingTargets); std::string errorMessage; if (!this->PopulateExportProperties(gt, properties, errorMessage)) { @@ -447,7 +448,7 @@ cmStateEnums::TargetType cmExportInstallFileGenerator::GetExportTargetType( void cmExportInstallFileGenerator::HandleMissingTarget( std::string& link_libs, std::vector<std::string>& missingTargets, - cmGeneratorTarget* depender, cmGeneratorTarget* dependee) + cmGeneratorTarget const* depender, cmGeneratorTarget* dependee) { const std::string name = dependee->GetName(); cmGlobalGenerator* gg = dependee->GetLocalGenerator()->GetGlobalGenerator(); @@ -499,7 +500,7 @@ cmExportInstallFileGenerator::FindNamespaces(cmGlobalGenerator* gg, } void cmExportInstallFileGenerator::ComplainAboutMissingTarget( - cmGeneratorTarget* depender, cmGeneratorTarget* dependee, + cmGeneratorTarget const* depender, cmGeneratorTarget const* dependee, std::vector<std::string> const& exportFiles) { std::ostringstream e; @@ -521,7 +522,7 @@ void cmExportInstallFileGenerator::ComplainAboutMissingTarget( } std::string cmExportInstallFileGenerator::InstallNameDir( - cmGeneratorTarget* target, const std::string& config) + cmGeneratorTarget const* target, const std::string& config) { std::string install_name_dir; diff --git a/Source/cmExportInstallFileGenerator.h b/Source/cmExportInstallFileGenerator.h index 2d8de9d83..5cec2e05e 100644 --- a/Source/cmExportInstallFileGenerator.h +++ b/Source/cmExportInstallFileGenerator.h @@ -63,13 +63,13 @@ protected: cmTargetExport const* targetExport) const; void HandleMissingTarget(std::string& link_libs, std::vector<std::string>& missingTargets, - cmGeneratorTarget* depender, + cmGeneratorTarget const* depender, cmGeneratorTarget* dependee) override; void ReplaceInstallPrefix(std::string& input) override; - void ComplainAboutMissingTarget(cmGeneratorTarget* depender, - cmGeneratorTarget* dependee, + void ComplainAboutMissingTarget(cmGeneratorTarget const* depender, + cmGeneratorTarget const* dependee, std::vector<std::string> const& exportFiles); std::pair<std::vector<std::string>, std::string> FindNamespaces( @@ -94,7 +94,7 @@ protected: ImportPropertyMap& properties, std::set<std::string>& importedLocations); - std::string InstallNameDir(cmGeneratorTarget* target, + std::string InstallNameDir(cmGeneratorTarget const* target, const std::string& config) override; cmInstallExportGenerator* IEGen; diff --git a/Source/cmExportLibraryDependenciesCommand.cxx b/Source/cmExportLibraryDependenciesCommand.cxx index 7f31dd218..8aec12b66 100644 --- a/Source/cmExportLibraryDependenciesCommand.cxx +++ b/Source/cmExportLibraryDependenciesCommand.cxx @@ -14,12 +14,12 @@ #include "cmGlobalGenerator.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" -#include "cmProperty.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" #include "cmTargetLinkLibraryType.h" +#include "cmValue.h" #include "cmake.h" class cmListFileBacktrace; @@ -96,7 +96,7 @@ static void FinalAction(cmMakefile& makefile, std::string const& filename, // Handle simple output name changes. This command is // deprecated so we do not support full target name // translation (which requires per-configuration info). - if (cmProp outname = libtgt->GetProperty("OUTPUT_NAME")) { + if (cmValue outname = libtgt->GetProperty("OUTPUT_NAME")) { lib = *outname; } } diff --git a/Source/cmExportTryCompileFileGenerator.cxx b/Source/cmExportTryCompileFileGenerator.cxx index cac60e14a..cbe3c4dc7 100644 --- a/Source/cmExportTryCompileFileGenerator.cxx +++ b/Source/cmExportTryCompileFileGenerator.cxx @@ -13,10 +13,10 @@ #include "cmGlobalGenerator.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" -#include "cmProperty.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmTarget.h" +#include "cmValue.h" cmExportTryCompileFileGenerator::cmExportTryCompileFileGenerator( cmGlobalGenerator* gg, const std::vector<std::string>& targets, @@ -60,7 +60,7 @@ std::string cmExportTryCompileFileGenerator::FindTargets( const std::string& propName, cmGeneratorTarget const* tgt, std::string const& language, std::set<cmGeneratorTarget const*>& emitted) { - cmProp prop = tgt->GetProperty(propName); + cmValue prop = tgt->GetProperty(propName); if (!prop) { return std::string(); } @@ -126,7 +126,7 @@ void cmExportTryCompileFileGenerator::PopulateProperties( } std::string cmExportTryCompileFileGenerator::InstallNameDir( - cmGeneratorTarget* target, const std::string& config) + cmGeneratorTarget const* target, const std::string& config) { std::string install_name_dir; diff --git a/Source/cmExportTryCompileFileGenerator.h b/Source/cmExportTryCompileFileGenerator.h index 6bf5781e8..127b8df15 100644 --- a/Source/cmExportTryCompileFileGenerator.h +++ b/Source/cmExportTryCompileFileGenerator.h @@ -36,7 +36,8 @@ protected: { } void HandleMissingTarget(std::string&, std::vector<std::string>&, - cmGeneratorTarget*, cmGeneratorTarget*) override + cmGeneratorTarget const*, + cmGeneratorTarget*) override { } @@ -44,7 +45,7 @@ protected: ImportPropertyMap& properties, std::set<const cmGeneratorTarget*>& emitted); - std::string InstallNameDir(cmGeneratorTarget* target, + std::string InstallNameDir(cmGeneratorTarget const* target, const std::string& config) override; private: diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx index df1426104..e2c54d77e 100644 --- a/Source/cmExtraCodeBlocksGenerator.cxx +++ b/Source/cmExtraCodeBlocksGenerator.cxx @@ -16,12 +16,12 @@ #include "cmGlobalGenerator.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" -#include "cmProperty.h" #include "cmRange.h" #include "cmSourceFile.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" #include "cmXMLWriter.h" #include "cmake.h" @@ -396,8 +396,8 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile( CbpUnit& cbpUnit = allFiles[fullPath]; cbpUnit.Targets.push_back(target.get()); } - } - default: // intended fallthrough + } break; + default: break; } } @@ -499,12 +499,12 @@ void cmExtraCodeBlocksGenerator::AppendTarget( if (target->GetType() == cmStateEnums::EXECUTABLE) { // Determine the directory where the executable target is created, and // set the working directory to this dir. - cmProp runtimeOutputDir = + cmValue runtimeOutputDir = makefile->GetDefinition("CMAKE_RUNTIME_OUTPUT_DIRECTORY"); if (runtimeOutputDir) { workingDir = *runtimeOutputDir; } else { - cmProp executableOutputDir = + cmValue executableOutputDir = makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH"); if (executableOutputDir) { workingDir = *executableOutputDir; diff --git a/Source/cmExtraCodeLiteGenerator.cxx b/Source/cmExtraCodeLiteGenerator.cxx index 549b08b4e..9e8ac5cf0 100644 --- a/Source/cmExtraCodeLiteGenerator.cxx +++ b/Source/cmExtraCodeLiteGenerator.cxx @@ -208,7 +208,7 @@ std::string cmExtraCodeLiteGenerator::CollectSourceFiles( case cmStateEnums::MODULE_LIBRARY: { projectType = "Dynamic Library"; } break; - default: // intended fallthrough + default: break; } @@ -233,8 +233,8 @@ std::string cmExtraCodeLiteGenerator::CollectSourceFiles( otherFiles.insert(fullPath); } } - } - default: // intended fallthrough + } break; + default: break; } return projectType; @@ -556,7 +556,8 @@ void cmExtraCodeLiteGenerator::CreateNewProjectFile( case cmStateEnums::SHARED_LIBRARY: case cmStateEnums::MODULE_LIBRARY: visualname = "lib" + targetName; - default: // intended fallthrough + break; + default: break; } xml.Attribute("Name", visualname); diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx index 672089c73..d9d5a4b50 100644 --- a/Source/cmExtraEclipseCDT4Generator.cxx +++ b/Source/cmExtraEclipseCDT4Generator.cxx @@ -19,13 +19,13 @@ #include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmMessageType.h" -#include "cmProperty.h" #include "cmSourceFile.h" #include "cmSourceGroup.h" #include "cmState.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" #include "cmXMLWriter.h" #include "cmake.h" @@ -189,7 +189,7 @@ void cmExtraEclipseCDT4Generator::CreateSettingsResourcePrefsFile() } fout << "eclipse.preferences.version=1\n"; - cmProp encoding = mf->GetDefinition("CMAKE_ECLIPSE_RESOURCE_ENCODING"); + cmValue encoding = mf->GetDefinition("CMAKE_ECLIPSE_RESOURCE_ENCODING"); if (encoding) { fout << "encoding/<project>=" << *encoding << '\n'; } @@ -244,7 +244,7 @@ void cmExtraEclipseCDT4Generator::AddEnvVar(std::ostream& out, const bool envVarSet = cmSystemTools::GetEnv(envVar, envVarValue); std::string cacheEntryName = cmStrCat("CMAKE_ECLIPSE_ENVVAR_", envVar); - cmProp cacheValue = lg.GetState()->GetInitializedCacheValue(cacheEntryName); + cmValue cacheValue = lg.GetState()->GetInitializedCacheValue(cacheEntryName); // now we have both, decide which one to use std::string valueToUse; @@ -415,7 +415,7 @@ void cmExtraEclipseCDT4Generator::CreateProjectFile() xml.Element("nature", n); } - if (cmProp extraNaturesProp = + if (cmValue extraNaturesProp = mf->GetState()->GetGlobalProperty("ECLIPSE_EXTRA_NATURES")) { std::vector<std::string> extraNatures = cmExpandedList(*extraNaturesProp); for (std::string const& n : extraNatures) { @@ -754,7 +754,7 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const emitted.clear(); for (const auto& lgen : this->GlobalGenerator->GetLocalGenerators()) { - if (cmProp cdefs = + if (cmValue cdefs = lgen->GetMakefile()->GetProperty("COMPILE_DEFINITIONS")) { // Expand the list. std::vector<std::string> defs; @@ -793,7 +793,7 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const } } // add system defined c macros - cmProp cDefs = + cmValue cDefs = mf->GetDefinition("CMAKE_EXTRA_GENERATOR_C_SYSTEM_DEFINED_MACROS"); if (this->CEnabled && cDefs) { // Expand the list. @@ -825,7 +825,7 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const } } // add system defined c++ macros - cmProp cxxDefs = + cmValue cxxDefs = mf->GetDefinition("CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_DEFINED_MACROS"); if (this->CXXEnabled && cxxDefs) { // Expand the list. @@ -1032,7 +1032,7 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const xml.EndElement(); // storageModule // Append additional cproject contents without applying any XML formatting - if (cmProp extraCProjectContents = + if (cmValue extraCProjectContents = mf->GetState()->GetGlobalProperty("ECLIPSE_EXTRA_CPROJECT_CONTENTS")) { fout << *extraCProjectContents; } diff --git a/Source/cmExtraKateGenerator.cxx b/Source/cmExtraKateGenerator.cxx index 9153119c4..eec43c473 100644 --- a/Source/cmExtraKateGenerator.cxx +++ b/Source/cmExtraKateGenerator.cxx @@ -13,11 +13,11 @@ #include "cmGlobalGenerator.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" -#include "cmProperty.h" #include "cmSourceFile.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" cmExtraKateGenerator::cmExtraKateGenerator() = default; @@ -128,7 +128,7 @@ void cmExtraKateGenerator::WriteTargets(const cmLocalGenerator& lg, // only add the "edit_cache" target if it's not ccmake, because // this will not work within the IDE if (targetName == "edit_cache") { - cmProp editCommand = + cmValue editCommand = localGen->GetMakefile()->GetDefinition("CMAKE_EDIT_COMMAND"); if (!editCommand || strstr(editCommand->c_str(), "ccmake") != nullptr) { diff --git a/Source/cmExtraSublimeTextGenerator.cxx b/Source/cmExtraSublimeTextGenerator.cxx index 52965bb57..fa93b04d2 100644 --- a/Source/cmExtraSublimeTextGenerator.cxx +++ b/Source/cmExtraSublimeTextGenerator.cxx @@ -17,11 +17,11 @@ #include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmMessageType.h" -#include "cmProperty.h" #include "cmSourceFile.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" #include "cmake.h" /* @@ -364,12 +364,12 @@ std::string cmExtraSublimeTextGenerator::ComputeFlagsForObject( language); const std::string COMPILE_FLAGS("COMPILE_FLAGS"); - if (cmProp cflags = source->GetProperty(COMPILE_FLAGS)) { + if (cmValue cflags = source->GetProperty(COMPILE_FLAGS)) { lg->AppendFlags(flags, genexInterpreter.Evaluate(*cflags, COMPILE_FLAGS)); } const std::string COMPILE_OPTIONS("COMPILE_OPTIONS"); - if (cmProp coptions = source->GetProperty(COMPILE_OPTIONS)) { + if (cmValue coptions = source->GetProperty(COMPILE_OPTIONS)) { lg->AppendCompileOptions( flags, genexInterpreter.Evaluate(*coptions, COMPILE_OPTIONS)); } @@ -393,14 +393,14 @@ std::string cmExtraSublimeTextGenerator::ComputeDefines( // Add preprocessor definitions for this target and configuration. lg->GetTargetDefines(target, config, language, defines); const std::string COMPILE_DEFINITIONS("COMPILE_DEFINITIONS"); - if (cmProp compile_defs = source->GetProperty(COMPILE_DEFINITIONS)) { + if (cmValue compile_defs = source->GetProperty(COMPILE_DEFINITIONS)) { lg->AppendDefines( defines, genexInterpreter.Evaluate(*compile_defs, COMPILE_DEFINITIONS)); } std::string defPropName = cmStrCat("COMPILE_DEFINITIONS_", cmSystemTools::UpperCase(config)); - if (cmProp config_compile_defs = source->GetProperty(defPropName)) { + if (cmValue config_compile_defs = source->GetProperty(defPropName)) { lg->AppendDefines( defines, genexInterpreter.Evaluate(*config_compile_defs, COMPILE_DEFINITIONS)); @@ -425,7 +425,7 @@ std::string cmExtraSublimeTextGenerator::ComputeIncludes( // Add include directories for this source file const std::string INCLUDE_DIRECTORIES("INCLUDE_DIRECTORIES"); - if (cmProp cincludes = source->GetProperty(INCLUDE_DIRECTORIES)) { + if (cmValue cincludes = source->GetProperty(INCLUDE_DIRECTORIES)) { lg->AppendIncludeDirectories( includes, genexInterpreter.Evaluate(*cincludes, INCLUDE_DIRECTORIES), *source); @@ -445,7 +445,7 @@ bool cmExtraSublimeTextGenerator::Open(const std::string& bindir, const std::string& projectName, bool dryRun) { - cmProp sublExecutable = + cmValue sublExecutable = this->GlobalGenerator->GetCMakeInstance()->GetCacheDefinition( "CMAKE_SUBLIMETEXT_EXECUTABLE"); if (!sublExecutable) { diff --git a/Source/cmFileAPICache.cxx b/Source/cmFileAPICache.cxx index ddae5273b..ba38ef798 100644 --- a/Source/cmFileAPICache.cxx +++ b/Source/cmFileAPICache.cxx @@ -10,8 +10,8 @@ #include <cm3p/json/value.h> #include "cmFileAPI.h" -#include "cmProperty.h" #include "cmState.h" +#include "cmValue.h" #include "cmake.h" namespace { @@ -95,7 +95,7 @@ Json::Value Cache::DumpEntryProperty(std::string const& name, { Json::Value property = Json::objectValue; property["name"] = prop; - cmProp p = this->State->GetCacheEntryProperty(name, prop); + cmValue p = this->State->GetCacheEntryProperty(name, prop); property["value"] = p ? *p : ""; return property; } diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx index a2b5460c1..147181e3f 100644 --- a/Source/cmFileAPICodemodel.cxx +++ b/Source/cmFileAPICodemodel.cxx @@ -41,7 +41,6 @@ #include "cmListFileCache.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" -#include "cmProperty.h" #include "cmSourceFile.h" #include "cmSourceGroup.h" #include "cmState.h" @@ -53,6 +52,7 @@ #include "cmTarget.h" #include "cmTargetDepend.h" #include "cmTargetExport.h" +#include "cmValue.h" #include "cmake.h" namespace { @@ -813,8 +813,7 @@ Json::Value CodemodelConfig::DumpProject(Project& p) Json::Value CodemodelConfig::DumpMinimumCMakeVersion(cmStateSnapshot s) { Json::Value minimumCMakeVersion; - if (std::string const* def = - s.GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION")) { + if (cmValue def = s.GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION")) { minimumCMakeVersion = Json::objectValue; minimumCMakeVersion["string"] = *def; } @@ -1188,10 +1187,10 @@ void Target::ProcessLanguage(std::string const& lang) { CompileData& cd = this->CompileDataMap[lang]; cd.Language = lang; - if (cmProp sysrootCompile = + if (cmValue sysrootCompile = this->GT->Makefile->GetDefinition("CMAKE_SYSROOT_COMPILE")) { cd.Sysroot = *sysrootCompile; - } else if (cmProp sysroot = + } else if (cmValue sysroot = this->GT->Makefile->GetDefinition("CMAKE_SYSROOT")) { cd.Sysroot = *sysroot; } @@ -1260,7 +1259,7 @@ CompileData Target::BuildCompileData(cmSourceFile* sf) fd.Language); const std::string COMPILE_FLAGS("COMPILE_FLAGS"); - if (cmProp cflags = sf->GetProperty(COMPILE_FLAGS)) { + if (cmValue cflags = sf->GetProperty(COMPILE_FLAGS)) { std::string flags = genexInterpreter.Evaluate(*cflags, COMPILE_FLAGS); fd.Flags.emplace_back(std::move(flags), JBTIndex()); } @@ -1354,7 +1353,7 @@ CompileData Target::BuildCompileData(cmSourceFile* sf) std::set<std::string> configFileDefines; const std::string defPropName = "COMPILE_DEFINITIONS_" + cmSystemTools::UpperCase(this->Config); - if (cmProp config_defs = sf->GetProperty(defPropName)) { + if (cmValue config_defs = sf->GetProperty(defPropName)) { lg->AppendDefines( configFileDefines, genexInterpreter.Evaluate(*config_defs, COMPILE_DEFINITIONS)); @@ -1740,10 +1739,10 @@ Json::Value Target::DumpLink() link["commandFragments"] = std::move(commandFragments); } } - if (cmProp sysrootLink = + if (cmValue sysrootLink = this->GT->Makefile->GetDefinition("CMAKE_SYSROOT_LINK")) { link["sysroot"] = this->DumpSysroot(*sysrootLink); - } else if (cmProp sysroot = + } else if (cmValue sysroot = this->GT->Makefile->GetDefinition("CMAKE_SYSROOT")) { link["sysroot"] = this->DumpSysroot(*sysroot); } @@ -1869,7 +1868,7 @@ Json::Value Target::DumpDependency(cmTargetDepend const& td) Json::Value Target::DumpFolder() { Json::Value folder; - if (cmProp f = this->GT->GetProperty("FOLDER")) { + if (cmValue f = this->GT->GetProperty("FOLDER")) { folder = Json::objectValue; folder["name"] = *f; } diff --git a/Source/cmFileAPIToolchains.cxx b/Source/cmFileAPIToolchains.cxx index 722c1145e..b3540c97b 100644 --- a/Source/cmFileAPIToolchains.cxx +++ b/Source/cmFileAPIToolchains.cxx @@ -11,9 +11,9 @@ #include "cmFileAPI.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" -#include "cmProperty.h" #include "cmState.h" #include "cmStringAlgorithms.h" +#include "cmValue.h" #include "cmake.h" namespace { @@ -136,7 +136,7 @@ void Toolchains::DumpToolchainVariable(cmMakefile const* mf, object[variable.ObjectKey] = jsonArray; } } else { - cmProp def = mf->GetDefinition(variableName); + cmValue def = mf->GetDefinition(variableName); if (def) { object[variable.ObjectKey] = *def; } diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index 0ad59c7b5..fd0595d88 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -31,6 +31,7 @@ #include "cmArgumentParser.h" #include "cmCMakePath.h" #include "cmCryptoHash.h" +#include "cmELF.h" #include "cmExecutionStatus.h" #include "cmFSPermissions.h" #include "cmFileCopier.h" @@ -46,7 +47,6 @@ #include "cmMessageType.h" #include "cmNewLineStyle.h" #include "cmPolicies.h" -#include "cmProperty.h" #include "cmRange.h" #include "cmRuntimeDependencyArchive.h" #include "cmState.h" @@ -54,6 +54,7 @@ #include "cmSubcommandTable.h" #include "cmSystemTools.h" #include "cmTimestamp.h" +#include "cmValue.h" #include "cmWorkingDirectory.h" #include "cmake.h" @@ -64,41 +65,8 @@ # include "cmFileLockResult.h" #endif -#if defined(CMake_USE_ELF_PARSER) -# include "cmELF.h" -#endif - -#if defined(_WIN32) -# include <windows.h> -#endif - namespace { -#if defined(_WIN32) -// libcurl doesn't support file:// urls for unicode filenames on Windows. -// Convert string from UTF-8 to ACP if this is a file:// URL. -std::string fix_file_url_windows(const std::string& url) -{ - std::string ret = url; - if (strncmp(url.c_str(), "file://", 7) == 0) { - std::wstring wurl = cmsys::Encoding::ToWide(url); - if (!wurl.empty()) { - int mblen = - WideCharToMultiByte(CP_ACP, 0, wurl.c_str(), -1, NULL, 0, NULL, NULL); - if (mblen > 0) { - std::vector<char> chars(mblen); - mblen = WideCharToMultiByte(CP_ACP, 0, wurl.c_str(), -1, &chars[0], - mblen, NULL, NULL); - if (mblen > 0) { - ret = &chars[0]; - } - } - } - } - return ret; -} -#endif - bool HandleWriteImpl(std::vector<std::string> const& args, bool append, cmExecutionStatus& status) { @@ -672,8 +640,9 @@ bool HandleGlobImpl(std::vector<std::string> const& args, bool recurse, case cmPolicies::NEW: g.RecurseThroughSymlinksOff(); break; - case cmPolicies::OLD: case cmPolicies::WARN: + CM_FALLTHROUGH; + case cmPolicies::OLD: g.RecurseThroughSymlinksOn(); break; } @@ -1242,8 +1211,12 @@ bool HandleReadElfCommand(std::vector<std::string> const& args, return false; } -#if defined(CMake_USE_ELF_PARSER) cmELF elf(fileNameArg.c_str()); + if (!elf) { + status.SetError(cmStrCat("READ_ELF given FILE \"", fileNameArg, + "\" that is not a valid ELF file.")); + return false; + } if (!arguments.RPath.empty()) { if (cmELF::StringEntry const* se_rpath = elf.GetRPath()) { @@ -1261,15 +1234,6 @@ bool HandleReadElfCommand(std::vector<std::string> const& args, } return true; -#else - std::string error = "ELF parser not available on this platform."; - if (arguments.Error.empty()) { - status.SetError(error); - return false; - } - status.GetMakefile().AddDefinition(arguments.Error, error); - return true; -#endif } bool HandleInstallCommand(std::vector<std::string> const& args, @@ -1803,7 +1767,7 @@ bool HandleDownloadCommand(std::vector<std::string> const& args, std::string logVar; std::string statusVar; bool tls_verify = status.GetMakefile().IsOn("CMAKE_TLS_VERIFY"); - cmProp cainfo = status.GetMakefile().GetDefinition("CMAKE_TLS_CAINFO"); + cmValue cainfo = status.GetMakefile().GetDefinition("CMAKE_TLS_CAINFO"); std::string netrc_level = status.GetMakefile().GetSafeDefinition("CMAKE_NETRC"); std::string netrc_file = @@ -1858,7 +1822,7 @@ bool HandleDownloadCommand(std::vector<std::string> const& args, } else if (*i == "TLS_CAINFO") { ++i; if (i != args.end()) { - cainfo = &(*i); + cainfo = cmValue(*i); } else { status.SetError("DOWNLOAD missing file value for TLS_CAINFO."); return false; @@ -1984,9 +1948,7 @@ bool HandleDownloadCommand(std::vector<std::string> const& args, } } -# if defined(_WIN32) - url = fix_file_url_windows(url); -# endif + url = cmCurlFixFileURL(url); ::CURL* curl; ::curl_global_init(CURL_GLOBAL_DEFAULT); @@ -2025,7 +1987,7 @@ bool HandleDownloadCommand(std::vector<std::string> const& args, // check to see if a CAINFO file has been specified // command arg comes first - std::string const& cainfo_err = cmCurlSetCAInfo(curl, cmToCStr(cainfo)); + std::string const& cainfo_err = cmCurlSetCAInfo(curl, cainfo); if (!cainfo_err.empty()) { status.SetError(cainfo_err); return false; @@ -2191,7 +2153,7 @@ bool HandleUploadCommand(std::vector<std::string> const& args, std::string statusVar; bool showProgress = false; bool tls_verify = status.GetMakefile().IsOn("CMAKE_TLS_VERIFY"); - cmProp cainfo = status.GetMakefile().GetDefinition("CMAKE_TLS_CAINFO"); + cmValue cainfo = status.GetMakefile().GetDefinition("CMAKE_TLS_CAINFO"); std::string userpwd; std::string netrc_level = status.GetMakefile().GetSafeDefinition("CMAKE_NETRC"); @@ -2244,7 +2206,7 @@ bool HandleUploadCommand(std::vector<std::string> const& args, } else if (*i == "TLS_CAINFO") { ++i; if (i != args.end()) { - cainfo = &(*i); + cainfo = cmValue(*i); } else { status.SetError("UPLOAD missing file value for TLS_CAINFO."); return false; @@ -2300,9 +2262,7 @@ bool HandleUploadCommand(std::vector<std::string> const& args, unsigned long file_size = cmsys::SystemTools::FileLength(filename); -# if defined(_WIN32) - url = fix_file_url_windows(url); -# endif + url = cmCurlFixFileURL(url); ::CURL* curl; ::curl_global_init(CURL_GLOBAL_DEFAULT); @@ -2345,7 +2305,7 @@ bool HandleUploadCommand(std::vector<std::string> const& args, // check to see if a CAINFO file has been specified // command arg comes first - std::string const& cainfo_err = cmCurlSetCAInfo(curl, cmToCStr(cainfo)); + std::string const& cainfo_err = cmCurlSetCAInfo(curl, cainfo); if (!cainfo_err.empty()) { status.SetError(cainfo_err); return false; @@ -3210,9 +3170,12 @@ bool HandleGetRuntimeDependenciesCommand(std::vector<std::string> const& args, archive.GetUnresolvedPaths().begin(), archive.GetUnresolvedPaths().end()); } else { - auto it = archive.GetUnresolvedPaths().begin(); - assert(it != archive.GetUnresolvedPaths().end()); - status.SetError(cmStrCat("Could not resolve file ", *it)); + std::ostringstream e; + e << "Could not resolve runtime dependencies:"; + for (auto const& path : archive.GetUnresolvedPaths()) { + e << "\n " << path; + } + status.SetError(e.str()); cmSystemTools::SetFatalErrorOccured(); return false; } diff --git a/Source/cmFileCopier.cxx b/Source/cmFileCopier.cxx index 237d234f8..63a4274c1 100644 --- a/Source/cmFileCopier.cxx +++ b/Source/cmFileCopier.cxx @@ -10,9 +10,9 @@ #include "cmFSPermissions.h" #include "cmFileTimes.h" #include "cmMakefile.h" -#include "cmProperty.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" #ifdef _WIN32 # include "cmsys/FStream.hxx" @@ -172,7 +172,7 @@ void cmFileCopier::DefaultDirectoryPermissions() bool cmFileCopier::GetDefaultDirectoryPermissions(mode_t** mode) { // check if default dir creation permissions were set - cmProp default_dir_install_permissions = this->Makefile->GetDefinition( + cmValue default_dir_install_permissions = this->Makefile->GetDefinition( "CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS"); if (cmNonempty(default_dir_install_permissions)) { std::vector<std::string> items = diff --git a/Source/cmFileCopier.h b/Source/cmFileCopier.h index 217d58d28..ee9872d9d 100644 --- a/Source/cmFileCopier.h +++ b/Source/cmFileCopier.h @@ -67,8 +67,9 @@ protected: bool InstallSymlinkChain(std::string& fromFile, std::string& toFile); bool InstallSymlink(const std::string& fromFile, const std::string& toFile); - bool InstallFile(const std::string& fromFile, const std::string& toFile, - MatchProperties match_properties); + virtual bool InstallFile(const std::string& fromFile, + const std::string& toFile, + MatchProperties match_properties); bool InstallDirectory(const std::string& source, const std::string& destination, MatchProperties match_properties); diff --git a/Source/cmFileInstaller.cxx b/Source/cmFileInstaller.cxx index c89be9628..9bfbd135c 100644 --- a/Source/cmFileInstaller.cxx +++ b/Source/cmFileInstaller.cxx @@ -3,7 +3,12 @@ #include "cmFileInstaller.h" +#include <map> #include <sstream> +#include <utility> + +#include <cm/string_view> +#include <cmext/string_view> #include "cm_sys_stat.h" @@ -12,12 +17,14 @@ #include "cmMakefile.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" using namespace cmFSPermissions; cmFileInstaller::cmFileInstaller(cmExecutionStatus& status) : cmFileCopier(status, "INSTALL") , InstallType(cmInstallType_FILES) + , InstallMode(cmInstallMode::COPY) , Optional(false) , MessageAlways(false) , MessageLazy(false) @@ -82,6 +89,93 @@ bool cmFileInstaller::Install(const std::string& fromFile, return this->cmFileCopier::Install(fromFile, toFile); } +bool cmFileInstaller::InstallFile(const std::string& fromFile, + const std::string& toFile, + MatchProperties match_properties) +{ + if (this->InstallMode == cmInstallMode::COPY) { + return this->cmFileCopier::InstallFile(fromFile, toFile, match_properties); + } + + std::string newFromFile; + + if (this->InstallMode == cmInstallMode::REL_SYMLINK || + this->InstallMode == cmInstallMode::REL_SYMLINK_OR_COPY || + this->InstallMode == cmInstallMode::SYMLINK || + this->InstallMode == cmInstallMode::SYMLINK_OR_COPY) { + // Try to get a relative path. + std::string toDir = cmSystemTools::GetParentDirectory(toFile); + newFromFile = cmSystemTools::ForceToRelativePath(toDir, fromFile); + + // Double check that we can restore the original path. + std::string reassembled = + cmSystemTools::CollapseFullPath(newFromFile, toDir); + if (!cmSystemTools::ComparePath(reassembled, fromFile)) { + if (this->InstallMode == cmInstallMode::SYMLINK || + this->InstallMode == cmInstallMode::SYMLINK_OR_COPY) { + // User does not mind, silently proceed with absolute path. + newFromFile = fromFile; + } else if (this->InstallMode == cmInstallMode::REL_SYMLINK_OR_COPY) { + // User expects a relative symbolic link or a copy. + // Since an absolute symlink won't do, copy instead. + return this->cmFileCopier::InstallFile(fromFile, toFile, + match_properties); + } else { + // We cannot meet user's expectation (REL_SYMLINK) + auto e = cmStrCat(this->Name, + " cannot determine relative path for symlink to \"", + newFromFile, "\" at \"", toFile, "\"."); + this->Status.SetError(e); + return false; + } + } + } else { + newFromFile = fromFile; // stick with absolute path + } + + // Compare the symlink value to that at the destination if not + // always installing. + bool copy = true; + if (!this->Always) { + std::string oldSymlinkTarget; + if (cmSystemTools::ReadSymlink(toFile, oldSymlinkTarget)) { + if (newFromFile == oldSymlinkTarget) { + copy = false; + } + } + } + + // Inform the user about this file installation. + this->ReportCopy(toFile, TypeLink, copy); + + if (copy) { + // Remove the destination file so we can always create the symlink. + cmSystemTools::RemoveFile(toFile); + + // Create destination directory if it doesn't exist + cmSystemTools::MakeDirectory(cmSystemTools::GetFilenamePath(toFile)); + + // Create the symlink. + if (!cmSystemTools::CreateSymlink(newFromFile, toFile)) { + if (this->InstallMode == cmInstallMode::ABS_SYMLINK_OR_COPY || + this->InstallMode == cmInstallMode::REL_SYMLINK_OR_COPY || + this->InstallMode == cmInstallMode::SYMLINK_OR_COPY) { + // Failed to create a symbolic link, fall back to copying. + return this->cmFileCopier::InstallFile(newFromFile, toFile, + match_properties); + } + + auto e = cmStrCat(this->Name, " cannot create symlink to \"", + newFromFile, "\" at \"", toFile, + "\": ", cmSystemTools::GetLastSystemError(), "\"."); + this->Status.SetError(e); + return false; + } + } + + return true; +} + void cmFileInstaller::DefaultFilePermissions() { this->cmFileCopier::DefaultFilePermissions(); @@ -141,6 +235,31 @@ bool cmFileInstaller::Parse(std::vector<std::string> const& args) return false; } + static const std::map<cm::string_view, cmInstallMode> install_mode_dict{ + { "ABS_SYMLINK"_s, cmInstallMode::ABS_SYMLINK }, + { "ABS_SYMLINK_OR_COPY"_s, cmInstallMode::ABS_SYMLINK_OR_COPY }, + { "REL_SYMLINK"_s, cmInstallMode::REL_SYMLINK }, + { "REL_SYMLINK_OR_COPY"_s, cmInstallMode::REL_SYMLINK_OR_COPY }, + { "SYMLINK"_s, cmInstallMode::SYMLINK }, + { "SYMLINK_OR_COPY"_s, cmInstallMode::SYMLINK_OR_COPY } + }; + + std::string install_mode; + cmSystemTools::GetEnv("CMAKE_INSTALL_MODE", install_mode); + if (install_mode.empty() || install_mode == "COPY"_s) { + this->InstallMode = cmInstallMode::COPY; + } else { + auto it = install_mode_dict.find(install_mode); + if (it != install_mode_dict.end()) { + this->InstallMode = it->second; + } else { + auto e = cmStrCat("Unrecognized value '", install_mode, + "' for environment variable CMAKE_INSTALL_MODE"); + this->Status.SetError(e); + return false; + } + } + return true; } diff --git a/Source/cmFileInstaller.h b/Source/cmFileInstaller.h index 3a905d320..3f6bd4542 100644 --- a/Source/cmFileInstaller.h +++ b/Source/cmFileInstaller.h @@ -8,6 +8,7 @@ #include <vector> #include "cmFileCopier.h" +#include "cmInstallMode.h" #include "cmInstallType.h" class cmExecutionStatus; @@ -19,6 +20,7 @@ struct cmFileInstaller : public cmFileCopier protected: cmInstallType InstallType; + cmInstallMode InstallMode; bool Optional; bool MessageAlways; bool MessageLazy; @@ -35,7 +37,8 @@ protected: bool ReportMissing(const std::string& fromFile) override; bool Install(const std::string& fromFile, const std::string& toFile) override; - + bool InstallFile(const std::string& fromFile, const std::string& toFile, + MatchProperties match_properties) override; bool Parse(std::vector<std::string> const& args) override; enum { diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx index 1038ac29e..a123e4408 100644 --- a/Source/cmFindBase.cxx +++ b/Source/cmFindBase.cxx @@ -13,13 +13,13 @@ #include "cmMakefile.h" #include "cmMessageType.h" #include "cmPolicies.h" -#include "cmProperty.h" #include "cmRange.h" #include "cmSearchPath.h" #include "cmState.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" #include "cmake.h" class cmExecutionStatus; @@ -301,9 +301,9 @@ void cmFindBase::FillUserGuessPath() bool cmFindBase::CheckForVariableDefined() { - if (cmProp value = this->Makefile->GetDefinition(this->VariableName)) { + if (cmValue value = this->Makefile->GetDefinition(this->VariableName)) { cmState* state = this->Makefile->GetState(); - cmProp cacheEntry = state->GetCacheEntryValue(this->VariableName); + cmValue cacheEntry = state->GetCacheEntryValue(this->VariableName); bool found = !cmIsNOTFOUND(*value); bool cached = cacheEntry != nullptr; auto cacheType = cached ? state->GetCacheEntryType(this->VariableName) @@ -311,7 +311,7 @@ bool cmFindBase::CheckForVariableDefined() if (cached && cacheType != cmStateEnums::UNINITIALIZED) { this->VariableType = cacheType; - if (const auto* hs = + if (const auto& hs = state->GetCacheEntryProperty(this->VariableName, "HELPSTRING")) { this->VariableDocumentation = *hs; } @@ -336,7 +336,7 @@ void cmFindBase::NormalizeFindResult() if (this->Makefile->GetPolicyStatus(cmPolicies::CMP0125) == cmPolicies::NEW) { // ensure the path returned by find_* command is absolute - const auto* existingValue = + const auto& existingValue = this->Makefile->GetDefinition(this->VariableName); std::string value; if (!existingValue->empty()) { @@ -358,8 +358,8 @@ void cmFindBase::NormalizeFindResult() // value. if (value != *existingValue || this->AlreadyInCacheWithoutMetaInfo) { this->Makefile->GetCMakeInstance()->AddCacheEntry( - this->VariableName, value.c_str(), - this->VariableDocumentation.c_str(), this->VariableType); + this->VariableName, value, this->VariableDocumentation.c_str(), + this->VariableType); if (this->Makefile->GetPolicyStatus(cmPolicies::CMP0126) == cmPolicies::NEW) { if (this->Makefile->IsNormalDefinitionSet(this->VariableName)) { diff --git a/Source/cmFindCommon.cxx b/Source/cmFindCommon.cxx index d2f96197b..bdc920772 100644 --- a/Source/cmFindCommon.cxx +++ b/Source/cmFindCommon.cxx @@ -11,9 +11,9 @@ #include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmMessageType.h" -#include "cmProperty.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" #include "cmake.h" cmFindCommon::PathGroup cmFindCommon::PathGroup::All("ALL"); @@ -183,7 +183,7 @@ void cmFindCommon::SelectDefaultSearchModes() }; for (auto const& path : search_paths) { - cmProp def = this->Makefile->GetDefinition(path.second); + cmValue def = this->Makefile->GetDefinition(path.second); if (def) { path.first = !cmIsOn(*def); } @@ -203,11 +203,11 @@ void cmFindCommon::RerootPaths(std::vector<std::string>& paths) return; } - cmProp sysroot = this->Makefile->GetDefinition("CMAKE_SYSROOT"); - cmProp sysrootCompile = + cmValue sysroot = this->Makefile->GetDefinition("CMAKE_SYSROOT"); + cmValue sysrootCompile = this->Makefile->GetDefinition("CMAKE_SYSROOT_COMPILE"); - cmProp sysrootLink = this->Makefile->GetDefinition("CMAKE_SYSROOT_LINK"); - cmProp rootPath = this->Makefile->GetDefinition("CMAKE_FIND_ROOT_PATH"); + cmValue sysrootLink = this->Makefile->GetDefinition("CMAKE_SYSROOT_LINK"); + cmValue rootPath = this->Makefile->GetDefinition("CMAKE_FIND_ROOT_PATH"); const bool noSysroot = !cmNonempty(sysroot); const bool noCompileSysroot = !cmNonempty(sysrootCompile); const bool noLinkSysroot = !cmNonempty(sysrootLink); @@ -234,7 +234,7 @@ void cmFindCommon::RerootPaths(std::vector<std::string>& paths) cmSystemTools::ConvertToUnixSlashes(r); } - cmProp stagePrefix = this->Makefile->GetDefinition("CMAKE_STAGING_PREFIX"); + cmValue stagePrefix = this->Makefile->GetDefinition("CMAKE_STAGING_PREFIX"); // Copy the original set of unrooted paths. std::vector<std::string> unrootedPaths = paths; diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx index 0cbe63773..ff04bab06 100644 --- a/Source/cmFindLibraryCommand.cxx +++ b/Source/cmFindLibraryCommand.cxx @@ -12,11 +12,11 @@ #include "cmGlobalGenerator.h" #include "cmMakefile.h" -#include "cmProperty.h" #include "cmState.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" class cmExecutionStatus; @@ -46,7 +46,7 @@ bool cmFindLibraryCommand::InitialPass(std::vector<std::string> const& argsIn) // add custom lib<qual> paths instead of using fixed lib32, lib64 or // libx32 - if (cmProp customLib = this->Makefile->GetDefinition( + if (cmValue customLib = this->Makefile->GetDefinition( "CMAKE_FIND_LIBRARY_CUSTOM_LIB_SUFFIX")) { this->AddArchitecturePaths(customLib->c_str()); } @@ -247,7 +247,7 @@ struct cmFindLibraryHelper cmStrCat(this->PrefixRegexStr, name, this->SuffixRegexStr); this->DebugSearches.FailedAt(path, regexName); } - }; + } void DebugLibraryFound(std::string const& name, std::string const& path) { @@ -256,9 +256,37 @@ struct cmFindLibraryHelper cmStrCat(this->PrefixRegexStr, name, this->SuffixRegexStr); this->DebugSearches.FoundAt(path, regexName); } - }; + } }; +namespace { + +std::string const& get_prefixes(cmMakefile* mf) +{ +#ifdef _WIN32 + static std::string defaultPrefix = ";lib"; +#else + static std::string defaultPrefix = "lib"; +#endif + cmValue prefixProp = mf->GetDefinition("CMAKE_FIND_LIBRARY_PREFIXES"); + return (prefixProp) ? *prefixProp : defaultPrefix; +} + +std::string const& get_suffixes(cmMakefile* mf) +{ +#ifdef _WIN32 + static std::string defaultSuffix = ".lib;.dll.a;.a"; +#elif defined(__APPLE__) + static std::string defaultSuffix = ".tbd;.dylib;.so;.a"; +#elif defined(__hpux) + static std::string defaultSuffix = ".sl;.so;.a"; +#else + static std::string defaultSuffix = ".so;.a"; +#endif + cmValue suffixProp = mf->GetDefinition("CMAKE_FIND_LIBRARY_SUFFIXES"); + return (suffixProp) ? *suffixProp : defaultSuffix; +} +} cmFindLibraryHelper::cmFindLibraryHelper(std::string debugName, cmMakefile* mf, cmFindBase const* base) : Makefile(mf) @@ -268,10 +296,9 @@ cmFindLibraryHelper::cmFindLibraryHelper(std::string debugName, cmMakefile* mf, this->GG = this->Makefile->GetGlobalGenerator(); // Collect the list of library name prefixes/suffixes to try. - std::string const& prefixes_list = - this->Makefile->GetRequiredDefinition("CMAKE_FIND_LIBRARY_PREFIXES"); - std::string const& suffixes_list = - this->Makefile->GetRequiredDefinition("CMAKE_FIND_LIBRARY_SUFFIXES"); + std::string const& prefixes_list = get_prefixes(this->Makefile); + std::string const& suffixes_list = get_suffixes(this->Makefile); + cmExpandList(prefixes_list, this->Prefixes, true); cmExpandList(suffixes_list, this->Suffixes, true); this->RegexFromList(this->PrefixRegexStr, this->Prefixes); diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index fba736eed..335ebbe4e 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -25,13 +25,13 @@ #include "cmMakefile.h" #include "cmMessageType.h" #include "cmPolicies.h" -#include "cmProperty.h" #include "cmRange.h" #include "cmSearchPath.h" #include "cmState.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" #include "cmVersion.h" #if defined(__HAIKU__) @@ -137,7 +137,7 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args) } // Lookup required version of CMake. - if (cmProp rv = + if (cmValue rv = this->Makefile->GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION")) { unsigned int v[3] = { 0, 0, 0 }; sscanf(rv->c_str(), "%u.%u.%u", &v[0], &v[1], &v[2]); @@ -148,7 +148,7 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args) this->DebugBuffer.clear(); // Lookup target architecture, if any. - if (cmProp arch = + if (cmValue arch = this->Makefile->GetDefinition("CMAKE_LIBRARY_ARCHITECTURE")) { this->LibraryArchitecture = *arch; } @@ -177,7 +177,7 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args) // Check if User Package Registry should be disabled // The `CMAKE_FIND_USE_PACKAGE_REGISTRY` has // priority over the deprecated CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY - if (cmProp def = + if (cmValue def = this->Makefile->GetDefinition("CMAKE_FIND_USE_PACKAGE_REGISTRY")) { this->NoUserRegistry = !cmIsOn(*def); } else if (this->Makefile->IsOn("CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY")) { @@ -187,7 +187,7 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args) // Check if System Package Registry should be disabled // The `CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY` has // priority over the deprecated CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY - if (cmProp def = this->Makefile->GetDefinition( + if (cmValue def = this->Makefile->GetDefinition( "CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY")) { this->NoSystemRegistry = !cmIsOn(*def); } else if (this->Makefile->IsOn( @@ -201,7 +201,7 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args) } // Check if Sorting should be enabled - if (cmProp so = + if (cmValue so = this->Makefile->GetDefinition("CMAKE_FIND_PACKAGE_SORT_ORDER")) { if (*so == "NAME") { @@ -212,7 +212,7 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args) this->SortOrder = None; } } - if (cmProp sd = + if (cmValue sd = this->Makefile->GetDefinition("CMAKE_FIND_PACKAGE_SORT_DIRECTION")) { this->SortDirection = (*sd == "ASC") ? Asc : Dec; } @@ -478,17 +478,35 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args) this->VersionMaxPatch, this->VersionMaxTweak); } + const std::string makePackageRequiredVar = + cmStrCat("CMAKE_REQUIRE_FIND_PACKAGE_", this->Name); + const bool makePackageRequiredSet = + this->Makefile->IsOn(makePackageRequiredVar); + if (makePackageRequiredSet) { + if (this->Required) { + this->Makefile->IssueMessage( + MessageType::WARNING, + cmStrCat("for module ", this->Name, + " already called with REQUIRED, thus ", + makePackageRequiredVar, " has no effect.")); + } else { + this->Required = true; + } + } + std::string disableFindPackageVar = cmStrCat("CMAKE_DISABLE_FIND_PACKAGE_", this->Name); if (this->Makefile->IsOn(disableFindPackageVar)) { if (this->Required) { this->SetError( - cmStrCat("for module ", this->Name, " called with REQUIRED, but ", - disableFindPackageVar, + cmStrCat("for module ", this->Name, + (makePackageRequiredSet + ? " was made REQUIRED with " + makePackageRequiredVar + : " called with REQUIRED, "), + " but ", disableFindPackageVar, " is enabled. A REQUIRED package cannot be disabled.")); return false; } - return true; } @@ -735,7 +753,7 @@ void cmFindPackageCommand::SetModuleVariables(const std::string& components) void cmFindPackageCommand::AddFindDefinition(const std::string& var, cm::string_view value) { - if (cmProp old = this->Makefile->GetDefinition(var)) { + if (cmValue old = this->Makefile->GetDefinition(var)) { this->OriginalDefs[var].exists = true; this->OriginalDefs[var].value = *old; } else { @@ -828,7 +846,7 @@ bool cmFindPackageCommand::HandlePackageMode( this->ConsideredConfigs.clear(); // Try to find the config file. - cmProp def = this->Makefile->GetDefinition(this->Variable); + cmValue def = this->Makefile->GetDefinition(this->Variable); // Try to load the config file if the directory is known bool fileFound = false; @@ -1188,7 +1206,7 @@ bool cmFindPackageCommand::ReadListFile(const std::string& f, void cmFindPackageCommand::AppendToFoundProperty(bool found) { std::vector<std::string> foundContents; - cmProp foundProp = + cmValue foundProp = this->Makefile->GetState()->GetGlobalProperty("PACKAGES_FOUND"); if (cmNonempty(foundProp)) { cmExpandList(*foundProp, foundContents, false); @@ -1200,7 +1218,7 @@ void cmFindPackageCommand::AppendToFoundProperty(bool found) } std::vector<std::string> notFoundContents; - cmProp notFoundProp = + cmValue notFoundProp = this->Makefile->GetState()->GetGlobalProperty("PACKAGES_NOT_FOUND"); if (cmNonempty(notFoundProp)) { cmExpandList(*notFoundProp, notFoundContents, false); diff --git a/Source/cmForEachCommand.cxx b/Source/cmForEachCommand.cxx index 4845a6d09..dcb362654 100644 --- a/Source/cmForEachCommand.cxx +++ b/Source/cmForEachCommand.cxx @@ -30,6 +30,7 @@ #include "cmRange.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" namespace { class cmForEachFunctionBlocker : public cmFunctionBlocker diff --git a/Source/cmFortranParser.h b/Source/cmFortranParser.h index 1b14d1777..70fe5374c 100644 --- a/Source/cmFortranParser.h +++ b/Source/cmFortranParser.h @@ -40,6 +40,8 @@ int cmFortranParser_GetOldStartcond(cmFortranParser* parser); /* Callbacks for parser. */ void cmFortranParser_Error(cmFortranParser* parser, const char* message); void cmFortranParser_RuleUse(cmFortranParser* parser, const char* module_name); +void cmFortranParser_RuleUseIntrinsic(cmFortranParser* parser, + const char* module_name); void cmFortranParser_RuleLineDirective(cmFortranParser* parser, const char* filename); void cmFortranParser_RuleInclude(cmFortranParser* parser, const char* name); @@ -99,6 +101,9 @@ public: std::set<std::string> Provides; std::set<std::string> Requires; + // Set of intrinsic modules. + std::set<std::string> Intrinsics; + // Set of files included in the translation unit. std::set<std::string> Includes; }; diff --git a/Source/cmFortranParserImpl.cxx b/Source/cmFortranParserImpl.cxx index 054a2a93e..efcc5bb2e 100644 --- a/Source/cmFortranParserImpl.cxx +++ b/Source/cmFortranParserImpl.cxx @@ -197,6 +197,19 @@ void cmFortranParser_RuleUse(cmFortranParser* parser, const char* module_name) parser->Info.Requires.insert(parser->ModName(mod_name)); } +void cmFortranParser_RuleUseIntrinsic(cmFortranParser* parser, + const char* module_name) +{ + if (parser->InPPFalseBranch) { + return; + } + + // syntax: "use, intrinsic:: module_name" + // requires: "module_name.mod" + std::string const& mod_name = cmSystemTools::LowerCase(module_name); + parser->Info.Intrinsics.insert(parser->ModName(mod_name)); +} + void cmFortranParser_RuleLineDirective(cmFortranParser* parser, const char* filename) { diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx index 217ebe5f9..c357ee145 100644 --- a/Source/cmGeneratorExpressionNode.cxx +++ b/Source/cmGeneratorExpressionNode.cxx @@ -37,7 +37,6 @@ #include "cmMessageType.h" #include "cmOutputConverter.h" #include "cmPolicies.h" -#include "cmProperty.h" #include "cmRange.h" #include "cmStandardLevelResolver.h" #include "cmState.h" @@ -46,6 +45,7 @@ #include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" +#include "cmValue.h" #include "cmake.h" std::string cmGeneratorExpressionNode::EvaluateDependentExpression( @@ -771,8 +771,7 @@ struct CompilerVersionNode : public cmGeneratorExpressionNode } return cmSystemTools::VersionCompare(cmSystemTools::OP_EQUAL, - parameters.front().c_str(), - compilerVersion.c_str()) + parameters.front(), compilerVersion) ? "1" : "0"; } @@ -830,8 +829,7 @@ struct VersionNode : public cmGeneratorExpressionNode const GeneratorExpressionContent* /*content*/, cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override { - return cmSystemTools::VersionCompare(Op, parameters.front().c_str(), - parameters[1].c_str()) + return cmSystemTools::VersionCompare(Op, parameters.front(), parameters[1]) ? "1" : "0"; } @@ -916,8 +914,8 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode } if (context->CurrentTarget && context->CurrentTarget->IsImported()) { - cmProp loc = nullptr; - cmProp imp = nullptr; + cmValue loc = nullptr; + cmValue imp = nullptr; std::string suffix; if (context->CurrentTarget->Target->GetMappedConfig(context->Config, loc, imp, suffix)) { @@ -927,7 +925,7 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode std::vector<std::string> mappedConfigs; std::string mapProp = cmStrCat( "MAP_IMPORTED_CONFIG_", cmSystemTools::UpperCase(context->Config)); - if (cmProp mapValue = context->CurrentTarget->GetProperty(mapProp)) { + if (cmValue mapValue = context->CurrentTarget->GetProperty(mapProp)) { cmExpandList(cmSystemTools::UpperCase(*mapValue), mappedConfigs); for (auto const& param : parameters) { @@ -1504,7 +1502,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode std::string result; bool haveProp = false; - if (cmProp p = target->GetProperty(propertyName)) { + if (cmValue p = target->GetProperty(propertyName)) { result = *p; haveProp = true; } else if (evaluatingLinkLibraries) { @@ -1654,8 +1652,8 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode std::vector<std::string> objects; if (gt->IsImported()) { - cmProp loc = nullptr; - cmProp imp = nullptr; + cmValue loc = nullptr; + cmValue imp = nullptr; std::string suffix; if (gt->Target->GetMappedConfig(context->Config, loc, imp, suffix)) { cmExpandList(*loc, objects); @@ -1777,7 +1775,7 @@ static const struct CompileFeaturesNode : public cmGeneratorExpressionNode testedFeatures[lang].push_back(p); if (availableFeatures.find(lang) == availableFeatures.end()) { - const char* featuresKnown = + cmValue featuresKnown = standardResolver.CompileFeaturesAvailable(lang, &error); if (!featuresKnown) { reportError(context, content->GetOriginalExpression(), error); @@ -1792,7 +1790,7 @@ static const struct CompileFeaturesNode : public cmGeneratorExpressionNode for (auto const& lit : testedFeatures) { std::vector<std::string> const& langAvailable = availableFeatures[lit.first]; - cmProp standardDefault = context->LG->GetMakefile()->GetDefinition( + cmValue standardDefault = context->LG->GetMakefile()->GetDefinition( "CMAKE_" + lit.first + "_STANDARD_DEFAULT"); for (std::string const& it : lit.second) { if (!cm::contains(langAvailable, it)) { @@ -1806,7 +1804,8 @@ static const struct CompileFeaturesNode : public cmGeneratorExpressionNode if (!standardResolver.HaveStandardAvailable(target, lit.first, context->Config, it)) { if (evalLL) { - cmProp l = target->GetLanguageStandard(lit.first, context->Config); + cmValue l = + target->GetLanguageStandard(lit.first, context->Config); if (!l) { l = standardDefault; } diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index f1ef130af..8033ef544 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -58,11 +58,11 @@ const cmsys::RegularExpression FrameworkRegularExpression( } template <> -cmProp cmTargetPropertyComputer::GetSources<cmGeneratorTarget>( +cmValue cmTargetPropertyComputer::GetSources<cmGeneratorTarget>( cmGeneratorTarget const* tgt, cmMessenger* /* messenger */, cmListFileBacktrace const& /* context */) { - return &tgt->GetSourcesProperty(); + return tgt->GetSourcesProperty(); } template <> @@ -145,12 +145,10 @@ private: class TargetPropertyEntryString : public cmGeneratorTarget::TargetPropertyEntry { public: - TargetPropertyEntryString(std::string propertyValue, - cmListFileBacktrace backtrace, + TargetPropertyEntryString(BT<std::string> propertyValue, cmLinkImplItem const& item = NoLinkImplItem) : cmGeneratorTarget::TargetPropertyEntry(item) , PropertyValue(std::move(propertyValue)) - , Backtrace(std::move(backtrace)) { } @@ -159,46 +157,46 @@ public: cmGeneratorExpressionDAGChecker*, std::string const&) const override { - return this->PropertyValue; + return this->PropertyValue.Value; } - cmListFileBacktrace GetBacktrace() const override { return this->Backtrace; } - std::string const& GetInput() const override { return this->PropertyValue; } + cmListFileBacktrace GetBacktrace() const override + { + return this->PropertyValue.Backtrace; + } + std::string const& GetInput() const override + { + return this->PropertyValue.Value; + } private: - std::string PropertyValue; - cmListFileBacktrace Backtrace; + BT<std::string> PropertyValue; }; std::unique_ptr<cmGeneratorTarget::TargetPropertyEntry> -CreateTargetPropertyEntry( - const std::string& propertyValue, - cmListFileBacktrace backtrace = cmListFileBacktrace(), - bool evaluateForBuildsystem = false) +CreateTargetPropertyEntry(const BT<std::string>& propertyValue, + bool evaluateForBuildsystem = false) { - if (cmGeneratorExpression::Find(propertyValue) != std::string::npos) { - cmGeneratorExpression ge(std::move(backtrace)); + if (cmGeneratorExpression::Find(propertyValue.Value) != std::string::npos) { + cmGeneratorExpression ge(propertyValue.Backtrace); std::unique_ptr<cmCompiledGeneratorExpression> cge = - ge.Parse(propertyValue); + ge.Parse(propertyValue.Value); cge->SetEvaluateForBuildsystem(evaluateForBuildsystem); return std::unique_ptr<cmGeneratorTarget::TargetPropertyEntry>( cm::make_unique<TargetPropertyEntryGenex>(std::move(cge))); } return std::unique_ptr<cmGeneratorTarget::TargetPropertyEntry>( - cm::make_unique<TargetPropertyEntryString>(propertyValue, - std::move(backtrace))); + cm::make_unique<TargetPropertyEntryString>(propertyValue)); } void CreatePropertyGeneratorExpressions( - cmStringRange entries, cmBacktraceRange backtraces, + cmBTStringRange entries, std::vector<std::unique_ptr<cmGeneratorTarget::TargetPropertyEntry>>& items, bool evaluateForBuildsystem = false) { - auto btIt = backtraces.begin(); - for (auto it = entries.begin(); it != entries.end(); ++it, ++btIt) { - items.push_back( - CreateTargetPropertyEntry(*it, *btIt, evaluateForBuildsystem)); + for (auto const& entry : entries) { + items.push_back(CreateTargetPropertyEntry(entry, evaluateForBuildsystem)); } } @@ -289,35 +287,27 @@ cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg) this->GlobalGenerator->ComputeTargetObjectDirectory(this); CreatePropertyGeneratorExpressions(t->GetIncludeDirectoriesEntries(), - t->GetIncludeDirectoriesBacktraces(), this->IncludeDirectoriesEntries); CreatePropertyGeneratorExpressions(t->GetCompileOptionsEntries(), - t->GetCompileOptionsBacktraces(), this->CompileOptionsEntries); CreatePropertyGeneratorExpressions(t->GetCompileFeaturesEntries(), - t->GetCompileFeaturesBacktraces(), this->CompileFeaturesEntries); CreatePropertyGeneratorExpressions(t->GetCompileDefinitionsEntries(), - t->GetCompileDefinitionsBacktraces(), this->CompileDefinitionsEntries); CreatePropertyGeneratorExpressions(t->GetLinkOptionsEntries(), - t->GetLinkOptionsBacktraces(), this->LinkOptionsEntries); CreatePropertyGeneratorExpressions(t->GetLinkDirectoriesEntries(), - t->GetLinkDirectoriesBacktraces(), this->LinkDirectoriesEntries); CreatePropertyGeneratorExpressions(t->GetPrecompileHeadersEntries(), - t->GetPrecompileHeadersBacktraces(), this->PrecompileHeadersEntries); CreatePropertyGeneratorExpressions(t->GetSourceEntries(), - t->GetSourceBacktraces(), this->SourceEntries, true); this->PolicyMap = t->GetPolicyMap(); @@ -332,7 +322,7 @@ cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg) cmGeneratorTarget::~cmGeneratorTarget() = default; -const std::string& cmGeneratorTarget::GetSourcesProperty() const +cmValue cmGeneratorTarget::GetSourcesProperty() const { std::vector<std::string> values; for (auto const& se : this->SourceEntries) { @@ -341,7 +331,7 @@ const std::string& cmGeneratorTarget::GetSourcesProperty() const static std::string value; value.clear(); value = cmJoin(values, ";"); - return value; + return cmValue(value); } cmGlobalGenerator* cmGeneratorTarget::GetGlobalGenerator() const @@ -366,7 +356,7 @@ const std::string& cmGeneratorTarget::GetName() const std::string cmGeneratorTarget::GetExportName() const { - cmProp exportName = this->GetProperty("EXPORT_NAME"); + cmValue exportName = this->GetProperty("EXPORT_NAME"); if (cmNonempty(exportName)) { if (!cmGeneratorExpression::IsValidTargetName(*exportName)) { @@ -381,9 +371,9 @@ std::string cmGeneratorTarget::GetExportName() const return this->GetName(); } -cmProp cmGeneratorTarget::GetProperty(const std::string& prop) const +cmValue cmGeneratorTarget::GetProperty(const std::string& prop) const { - if (cmProp result = cmTargetPropertyComputer::GetProperty( + if (cmValue result = cmTargetPropertyComputer::GetProperty( this, prop, this->Makefile->GetMessenger(), this->GetBacktrace())) { return result; } @@ -396,13 +386,7 @@ cmProp cmGeneratorTarget::GetProperty(const std::string& prop) const std::string const& cmGeneratorTarget::GetSafeProperty( std::string const& prop) const { - cmProp ret = this->GetProperty(prop); - if (ret) { - return *ret; - } - - static std::string const s_empty; - return s_empty; + return this->GetProperty(prop); } const char* cmGeneratorTarget::GetOutputTargetType( @@ -491,7 +475,7 @@ std::string cmGeneratorTarget::GetOutputName( std::string outName; for (std::string const& p : props) { - if (cmProp outNameProp = this->GetProperty(p)) { + if (cmValue outNameProp = this->GetProperty(p)) { outName = *outNameProp; break; } @@ -519,7 +503,7 @@ std::string cmGeneratorTarget::GetFilePrefix( const std::string& config, cmStateEnums::ArtifactType artifact) const { if (this->IsImported()) { - cmProp prefix = this->GetFilePrefixInternal(config, artifact); + cmValue prefix = this->GetFilePrefixInternal(config, artifact); return prefix ? *prefix : std::string(); } @@ -533,7 +517,7 @@ std::string cmGeneratorTarget::GetFileSuffix( const std::string& config, cmStateEnums::ArtifactType artifact) const { if (this->IsImported()) { - cmProp suffix = this->GetFileSuffixInternal(config, artifact); + cmValue suffix = this->GetFileSuffixInternal(config, artifact); return suffix ? *suffix : std::string(); } @@ -546,7 +530,7 @@ std::string cmGeneratorTarget::GetFileSuffix( std::string cmGeneratorTarget::GetFilePostfix(const std::string& config) const { - cmProp postfix = nullptr; + cmValue postfix = nullptr; std::string frameworkPostfix; if (!config.empty()) { std::string configProp = @@ -564,7 +548,7 @@ std::string cmGeneratorTarget::GetFilePostfix(const std::string& config) const // framework postfix. frameworkPostfix = this->GetFrameworkMultiConfigPostfix(config); if (!frameworkPostfix.empty()) { - postfix = &frameworkPostfix; + postfix = cmValue(frameworkPostfix); } } return postfix ? *postfix : std::string(); @@ -573,7 +557,7 @@ std::string cmGeneratorTarget::GetFilePostfix(const std::string& config) const std::string cmGeneratorTarget::GetFrameworkMultiConfigPostfix( const std::string& config) const { - cmProp postfix = nullptr; + cmValue postfix = nullptr; if (!config.empty()) { std::string configProp = cmStrCat("FRAMEWORK_MULTI_CONFIG_POSTFIX_", cmSystemTools::UpperCase(config)); @@ -588,7 +572,7 @@ std::string cmGeneratorTarget::GetFrameworkMultiConfigPostfix( return postfix ? *postfix : std::string(); } -cmProp cmGeneratorTarget::GetFilePrefixInternal( +cmValue cmGeneratorTarget::GetFilePrefixInternal( std::string const& config, cmStateEnums::ArtifactType artifact, const std::string& language) const { @@ -618,7 +602,7 @@ cmProp cmGeneratorTarget::GetFilePrefixInternal( } // Compute prefix value. - cmProp targetPrefix = + cmValue targetPrefix = (isImportedLibraryArtifact ? this->GetProperty("IMPORT_PREFIX") : this->GetProperty("PREFIX")); @@ -639,7 +623,7 @@ cmProp cmGeneratorTarget::GetFilePrefixInternal( return targetPrefix; } -cmProp cmGeneratorTarget::GetFileSuffixInternal( +cmValue cmGeneratorTarget::GetFileSuffixInternal( std::string const& config, cmStateEnums::ArtifactType artifact, const std::string& language) const { @@ -669,7 +653,7 @@ cmProp cmGeneratorTarget::GetFileSuffixInternal( } // Compute suffix value. - cmProp targetSuffix = + cmValue targetSuffix = (isImportedLibraryArtifact ? this->GetProperty("IMPORT_SUFFIX") : this->GetProperty("SUFFIX")); @@ -704,7 +688,8 @@ void cmGeneratorTarget::AddSourceCommon(const std::string& src, bool before) { this->SourceEntries.insert( before ? this->SourceEntries.begin() : this->SourceEntries.end(), - CreateTargetPropertyEntry(src, this->Makefile->GetBacktrace(), true)); + CreateTargetPropertyEntry( + BT<std::string>(src, this->Makefile->GetBacktrace()), true)); this->ClearSourcesCache(); } @@ -725,11 +710,13 @@ void cmGeneratorTarget::AddTracedSources(std::vector<std::string> const& srcs) void cmGeneratorTarget::AddIncludeDirectory(const std::string& src, bool before) { - this->Target->InsertInclude(src, this->Makefile->GetBacktrace(), before); + this->Target->InsertInclude( + BT<std::string>(src, this->Makefile->GetBacktrace()), before); this->IncludeDirectoriesEntries.insert( before ? this->IncludeDirectoriesEntries.begin() : this->IncludeDirectoriesEntries.end(), - CreateTargetPropertyEntry(src, this->Makefile->GetBacktrace(), true)); + CreateTargetPropertyEntry( + BT<std::string>(src, this->Makefile->GetBacktrace()), true)); } std::vector<cmSourceFile*> const* cmGeneratorTarget::GetSourceDepends( @@ -751,7 +738,7 @@ void handleSystemIncludesDep(cmLocalGenerator* lg, std::vector<std::string>& result, bool excludeImported, std::string const& language) { - if (cmProp dirs = + if (cmValue dirs = depTgt->GetProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES")) { cmExpandList(cmGeneratorExpression::Evaluate(*dirs, lg, config, headTarget, dagChecker, depTgt, language), @@ -761,7 +748,7 @@ void handleSystemIncludesDep(cmLocalGenerator* lg, return; } - if (cmProp dirs = depTgt->GetProperty("INTERFACE_INCLUDE_DIRECTORIES")) { + if (cmValue dirs = depTgt->GetProperty("INTERFACE_INCLUDE_DIRECTORIES")) { cmExpandList(cmGeneratorExpression::Evaluate(*dirs, lg, config, headTarget, dagChecker, depTgt, language), result); @@ -813,17 +800,17 @@ void cmGeneratorTarget::ComputeObjectMapping() } } -cmProp cmGeneratorTarget::GetFeature(const std::string& feature, - const std::string& config) const +cmValue cmGeneratorTarget::GetFeature(const std::string& feature, + const std::string& config) const { if (!config.empty()) { std::string featureConfig = cmStrCat(feature, '_', cmSystemTools::UpperCase(config)); - if (cmProp value = this->GetProperty(featureConfig)) { + if (cmValue value = this->GetProperty(featureConfig)) { return value; } } - if (cmProp value = this->GetProperty(feature)) { + if (cmValue value = this->GetProperty(feature)) { return value; } return this->LocalGenerator->GetFeature(feature, config); @@ -851,7 +838,7 @@ const char* cmGeneratorTarget::GetLinkPIEProperty( bool cmGeneratorTarget::IsIPOEnabled(std::string const& lang, std::string const& config) const { - cmProp feature = this->GetFeature("INTERPROCEDURAL_OPTIMIZATION", config); + cmValue feature = this->GetFeature("INTERPROCEDURAL_OPTIMIZATION", config); if (!cmIsOn(feature)) { // 'INTERPROCEDURAL_OPTIMIZATION' is off, no need to check policies @@ -959,23 +946,23 @@ BTs<std::string> const* cmGeneratorTarget::GetLanguageStandardProperty( cmStrCat(lang, "_STANDARD")); } -cmProp cmGeneratorTarget::GetLanguageStandard(std::string const& lang, - std::string const& config) const +cmValue cmGeneratorTarget::GetLanguageStandard(std::string const& lang, + std::string const& config) const { BTs<std::string> const* languageStandard = this->GetLanguageStandardProperty(lang, config); if (languageStandard) { - return &(languageStandard->Value); + return cmValue(languageStandard->Value); } return nullptr; } -cmProp cmGeneratorTarget::GetPropertyWithPairedLanguageSupport( +cmValue cmGeneratorTarget::GetPropertyWithPairedLanguageSupport( std::string const& lang, const char* suffix) const { - cmProp propertyValue = this->Target->GetProperty(cmStrCat(lang, suffix)); + cmValue propertyValue = this->Target->GetProperty(cmStrCat(lang, suffix)); if (!propertyValue) { // Check if we should use the value set by another language. if (lang == "OBJC") { @@ -988,7 +975,7 @@ cmProp cmGeneratorTarget::GetPropertyWithPairedLanguageSupport( return propertyValue; } -cmProp cmGeneratorTarget::GetLanguageExtensions(std::string const& lang) const +cmValue cmGeneratorTarget::GetLanguageExtensions(std::string const& lang) const { return this->GetPropertyWithPairedLanguageSupport(lang, "_EXTENSIONS"); } @@ -1150,6 +1137,7 @@ bool cmGeneratorTarget::IsInBuildSystem() const if (!this->SourceEntries.empty()) { return true; } + break; case cmStateEnums::UNKNOWN_LIBRARY: break; } @@ -1183,7 +1171,7 @@ const std::string& cmGeneratorTarget::GetLocationForBuild() const // Now handle the deprecated build-time configuration location. std::string const noConfig; location = this->GetDirectory(noConfig); - cmProp cfgid = this->Makefile->GetDefinition("CMAKE_CFG_INTDIR"); + cmValue cfgid = this->Makefile->GetDefinition("CMAKE_CFG_INTDIR"); if (cfgid && (*cfgid != ".")) { location += "/"; location += *cfgid; @@ -1343,7 +1331,7 @@ std::string cmGeneratorTarget::EvaluateInterfaceProperty( cmGeneratorTarget const* headTarget = context->HeadTarget ? context->HeadTarget : this; - if (cmProp p = this->GetProperty(prop)) { + if (cmValue p = this->GetProperty(prop)) { result = cmGeneratorExpressionNode::EvaluateDependentExpression( *p, context->LG, context, headTarget, &dagChecker, this); } @@ -1466,7 +1454,7 @@ void AddLangSpecificImplicitIncludeDirectories( auto* lg = dependency->GetLocalGenerator(); EvaluatedTargetPropertyEntry entry{ library, library.Backtrace }; - if (cmProp val = dependency->GetProperty(propertyName)) { + if (cmValue val = dependency->GetProperty(propertyName)) { entry.Values.emplace_back(*val); } else { if (mode == IncludeDirectoryFallBack::BINARY) { @@ -1681,9 +1669,9 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths( // for TARGET_OBJECTS instead for backwards compatibility with OLD // behavior of CMP0024 and CMP0026 only. - cmStringRange sourceEntries = this->Target->GetSourceEntries(); - for (std::string const& entry : sourceEntries) { - std::vector<std::string> items = cmExpandedList(entry); + cmBTStringRange sourceEntries = this->Target->GetSourceEntries(); + for (auto const& entry : sourceEntries) { + std::vector<std::string> items = cmExpandedList(entry.Value); for (std::string const& item : items) { if (cmHasLiteralPrefix(item, "$<TARGET_OBJECTS:") && item.back() == '>') { @@ -1998,12 +1986,12 @@ std::string cmGeneratorTarget::GetCompilePDBName( // Check for a per-configuration output directory target property. std::string configUpper = cmSystemTools::UpperCase(config); std::string configProp = cmStrCat("COMPILE_PDB_NAME_", configUpper); - cmProp config_name = this->GetProperty(configProp); + cmValue config_name = this->GetProperty(configProp); if (cmNonempty(config_name)) { return prefix + *config_name + ".pdb"; } - cmProp name = this->GetProperty("COMPILE_PDB_NAME"); + cmValue name = this->GetProperty("COMPILE_PDB_NAME"); if (cmNonempty(name)) { return prefix + *name + ".pdb"; } @@ -2142,34 +2130,29 @@ bool cmGeneratorTarget::IsChrpathUsed(const std::string& config) const return true; } -#if defined(CMake_USE_ELF_PARSER) || defined(CMake_USE_XCOFF_PARSER) // Enable if the rpath flag uses a separator and the target uses // binaries we know how to edit. std::string ll = this->GetLinkerLanguage(config); if (!ll.empty()) { std::string sepVar = cmStrCat("CMAKE_SHARED_LIBRARY_RUNTIME_", ll, "_FLAG_SEP"); - cmProp sep = this->Makefile->GetDefinition(sepVar); + cmValue sep = this->Makefile->GetDefinition(sepVar); if (cmNonempty(sep)) { // TODO: Add binary format check to ABI detection and get rid of // CMAKE_EXECUTABLE_FORMAT. - if (cmProp fmt = + if (cmValue fmt = this->Makefile->GetDefinition("CMAKE_EXECUTABLE_FORMAT")) { -# if defined(CMake_USE_ELF_PARSER) if (*fmt == "ELF") { return true; } -# endif -# if defined(CMake_USE_XCOFF_PARSER) +#if defined(CMake_USE_XCOFF_PARSER) if (*fmt == "XCOFF") { return true; } -# endif +#endif } } } -#endif - static_cast<void>(config); return false; } @@ -2188,6 +2171,21 @@ bool cmGeneratorTarget::IsImportedSharedLibWithoutSOName( bool cmGeneratorTarget::HasMacOSXRpathInstallNameDir( const std::string& config) const { + TargetPtrToBoolMap& cache = this->MacOSXRpathInstallNameDirCache[config]; + const auto lookup = cache.find(this->Target); + + if (lookup != cache.cend()) { + return lookup->second; + } + + const bool result = this->DetermineHasMacOSXRpathInstallNameDir(config); + cache[this->Target] = result; + return result; +} + +bool cmGeneratorTarget::DetermineHasMacOSXRpathInstallNameDir( + const std::string& config) const +{ bool install_name_is_rpath = false; bool macosx_rpath = false; @@ -2195,7 +2193,7 @@ bool cmGeneratorTarget::HasMacOSXRpathInstallNameDir( if (this->GetType() != cmStateEnums::SHARED_LIBRARY) { return false; } - cmProp install_name = this->GetProperty("INSTALL_NAME_DIR"); + cmValue install_name = this->GetProperty("INSTALL_NAME_DIR"); bool use_install_name = this->MacOSXUseInstallNameDir(); if (install_name && use_install_name && *install_name == "@rpath") { install_name_is_rpath = true; @@ -2253,7 +2251,7 @@ bool cmGeneratorTarget::MacOSXRpathInstallNameDirDefault() const return false; } - cmProp macosx_rpath_str = this->GetProperty("MACOSX_RPATH"); + cmValue macosx_rpath_str = this->GetProperty("MACOSX_RPATH"); if (macosx_rpath_str) { return this->GetPropertyAsBool("MACOSX_RPATH"); } @@ -2270,7 +2268,7 @@ bool cmGeneratorTarget::MacOSXRpathInstallNameDirDefault() const bool cmGeneratorTarget::MacOSXUseInstallNameDir() const { - cmProp build_with_install_name = + cmValue build_with_install_name = this->GetProperty("BUILD_WITH_INSTALL_NAME_DIR"); if (build_with_install_name) { return cmIsOn(*build_with_install_name); @@ -2363,7 +2361,7 @@ std::string cmGeneratorTarget::GetAppBundleDirectory( { std::string fpath = cmStrCat( this->GetFullName(config, cmStateEnums::RuntimeBinaryArtifact), '.'); - cmProp ext = this->GetProperty("BUNDLE_EXTENSION"); + cmValue ext = this->GetProperty("BUNDLE_EXTENSION"); fpath += (ext ? *ext : "app"); if (shouldAddContentLevel(level) && !this->Makefile->PlatformIsAppleEmbedded()) { @@ -2393,7 +2391,7 @@ std::string cmGeneratorTarget::GetCFBundleDirectory( std::string fpath = cmStrCat( this->GetOutputName(config, cmStateEnums::RuntimeBinaryArtifact), '.'); std::string ext; - if (cmProp p = this->GetProperty("BUNDLE_EXTENSION")) { + if (cmValue p = this->GetProperty("BUNDLE_EXTENSION")) { ext = *p; } else { if (this->IsXCTestOnApple()) { @@ -2418,7 +2416,7 @@ std::string cmGeneratorTarget::GetFrameworkDirectory( { std::string fpath = cmStrCat( this->GetOutputName(config, cmStateEnums::RuntimeBinaryArtifact), '.'); - cmProp ext = this->GetProperty("BUNDLE_EXTENSION"); + cmValue ext = this->GetProperty("BUNDLE_EXTENSION"); fpath += (ext ? *ext : "framework"); if (shouldAddFullLevel(level) && !this->Makefile->PlatformIsAppleEmbedded()) { @@ -2470,7 +2468,7 @@ std::string cmGeneratorTarget::GetInstallNameDirForInstallTree( { if (this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME")) { std::string dir; - cmProp install_name_dir = this->GetProperty("INSTALL_NAME_DIR"); + cmValue install_name_dir = this->GetProperty("INSTALL_NAME_DIR"); if (this->CanGenerateInstallNameDir(INSTALL_NAME_FOR_INSTALL)) { if (cmNonempty(install_name_dir)) { @@ -2519,7 +2517,7 @@ const std::string* cmGeneratorTarget::GetExportMacro() const if (this->GetType() == cmStateEnums::SHARED_LIBRARY || this->GetType() == cmStateEnums::MODULE_LIBRARY || this->IsExecutableWithExports()) { - if (cmProp custom_export_name = this->GetProperty("DEFINE_SYMBOL")) { + if (cmValue custom_export_name = this->GetProperty("DEFINE_SYMBOL")) { this->ExportMacro = *custom_export_name; } else { std::string in = cmStrCat(this->GetName(), "_EXPORTS"); @@ -2561,6 +2559,7 @@ public: } break; case cmPolicies::OLD: noMessage = true; + break; case cmPolicies::REQUIRED_IF_USED: case cmPolicies::REQUIRED_ALWAYS: case cmPolicies::NEW: @@ -2817,7 +2816,7 @@ std::string cmGeneratorTarget::GetEffectiveFolderName() const return effectiveFolder; } - cmProp targetFolder = this->GetProperty("FOLDER"); + cmValue targetFolder = this->GetProperty("FOLDER"); if (targetFolder) { effectiveFolder += *targetFolder; } @@ -3045,7 +3044,7 @@ void cmTargetTraceDependencies::Trace() this->CurrentEntry = &this->GeneratorTarget->SourceDepends[sf]; // Queue dependencies added explicitly by the user. - if (cmProp additionalDeps = sf->GetProperty("OBJECT_DEPENDS")) { + if (cmValue additionalDeps = sf->GetProperty("OBJECT_DEPENDS")) { std::vector<std::string> objDeps = cmExpandedList(*additionalDeps); for (std::string& objDep : objDeps) { if (cmSystemTools::FileIsFullPath(objDep)) { @@ -3243,7 +3242,7 @@ void cmGeneratorTarget::GetAppleArchs(const std::string& config, if (!this->Makefile->IsOn("APPLE")) { return; } - cmProp archs = nullptr; + cmValue archs = nullptr; if (!config.empty()) { std::string defVarName = cmStrCat("OSX_ARCHITECTURES_", cmSystemTools::UpperCase(config)); @@ -3263,13 +3262,14 @@ void cmGeneratorTarget::GetAppleArchs(const std::string& config, void cmGeneratorTarget::AddExplicitLanguageFlags(std::string& flags, cmSourceFile const& sf) const { - cmProp lang = sf.GetProperty("LANGUAGE"); + cmValue lang = sf.GetProperty("LANGUAGE"); if (!lang) { return; } switch (this->GetPolicyStatusCMP0119()) { case cmPolicies::WARN: + CM_FALLTHROUGH; case cmPolicies::OLD: // The OLD behavior is to not add explicit language flags. return; @@ -3568,6 +3568,7 @@ void processIncludeDirectories(cmGeneratorTarget const* tgt, } break; case cmPolicies::OLD: noMessage = true; + break; case cmPolicies::REQUIRED_IF_USED: case cmPolicies::REQUIRED_ALWAYS: case cmPolicies::NEW: @@ -3644,7 +3645,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories( // If this target has ISPC sources make sure to add the header // directory to other compilation units if (cm::contains(this->GetAllConfigCompileLanguages(), "ISPC")) { - if (cmProp val = this->GetProperty(propertyName)) { + if (cmValue val = this->GetProperty(propertyName)) { includes.emplace_back(*val); } else { includes.emplace_back(this->GetObjectDirectory(config)); @@ -3974,7 +3975,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileDefinitions( if (!config.empty()) { std::string configPropName = "COMPILE_DEFINITIONS_" + cmSystemTools::UpperCase(config); - cmProp configProp = this->GetProperty(configPropName); + cmValue configProp = this->GetProperty(configPropName); if (configProp) { switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0043)) { case cmPolicies::WARN: { @@ -4049,7 +4050,7 @@ std::string cmGeneratorTarget::GetPchHeader(const std::string& config, return std::string(); } const cmGeneratorTarget* generatorTarget = this; - cmProp pchReuseFrom = + cmValue pchReuseFrom = generatorTarget->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM"); const auto inserted = @@ -4090,8 +4091,10 @@ std::string cmGeneratorTarget::GetPchHeader(const std::string& config, const std::string filename_tmp = cmStrCat(filename, ".tmp"); if (!pchReuseFrom) { - cmProp pchPrologue = this->Makefile->GetDefinition("CMAKE_PCH_PROLOGUE"); - cmProp pchEpilogue = this->Makefile->GetDefinition("CMAKE_PCH_EPILOGUE"); + cmValue pchPrologue = + this->Makefile->GetDefinition("CMAKE_PCH_PROLOGUE"); + cmValue pchEpilogue = + this->Makefile->GetDefinition("CMAKE_PCH_EPILOGUE"); std::string firstHeaderOnDisk; { @@ -4105,7 +4108,7 @@ std::string cmGeneratorTarget::GetPchHeader(const std::string& config, if (this->GetGlobalGenerator()->IsXcode()) { file << "#ifndef CMAKE_SKIP_PRECOMPILE_HEADERS\n"; } - if (language == "CXX") { + if (language == "CXX" && !this->GetGlobalGenerator()->IsXcode()) { file << "#ifdef __cplusplus\n"; } for (auto const& header_bt : headers) { @@ -4123,7 +4126,7 @@ std::string cmGeneratorTarget::GetPchHeader(const std::string& config, firstHeaderOnDisk = header_bt.Value; } } - if (language == "CXX") { + if (language == "CXX" && !this->GetGlobalGenerator()->IsXcode()) { file << "#endif // __cplusplus\n"; } if (this->GetGlobalGenerator()->IsXcode()) { @@ -4162,7 +4165,7 @@ std::string cmGeneratorTarget::GetPchSource(const std::string& config, std::string& filename = inserted.first->second; const cmGeneratorTarget* generatorTarget = this; - cmProp pchReuseFrom = + cmValue pchReuseFrom = generatorTarget->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM"); if (pchReuseFrom) { generatorTarget = @@ -4260,7 +4263,7 @@ std::string cmGeneratorTarget::GetPchFile(const std::string& config, }; cmGeneratorTarget* generatorTarget = this; - cmProp pchReuseFrom = + cmValue pchReuseFrom = generatorTarget->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM"); if (pchReuseFrom) { generatorTarget = @@ -4466,6 +4469,13 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkOptions( // Last step: replace "LINKER:" prefixed elements by // actual linker wrapper + return this->ResolveLinkerWrapper(result, language); +} + +std::vector<BT<std::string>>& cmGeneratorTarget::ResolveLinkerWrapper( + std::vector<BT<std::string>>& result, const std::string& language) const +{ + // replace "LINKER:" prefixed elements by actual linker wrapper const std::string wrapper(this->Makefile->GetSafeDefinition( "CMAKE_" + language + (this->IsDeviceLink() ? "_DEVICE_LINKER_WRAPPER_FLAG" @@ -4549,7 +4559,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetStaticLibraryLinkOptions( nullptr, nullptr); EvaluatedTargetPropertyEntries entries; - if (cmProp linkOptions = this->GetProperty("STATIC_LIBRARY_OPTIONS")) { + if (cmValue linkOptions = this->GetProperty("STATIC_LIBRARY_OPTIONS")) { std::vector<std::string> options = cmExpandedList(*linkOptions); for (const auto& option : options) { std::unique_ptr<TargetPropertyEntry> entry = @@ -4700,7 +4710,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkDepends( nullptr); EvaluatedTargetPropertyEntries entries; - if (cmProp linkDepends = this->GetProperty("LINK_DEPENDS")) { + if (cmValue linkDepends = this->GetProperty("LINK_DEPENDS")) { std::vector<std::string> depends = cmExpandedList(*linkDepends); for (const auto& depend : depends) { std::unique_ptr<TargetPropertyEntry> entry = @@ -4781,7 +4791,7 @@ bool cmGeneratorTarget::ComputeCompileFeatures(std::string const& config) const } std::string key = cmStrCat(cmSystemTools::UpperCase(config), '-', lang); - cmProp currentLanguageStandard = this->GetLanguageStandard(lang, config); + cmValue currentLanguageStandard = this->GetLanguageStandard(lang, config); std::string newRequiredStandard; if (!standardResolver.GetNewRequiredStandard( @@ -4821,7 +4831,7 @@ bool cmGeneratorTarget::ComputeCompileFeatures( this->LanguageStandardMap[key] = *standardToCopy; generatorTargetLanguageStandard = &this->LanguageStandardMap[key]; } else { - cmProp defaultStandard = this->Makefile->GetDefinition( + cmValue defaultStandard = this->Makefile->GetDefinition( cmStrCat("CMAKE_", language.second, "_STANDARD_DEFAULT")); if (defaultStandard) { this->LanguageStandardMap[key] = BTs<std::string>(*defaultStandard); @@ -4924,8 +4934,8 @@ cmGeneratorTarget::Names cmGeneratorTarget::GetLibraryNames( } // Check for library version properties. - cmProp version = this->GetProperty("VERSION"); - cmProp soversion = this->GetProperty("SOVERSION"); + cmValue version = this->GetProperty("VERSION"); + cmValue soversion = this->GetProperty("SOVERSION"); if (!this->HasSOName(config) || this->Makefile->IsOn("CMAKE_PLATFORM_NO_VERSIONED_SONAME") || this->IsFrameworkOnApple()) { @@ -4966,11 +4976,11 @@ cmGeneratorTarget::Names cmGeneratorTarget::GetLibraryNames( // The library's soname. this->ComputeVersionedName(targetNames.SharedObject, prefix, targetNames.Base, suffix, targetNames.Output, - cmToCStr(soversion)); + soversion); // The library's real name on disk. this->ComputeVersionedName(targetNames.Real, prefix, targetNames.Base, - suffix, targetNames.Output, cmToCStr(version)); + suffix, targetNames.Output, version); } // The import library name. @@ -5003,10 +5013,10 @@ cmGeneratorTarget::Names cmGeneratorTarget::GetExecutableNames( // This versioning is supported only for executables and then only // when the platform supports symbolic links. #if defined(_WIN32) && !defined(__CYGWIN__) - const char* version = nullptr; + cmValue version; #else // Check for executable version properties. - const char* version = cmToCStr(this->GetProperty("VERSION")); + cmValue version = this->GetProperty("VERSION"); if (this->GetType() != cmStateEnums::EXECUTABLE || this->Makefile->IsOn("XCODE")) { version = nullptr; @@ -5030,7 +5040,7 @@ cmGeneratorTarget::Names cmGeneratorTarget::GetExecutableNames( #endif if (version) { targetNames.Real += "-"; - targetNames.Real += version; + targetNames.Real += *version; } #if defined(__CYGWIN__) targetNames.Real += suffix; @@ -5100,8 +5110,8 @@ void cmGeneratorTarget::GetFullNameInternal( // retrieve prefix and suffix std::string ll = this->GetLinkerLanguage(config); - cmProp targetPrefix = this->GetFilePrefixInternal(config, artifact, ll); - cmProp targetSuffix = this->GetFileSuffixInternal(config, artifact, ll); + cmValue targetPrefix = this->GetFilePrefixInternal(config, artifact, ll); + cmValue targetSuffix = this->GetFileSuffixInternal(config, artifact, ll); // The implib option is only allowed for shared libraries, module // libraries, and executables. @@ -5119,13 +5129,13 @@ void cmGeneratorTarget::GetFullNameInternal( if (this->IsFrameworkOnApple()) { fw_prefix = cmStrCat(this->GetFrameworkDirectory(config, ContentLevel), '/'); - targetPrefix = &fw_prefix; + targetPrefix = cmValue(fw_prefix); targetSuffix = nullptr; } if (this->IsCFBundleOnApple()) { fw_prefix = cmStrCat(this->GetCFBundleDirectory(config, FullLevel), '/'); - targetPrefix = &fw_prefix; + targetPrefix = cmValue(fw_prefix); targetSuffix = nullptr; } @@ -5141,13 +5151,13 @@ void cmGeneratorTarget::GetFullNameInternal( // EXECUTABLE_SUFFIX attribute. if (this->IsFrameworkOnApple() && this->GetGlobalGenerator()->GetName() == "Xcode") { - targetSuffix = &configPostfix; + targetSuffix = cmValue(configPostfix); } else { outBase += configPostfix; } // Name shared libraries with their version number on some platforms. - if (cmProp soversion = this->GetProperty("SOVERSION")) { + if (cmValue soversion = this->GetProperty("SOVERSION")) { if (this->GetType() == cmStateEnums::SHARED_LIBRARY && !isImportedLibraryArtifact && this->Makefile->IsOn("CMAKE_SHARED_LIBRARY_NAME_WITH_VERSION")) { @@ -5183,7 +5193,7 @@ std::string cmGeneratorTarget::GetPDBOutputName( props.emplace_back("PDB_NAME"); for (std::string const& p : props) { - if (cmProp outName = this->GetProperty(p)) { + if (cmValue outName = this->GetProperty(p)) { base = *outName; break; } @@ -5210,7 +5220,7 @@ std::string cmGeneratorTarget::GetPDBName(const std::string& config) const props.emplace_back("PDB_NAME"); for (std::string const& p : props) { - if (cmProp outName = this->GetProperty(p)) { + if (cmValue outName = this->GetProperty(p)) { base = *outName; break; } @@ -5293,7 +5303,7 @@ cmGeneratorTarget::GetTargetSourceFileFlags(const cmSourceFile* sf) const } else { // Handle the MACOSX_PACKAGE_LOCATION property on source files that // were not listed in one of the other lists. - if (cmProp location = sf->GetProperty("MACOSX_PACKAGE_LOCATION")) { + if (cmValue location = sf->GetProperty("MACOSX_PACKAGE_LOCATION")) { flags.MacFolder = location->c_str(); const bool stripResources = this->GlobalGenerator->ShouldStripResourcePath(this->Makefile); @@ -5323,7 +5333,7 @@ void cmGeneratorTarget::ConstructSourceFileFlags() const this->SourceFileFlagsConstructed = true; // Process public headers to mark the source files. - if (cmProp files = this->GetProperty("PUBLIC_HEADER")) { + if (cmValue files = this->GetProperty("PUBLIC_HEADER")) { std::vector<std::string> relFiles = cmExpandedList(*files); for (std::string const& relFile : relFiles) { if (cmSourceFile* sf = this->Makefile->GetSource(relFile)) { @@ -5336,7 +5346,7 @@ void cmGeneratorTarget::ConstructSourceFileFlags() const // Process private headers after public headers so that they take // precedence if a file is listed in both. - if (cmProp files = this->GetProperty("PRIVATE_HEADER")) { + if (cmValue files = this->GetProperty("PRIVATE_HEADER")) { std::vector<std::string> relFiles = cmExpandedList(*files); for (std::string const& relFile : relFiles) { if (cmSourceFile* sf = this->Makefile->GetSource(relFile)) { @@ -5348,7 +5358,7 @@ void cmGeneratorTarget::ConstructSourceFileFlags() const } // Mark sources listed as resources. - if (cmProp files = this->GetProperty("RESOURCE")) { + if (cmValue files = this->GetProperty("RESOURCE")) { std::vector<std::string> relFiles = cmExpandedList(*files); for (std::string const& relFile : relFiles) { if (cmSourceFile* sf = this->Makefile->GetSource(relFile)) { @@ -5376,7 +5386,7 @@ cmGeneratorTarget::GetCompatibleInterfaces(std::string const& config) const this->GetLinkImplementationClosure(config); for (cmGeneratorTarget const* li : deps) { #define CM_READ_COMPATIBLE_INTERFACE(X, x) \ - if (cmProp prop = li->GetProperty("COMPATIBLE_INTERFACE_" #X)) { \ + if (cmValue prop = li->GetProperty("COMPATIBLE_INTERFACE_" #X)) { \ std::vector<std::string> props; \ cmExpandList(*prop, props); \ compat.Props##x.insert(props.begin(), props.end()); \ @@ -5486,7 +5496,7 @@ void checkPropertyConsistency(cmGeneratorTarget const* depender, const std::string& config, CompatibleType t, PropertyType* /*unused*/) { - cmProp prop = dependee->GetProperty(propName); + cmValue prop = dependee->GetProperty(propName); if (!prop) { return; } @@ -5672,6 +5682,11 @@ std::string valueAsString<std::string>(std::string value) return value; } template <> +std::string valueAsString<cmValue>(cmValue value) +{ + return value ? value : std::string("(unset)"); +} +template <> std::string valueAsString<std::nullptr_t>(std::nullptr_t /*unused*/) { return "(unset)"; @@ -5721,7 +5736,7 @@ bool getTypedProperty<bool>(cmGeneratorTarget const* tgt, return tgt->GetPropertyAsBool(prop); } - cmProp value = tgt->GetProperty(prop); + cmValue value = tgt->GetProperty(prop); return cmIsOn(genexInterpreter->Evaluate(value ? *value : "", prop)); } @@ -5730,10 +5745,10 @@ const char* getTypedProperty<const char*>( cmGeneratorTarget const* tgt, const std::string& prop, cmGeneratorExpressionInterpreter* genexInterpreter) { - cmProp value = tgt->GetProperty(prop); + cmValue value = tgt->GetProperty(prop); if (genexInterpreter == nullptr) { - return cmToCStr(value); + return value.GetCStr(); } return genexInterpreter->Evaluate(value ? *value : "", prop).c_str(); @@ -5744,10 +5759,10 @@ std::string getTypedProperty<std::string>( cmGeneratorTarget const* tgt, const std::string& prop, cmGeneratorExpressionInterpreter* genexInterpreter) { - cmProp value = tgt->GetProperty(prop); + cmValue value = tgt->GetProperty(prop); if (genexInterpreter == nullptr) { - return valueAsString(cmToCStr(value)); + return valueAsString(value); } return genexInterpreter->Evaluate(value ? *value : "", prop); @@ -6121,7 +6136,7 @@ void cmGeneratorTarget::GetTargetVersion(const std::string& property, assert(this->GetType() != cmStateEnums::INTERFACE_LIBRARY); - if (cmProp version = this->GetProperty(property)) { + if (cmValue version = this->GetProperty(property)) { // Try to parse the version number and store the results that were // successfully parsed. int parsed_major; @@ -6149,12 +6164,12 @@ std::string cmGeneratorTarget::GetRuntimeLinkLibrary( { // This is activated by the presence of a default selection whether or // not it is overridden by a property. - cmProp runtimeLibraryDefault = this->Makefile->GetDefinition( + cmValue runtimeLibraryDefault = this->Makefile->GetDefinition( cmStrCat("CMAKE_", lang, "_RUNTIME_LIBRARY_DEFAULT")); if (!cmNonempty(runtimeLibraryDefault)) { return std::string(); } - cmProp runtimeLibraryValue = + cmValue runtimeLibraryValue = this->Target->GetProperty(cmStrCat(lang, "_RUNTIME_LIBRARY")); if (!runtimeLibraryValue) { runtimeLibraryValue = runtimeLibraryDefault; @@ -6175,12 +6190,21 @@ std::string cmGeneratorTarget::GetFortranModuleDirectory( return this->FortranModuleDirectory; } +bool cmGeneratorTarget::IsFortranBuildingInstrinsicModules() const +{ + if (cmValue prop = + this->GetProperty("Fortran_BUILDING_INSTRINSIC_MODULES")) { + return cmIsOn(*prop); + } + return false; +} + std::string cmGeneratorTarget::CreateFortranModuleDirectory( std::string const& working_dir) const { std::string mod_dir; std::string target_mod_dir; - if (cmProp prop = this->GetProperty("Fortran_MODULE_DIRECTORY")) { + if (cmValue prop = this->GetProperty("Fortran_MODULE_DIRECTORY")) { target_mod_dir = *prop; } else { std::string const& default_mod_dir = @@ -6189,7 +6213,7 @@ std::string cmGeneratorTarget::CreateFortranModuleDirectory( target_mod_dir = default_mod_dir; } } - cmProp moddir_flag = + cmValue moddir_flag = this->Makefile->GetDefinition("CMAKE_Fortran_MODDIR_FLAG"); if (!target_mod_dir.empty() && moddir_flag) { // Compute the full path to the module directory. @@ -6272,26 +6296,23 @@ std::string cmGeneratorTarget::GetFrameworkVersion() const { assert(this->GetType() != cmStateEnums::INTERFACE_LIBRARY); - if (cmProp fversion = this->GetProperty("FRAMEWORK_VERSION")) { + if (cmValue fversion = this->GetProperty("FRAMEWORK_VERSION")) { return *fversion; } - if (cmProp tversion = this->GetProperty("VERSION")) { + if (cmValue tversion = this->GetProperty("VERSION")) { return *tversion; } return "A"; } -void cmGeneratorTarget::ComputeVersionedName(std::string& vName, - std::string const& prefix, - std::string const& base, - std::string const& suffix, - std::string const& name, - const char* version) const +void cmGeneratorTarget::ComputeVersionedName( + std::string& vName, std::string const& prefix, std::string const& base, + std::string const& suffix, std::string const& name, cmValue version) const { vName = this->Makefile->IsOn("APPLE") ? (prefix + base) : name; if (version) { vName += "."; - vName += version; + vName += *version; } vName += this->Makefile->IsOn("APPLE") ? suffix : std::string(); } @@ -6358,16 +6379,16 @@ cm::optional<cmLinkItem> cmGeneratorTarget::LookupLinkItem( if (name == this->GetName() || name.empty()) { return maybeItem; } - maybeItem = this->ResolveLinkItem(name, bt, scope->LG); + maybeItem = this->ResolveLinkItem(BT<std::string>(name, bt), scope->LG); return maybeItem; } -void cmGeneratorTarget::ExpandLinkItems( - std::string const& prop, std::string const& value, std::string const& config, - cmGeneratorTarget const* headTarget, bool usage_requirements_only, - std::vector<cmLinkItem>& items, std::vector<cmLinkItem>& objects, - bool& hadHeadSensitiveCondition, bool& hadContextSensitiveCondition, - bool& hadLinkLanguageSensitiveCondition) const +void cmGeneratorTarget::ExpandLinkItems(std::string const& prop, + std::string const& value, + std::string const& config, + cmGeneratorTarget const* headTarget, + bool usage_requirements_only, + cmLinkInterface& iface) const { // Keep this logic in sync with ComputeLinkImplementationLibraries. cmGeneratorExpression ge; @@ -6389,24 +6410,27 @@ void cmGeneratorTarget::ExpandLinkItems( for (std::string const& lib : libs) { if (cm::optional<cmLinkItem> maybeItem = this->LookupLinkItem(lib, cge->GetBacktrace(), &scope)) { - if (!maybeItem->Target) { + cmLinkItem item = std::move(*maybeItem); + + if (!item.Target) { // Report explicitly linked object files separately. - std::string const& maybeObj = maybeItem->AsStr(); + std::string const& maybeObj = item.AsStr(); if (cmSystemTools::FileIsFullPath(maybeObj)) { cmSourceFile const* sf = mf->GetSource(maybeObj, cmSourceFileLocationKind::Known); if (sf && sf->GetPropertyAsBool("EXTERNAL_OBJECT")) { - objects.emplace_back(std::move(*maybeItem)); + iface.Objects.emplace_back(std::move(item)); continue; } } } - items.emplace_back(std::move(*maybeItem)); + + iface.Libraries.emplace_back(std::move(item)); } } - hadHeadSensitiveCondition = cge->GetHadHeadSensitiveCondition(); - hadContextSensitiveCondition = cge->GetHadContextSensitiveCondition(); - hadLinkLanguageSensitiveCondition = + iface.HadHeadSensitiveCondition = cge->GetHadHeadSensitiveCondition(); + iface.HadContextSensitiveCondition = cge->GetHadContextSensitiveCondition(); + iface.HadLinkLanguageSensitiveCondition = cge->GetHadLinkLanguageSensitiveCondition(); } @@ -6531,9 +6555,9 @@ void cmGeneratorTarget::ComputeLinkInterface( // How many repetitions are needed if this library has cyclic // dependencies? std::string propName = cmStrCat("LINK_INTERFACE_MULTIPLICITY", suffix); - if (cmProp config_reps = this->GetProperty(propName)) { + if (cmValue config_reps = this->GetProperty(propName)) { sscanf(config_reps->c_str(), "%u", &iface.Multiplicity); - } else if (cmProp reps = + } else if (cmValue reps = this->GetProperty("LINK_INTERFACE_MULTIPLICITY")) { sscanf(reps->c_str(), "%u", &iface.Multiplicity); } @@ -6690,14 +6714,14 @@ bool cmGeneratorTarget::ComputeOutputDir(const std::string& config, } // Select an output directory. - if (cmProp config_outdir = this->GetProperty(configProp)) { + if (cmValue config_outdir = this->GetProperty(configProp)) { // Use the user-specified per-configuration output directory. out = cmGeneratorExpression::Evaluate(*config_outdir, this->LocalGenerator, config, this); // Skip per-configuration subdirectory. conf.clear(); - } else if (cmProp outdir = this->GetProperty(propertyName)) { + } else if (cmValue outdir = this->GetProperty(propertyName)) { // Use the user-specified output directory. out = cmGeneratorExpression::Evaluate(*outdir, this->LocalGenerator, config, this); @@ -6760,14 +6784,14 @@ bool cmGeneratorTarget::ComputePDBOutputDir(const std::string& kind, } // Select an output directory. - if (cmProp config_outdir = this->GetProperty(configProp)) { + if (cmValue config_outdir = this->GetProperty(configProp)) { // Use the user-specified per-configuration output directory. out = cmGeneratorExpression::Evaluate(*config_outdir, this->LocalGenerator, config); // Skip per-configuration subdirectory. conf.clear(); - } else if (cmProp outdir = this->GetProperty(propertyName)) { + } else if (cmValue outdir = this->GetProperty(propertyName)) { // Use the user-specified output directory. out = cmGeneratorExpression::Evaluate(*outdir, this->LocalGenerator, config); @@ -6820,7 +6844,7 @@ bool cmGeneratorTarget::GetRPATH(const std::string& config, const std::string& prop, std::string& rpath) const { - cmProp value = this->GetProperty(prop); + cmValue value = this->GetProperty(prop); if (!value) { return false; } @@ -6845,7 +6869,7 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries( // An explicit list of interface libraries may be set for shared // libraries and executables that export symbols. - cmProp explicitLibraries = nullptr; + cmValue explicitLibraries = nullptr; std::string linkIfaceProp; bool const cmp0022NEW = (this->GetPolicyStatusCMP0022() != cmPolicies::OLD && this->GetPolicyStatusCMP0022() != cmPolicies::WARN); @@ -6874,7 +6898,7 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries( !this->PolicyWarnedCMP0022) { // Compare the explicitly set old link interface properties to the // preferred new link interface property one and warn if different. - cmProp newExplicitLibraries = + cmValue newExplicitLibraries = this->GetProperty("INTERFACE_LINK_LIBRARIES"); if (newExplicitLibraries && (*newExplicitLibraries != *explicitLibraries)) { @@ -6903,23 +6927,20 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries( return; } iface.Exists = true; + + // If CMP0022 is NEW then the plain tll signature sets the + // INTERFACE_LINK_LIBRARIES property. Even if the project + // clears it, the link interface is still explicit. iface.Explicit = cmp0022NEW || explicitLibraries; if (explicitLibraries) { // The interface libraries have been explicitly set. this->ExpandLinkItems(linkIfaceProp, *explicitLibraries, config, - headTarget, usage_requirements_only, iface.Libraries, - iface.Objects, iface.HadHeadSensitiveCondition, - iface.HadContextSensitiveCondition, - iface.HadLinkLanguageSensitiveCondition); - return; + headTarget, usage_requirements_only, iface); } - // If CMP0022 is NEW then the plain tll signature sets the - // INTERFACE_LINK_LIBRARIES, so if we get here then the project - // cleared the property explicitly and we should not fall back - // to the link implementation. - if (cmp0022NEW) { + // If the link interface is explicit, do not fall back to the link impl. + if (iface.Explicit) { return; } @@ -6932,22 +6953,15 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries( !this->PolicyWarnedCMP0022 && !usage_requirements_only) { // Compare the link implementation fallback link interface to the // preferred new link interface property and warn if different. - std::vector<cmLinkItem> ifaceLibs; - std::vector<cmLinkItem> ifaceObjects; + cmLinkInterface ifaceNew; static const std::string newProp = "INTERFACE_LINK_LIBRARIES"; - if (cmProp newExplicitLibraries = this->GetProperty(newProp)) { - bool hadHeadSensitiveConditionDummy = false; - bool hadContextSensitiveConditionDummy = false; - bool hadLinkLanguageSensitiveConditionDummy = false; + if (cmValue newExplicitLibraries = this->GetProperty(newProp)) { this->ExpandLinkItems(newProp, *newExplicitLibraries, config, - headTarget, usage_requirements_only, ifaceLibs, - ifaceObjects, hadHeadSensitiveConditionDummy, - hadContextSensitiveConditionDummy, - hadLinkLanguageSensitiveConditionDummy); + headTarget, usage_requirements_only, ifaceNew); } - if (ifaceLibs != iface.Libraries) { + if (ifaceNew.Libraries != iface.Libraries) { std::string oldLibraries = cmJoin(impl->Libraries, ";"); - std::string newLibraries = cmJoin(ifaceLibs, ";"); + std::string newLibraries = cmJoin(ifaceNew.Libraries, ";"); if (oldLibraries.empty()) { oldLibraries = "(empty)"; } @@ -7009,7 +7023,7 @@ std::vector<ValueType> computeImplicitLanguageTargets( std::string const& runtimeLibrary = currentTarget->GetRuntimeLinkLibrary(lang, config); - if (cmProp runtimeLinkOptions = currentTarget->Makefile->GetDefinition( + if (cmValue runtimeLinkOptions = currentTarget->Makefile->GetDefinition( "CMAKE_" + lang + "_RUNTIME_LIBRARIES_" + runtimeLibrary)) { std::vector<std::string> libsVec = cmExpandedList(*runtimeLinkOptions); result.reserve(libsVec.size()); @@ -7085,10 +7099,7 @@ const cmLinkInterface* cmGeneratorTarget::GetImportLinkInterface( iface.Multiplicity = info->Multiplicity; cmExpandList(info->Languages, iface.Languages); this->ExpandLinkItems(info->LibrariesProp, info->Libraries, config, - headTarget, usage_requirements_only, iface.Libraries, - iface.Objects, iface.HadHeadSensitiveCondition, - iface.HadContextSensitiveCondition, - iface.HadLinkLanguageSensitiveCondition); + headTarget, usage_requirements_only, iface); std::vector<std::string> deps = cmExpandedList(info->SharedDeps); LookupLinkItemScope scope{ this->LocalGenerator }; for (std::string const& dep : deps) { @@ -7150,8 +7161,8 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config, // Initialize members. info.NoSOName = false; - cmProp loc = nullptr; - cmProp imp = nullptr; + cmValue loc = nullptr; + cmValue imp = nullptr; std::string suffix; if (!this->Target->GetMappedConfig(desired_config, loc, imp, suffix)) { return; @@ -7160,7 +7171,7 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config, // Get the link interface. { std::string linkProp = "INTERFACE_LINK_LIBRARIES"; - cmProp propertyLibs = this->GetProperty(linkProp); + cmValue propertyLibs = this->GetProperty(linkProp); if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY) { if (!propertyLibs) { @@ -7193,9 +7204,9 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config, info.Location = *loc; } else { std::string impProp = cmStrCat("IMPORTED_LOCATION", suffix); - if (cmProp config_location = this->GetProperty(impProp)) { + if (cmValue config_location = this->GetProperty(impProp)) { info.Location = *config_location; - } else if (cmProp location = this->GetProperty("IMPORTED_LOCATION")) { + } else if (cmValue location = this->GetProperty("IMPORTED_LOCATION")) { info.Location = *location; } } @@ -7203,9 +7214,9 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config, // Get the soname. if (this->GetType() == cmStateEnums::SHARED_LIBRARY) { std::string soProp = cmStrCat("IMPORTED_SONAME", suffix); - if (cmProp config_soname = this->GetProperty(soProp)) { + if (cmValue config_soname = this->GetProperty(soProp)) { info.SOName = *config_soname; - } else if (cmProp soname = this->GetProperty("IMPORTED_SONAME")) { + } else if (cmValue soname = this->GetProperty("IMPORTED_SONAME")) { info.SOName = *soname; } } @@ -7213,9 +7224,9 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config, // Get the "no-soname" mark. if (this->GetType() == cmStateEnums::SHARED_LIBRARY) { std::string soProp = cmStrCat("IMPORTED_NO_SONAME", suffix); - if (cmProp config_no_soname = this->GetProperty(soProp)) { + if (cmValue config_no_soname = this->GetProperty(soProp)) { info.NoSOName = cmIsOn(*config_no_soname); - } else if (cmProp no_soname = this->GetProperty("IMPORTED_NO_SONAME")) { + } else if (cmValue no_soname = this->GetProperty("IMPORTED_NO_SONAME")) { info.NoSOName = cmIsOn(*no_soname); } } @@ -7226,9 +7237,9 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config, } else if (this->GetType() == cmStateEnums::SHARED_LIBRARY || this->IsExecutableWithExports()) { std::string impProp = cmStrCat("IMPORTED_IMPLIB", suffix); - if (cmProp config_implib = this->GetProperty(impProp)) { + if (cmValue config_implib = this->GetProperty(impProp)) { info.ImportLibrary = *config_implib; - } else if (cmProp implib = this->GetProperty("IMPORTED_IMPLIB")) { + } else if (cmValue implib = this->GetProperty("IMPORTED_IMPLIB")) { info.ImportLibrary = *implib; } } @@ -7237,9 +7248,9 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config, { std::string linkProp = cmStrCat("IMPORTED_LINK_DEPENDENT_LIBRARIES", suffix); - if (cmProp config_libs = this->GetProperty(linkProp)) { + if (cmValue config_libs = this->GetProperty(linkProp)) { info.SharedDeps = *config_libs; - } else if (cmProp libs = + } else if (cmValue libs = this->GetProperty("IMPORTED_LINK_DEPENDENT_LIBRARIES")) { info.SharedDeps = *libs; } @@ -7249,9 +7260,9 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config, if (this->LinkLanguagePropagatesToDependents()) { std::string linkProp = cmStrCat("IMPORTED_LINK_INTERFACE_LANGUAGES", suffix); - if (cmProp config_libs = this->GetProperty(linkProp)) { + if (cmValue config_libs = this->GetProperty(linkProp)) { info.Languages = *config_libs; - } else if (cmProp libs = + } else if (cmValue libs = this->GetProperty("IMPORTED_LINK_INTERFACE_LANGUAGES")) { info.Languages = *libs; } @@ -7260,9 +7271,9 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config, // Get information if target is managed assembly. { std::string linkProp = "IMPORTED_COMMON_LANGUAGE_RUNTIME"; - if (cmProp pc = this->GetProperty(linkProp + suffix)) { + if (cmValue pc = this->GetProperty(linkProp + suffix)) { info.Managed = this->CheckManagedType(*pc); - } else if (cmProp p = this->GetProperty(linkProp)) { + } else if (cmValue p = this->GetProperty(linkProp)) { info.Managed = this->CheckManagedType(*p); } } @@ -7271,9 +7282,9 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config, if (this->GetType() == cmStateEnums::STATIC_LIBRARY) { std::string linkProp = cmStrCat("IMPORTED_LINK_INTERFACE_MULTIPLICITY", suffix); - if (cmProp config_reps = this->GetProperty(linkProp)) { + if (cmValue config_reps = this->GetProperty(linkProp)) { sscanf(config_reps->c_str(), "%u", &info.Multiplicity); - } else if (cmProp reps = + } else if (cmValue reps = this->GetProperty("IMPORTED_LINK_INTERFACE_MULTIPLICITY")) { sscanf(reps->c_str(), "%u", &info.Multiplicity); } @@ -7381,9 +7392,9 @@ void cmGeneratorTarget::GetObjectLibrariesCMP0026( // there is no cmGeneratorTarget at configure-time, so search the SOURCES // for TARGET_OBJECTS instead for backwards compatibility with OLD // behavior of CMP0024 and CMP0026 only. - cmStringRange rng = this->Target->GetSourceEntries(); - for (std::string const& entry : rng) { - std::vector<std::string> files = cmExpandedList(entry); + cmBTStringRange rng = this->Target->GetSourceEntries(); + for (auto const& entry : rng) { + std::vector<std::string> files = cmExpandedList(entry.Value); for (std::string const& li : files) { if (cmHasLiteralPrefix(li, "$<TARGET_OBJECTS:") && li.back() == '>') { std::string objLibName = li.substr(17, li.size() - 18); @@ -7426,6 +7437,7 @@ std::string cmGeneratorTarget::CheckCMP0004(std::string const& item) const cm->IssueMessage(MessageType::AUTHOR_WARNING, w.str(), this->GetBacktrace()); } + CM_FALLTHROUGH; case cmPolicies::OLD: break; case cmPolicies::NEW: { @@ -7452,14 +7464,14 @@ std::string cmGeneratorTarget::CheckCMP0004(std::string const& item) const bool cmGeneratorTarget::IsDeprecated() const { - cmProp deprecation = this->GetProperty("DEPRECATION"); + cmValue deprecation = this->GetProperty("DEPRECATION"); return cmNonempty(deprecation); } std::string cmGeneratorTarget::GetDeprecation() const { // find DEPRECATION property - if (cmProp deprecation = this->GetProperty("DEPRECATION")) { + if (cmValue deprecation = this->GetProperty("DEPRECATION")) { return *deprecation; } return std::string(); @@ -7530,7 +7542,7 @@ bool cmGeneratorTarget::IsCSharpOnly() const std::set<std::string> languages = this->GetAllConfigCompileLanguages(); // Consider an explicit linker language property, but *not* the // computed linker language that may depend on linked targets. - cmProp linkLang = this->GetProperty("LINKER_LANGUAGE"); + cmValue linkLang = this->GetProperty("LINKER_LANGUAGE"); if (cmNonempty(linkLang)) { languages.insert(*linkLang); } @@ -7611,23 +7623,21 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries( { cmLocalGenerator const* lg = this->LocalGenerator; cmMakefile const* mf = lg->GetMakefile(); - cmStringRange entryRange = this->Target->GetLinkImplementationEntries(); - cmBacktraceRange btRange = this->Target->GetLinkImplementationBacktraces(); - cmBacktraceRange::const_iterator btIt = btRange.begin(); + cmBTStringRange entryRange = this->Target->GetLinkImplementationEntries(); // Collect libraries directly linked in this configuration. - for (cmStringRange::const_iterator le = entryRange.begin(), - end = entryRange.end(); - le != end; ++le, ++btIt) { + for (auto const& entry : entryRange) { std::vector<std::string> llibs; // Keep this logic in sync with ExpandLinkItems. cmGeneratorExpressionDAGChecker dagChecker(this, "LINK_LIBRARIES", nullptr, nullptr); - cmGeneratorExpression ge(*btIt); - std::unique_ptr<cmCompiledGeneratorExpression> const cge = ge.Parse(*le); + cmGeneratorExpression ge(entry.Backtrace); + std::unique_ptr<cmCompiledGeneratorExpression> const cge = + ge.Parse(entry.Value); cge->SetEvaluateForBuildsystem(true); std::string const& evaluated = cge->Evaluate(this->LocalGenerator, config, head, &dagChecker, nullptr, this->LinkerLanguage); + bool const fromGenex = evaluated != entry.Value; cmExpandList(evaluated, llibs); if (cge->GetHadHeadSensitiveCondition()) { impl.HadHeadSensitiveCondition = true; @@ -7665,6 +7675,7 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries( } break; case cmPolicies::OLD: noMessage = true; + break; case cmPolicies::REQUIRED_IF_USED: case cmPolicies::REQUIRED_ALWAYS: case cmPolicies::NEW: @@ -7685,7 +7696,8 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries( } // The entry is meant for this configuration. - cmLinkItem item = this->ResolveLinkItem(name, *btIt, lg); + cmLinkItem item = + this->ResolveLinkItem(BT<std::string>(name, entry.Backtrace), lg); if (!item.Target) { // Report explicitly linked object files separately. std::string const& maybeObj = item.AsStr(); @@ -7699,7 +7711,7 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries( } } - impl.Libraries.emplace_back(std::move(item), evaluated != *le); + impl.Libraries.emplace_back(std::move(item), fromGenex); } std::set<std::string> const& seenProps = cge->GetSeenTargetProperties(); @@ -7727,7 +7739,7 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries( } // Support OLD behavior for CMP0003. impl.WrongConfigLibraries.push_back( - this->ResolveLinkItem(name, cmListFileBacktrace())); + this->ResolveLinkItem(BT<std::string>(name))); } } } @@ -7753,16 +7765,16 @@ cmGeneratorTarget::TargetOrString cmGeneratorTarget::ResolveTargetReference( } cmLinkItem cmGeneratorTarget::ResolveLinkItem( - std::string const& name, cmListFileBacktrace const& bt) const + BT<std::string> const& name) const { - return this->ResolveLinkItem(name, bt, this->LocalGenerator); + return this->ResolveLinkItem(name, this->LocalGenerator); } -cmLinkItem cmGeneratorTarget::ResolveLinkItem(std::string const& name, - cmListFileBacktrace const& bt, +cmLinkItem cmGeneratorTarget::ResolveLinkItem(BT<std::string> const& name, cmLocalGenerator const* lg) const { - TargetOrString resolved = this->ResolveTargetReference(name, lg); + auto bt = name.Backtrace; + TargetOrString resolved = this->ResolveTargetReference(name.Value, lg); if (!resolved.Target) { return cmLinkItem(resolved.String, false, bt); @@ -7940,7 +7952,7 @@ cmGeneratorTarget::ManagedType cmGeneratorTarget::GetManagedType( } // Check for explicitly set clr target property. - if (cmProp clr = this->GetProperty("COMMON_LANGUAGE_RUNTIME")) { + if (cmValue clr = this->GetProperty("COMMON_LANGUAGE_RUNTIME")) { return this->CheckManagedType(*clr); } diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index 6d2aa85ed..990696307 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -19,8 +19,8 @@ #include "cmLinkItem.h" #include "cmListFileCache.h" #include "cmPolicies.h" -#include "cmProperty.h" #include "cmStateTypes.h" +#include "cmValue.h" class cmComputeLinkInformation; class cmCustomCommand; @@ -89,7 +89,7 @@ public: std::vector<std::string> GetPropertyKeys() const; //! Might return a nullptr if the property is not set or invalid - cmProp GetProperty(const std::string& prop) const; + cmValue GetProperty(const std::string& prop) const; //! Always returns a valid pointer std::string const& GetSafeProperty(std::string const& prop) const; bool GetPropertyAsBool(const std::string& prop) const; @@ -163,10 +163,10 @@ public: BTs<std::string> const* GetLanguageStandardProperty( std::string const& lang, std::string const& config) const; - cmProp GetLanguageStandard(std::string const& lang, - std::string const& config) const; + cmValue GetLanguageStandard(std::string const& lang, + std::string const& config) const; - cmProp GetLanguageExtensions(std::string const& lang) const; + cmValue GetLanguageExtensions(std::string const& lang) const; bool GetLanguageStandardRequired(std::string const& lang) const; @@ -187,8 +187,8 @@ public: void ComputeObjectMapping(); - cmProp GetFeature(const std::string& feature, - const std::string& config) const; + cmValue GetFeature(const std::string& feature, + const std::string& config) const; const char* GetLinkPIEProperty(const std::string& config) const; @@ -221,7 +221,7 @@ public: { this->PreviousState = target.SetDeviceLink(true); } - ~DeviceLinkSetter() { this->Target.SetDeviceLink(this->PreviousState); }; + ~DeviceLinkSetter() { this->Target.SetDeviceLink(this->PreviousState); } private: cmGeneratorTarget& Target; @@ -409,10 +409,8 @@ public: TargetOrString ResolveTargetReference(std::string const& name, cmLocalGenerator const* lg) const; - cmLinkItem ResolveLinkItem(std::string const& name, - cmListFileBacktrace const& bt) const; - cmLinkItem ResolveLinkItem(std::string const& name, - cmListFileBacktrace const& bt, + cmLinkItem ResolveLinkItem(BT<std::string> const& name) const; + cmLinkItem ResolveLinkItem(BT<std::string> const& name, cmLocalGenerator const* lg) const; // Compute the set of languages compiled by the target. This is @@ -498,6 +496,9 @@ public: std::vector<BT<std::string>> GetLinkOptions( std::string const& config, std::string const& language) const; + std::vector<BT<std::string>>& ResolveLinkerWrapper( + std::vector<BT<std::string>>& result, const std::string& language) const; + void GetStaticLibraryLinkOptions(std::vector<std::string>& result, const std::string& config, const std::string& language) const; @@ -832,8 +833,9 @@ public: std::string const& config) const; std::string GetFortranModuleDirectory(std::string const& working_dir) const; + bool IsFortranBuildingInstrinsicModules() const; - const std::string& GetSourcesProperty() const; + cmValue GetSourcesProperty() const; void AddISPCGeneratedHeader(std::string const& header, std::string const& config); @@ -864,6 +866,11 @@ private: mutable std::map<cmSourceFile const*, std::string> Objects; std::set<cmSourceFile const*> ExplicitObjectName; + using TargetPtrToBoolMap = std::unordered_map<cmTarget*, bool>; + mutable std::unordered_map<std::string, TargetPtrToBoolMap> + MacOSXRpathInstallNameDirCache; + bool DetermineHasMacOSXRpathInstallNameDir(const std::string& config) const; + // "config/language" is the key mutable std::map<std::string, std::vector<std::string>> SystemIncludesCache; @@ -877,12 +884,12 @@ private: bool NeedImportLibraryName(std::string const& config) const; - cmProp GetFilePrefixInternal(std::string const& config, - cmStateEnums::ArtifactType artifact, - const std::string& language = "") const; - cmProp GetFileSuffixInternal(std::string const& config, - cmStateEnums::ArtifactType artifact, - const std::string& language = "") const; + cmValue GetFilePrefixInternal(std::string const& config, + cmStateEnums::ArtifactType artifact, + const std::string& language = "") const; + cmValue GetFileSuffixInternal(std::string const& config, + cmStateEnums::ArtifactType artifact, + const std::string& language = "") const; std::string GetFullNameInternal(const std::string& config, cmStateEnums::ArtifactType artifact) const; @@ -901,8 +908,7 @@ private: void ComputeVersionedName(std::string& vName, std::string const& prefix, std::string const& base, std::string const& suffix, - std::string const& name, - const char* version) const; + std::string const& name, cmValue version) const; struct CompatibleInterfacesBase { @@ -1037,11 +1043,8 @@ private: std::string const& config, const cmGeneratorTarget* headTarget, bool usage_requirements_only, - std::vector<cmLinkItem>& items, - std::vector<cmLinkItem>& objects, - bool& hadHeadSensitiveCondition, - bool& hadContextSensitiveCondition, - bool& hadLinkLanguageSensitiveCondition) const; + cmLinkInterface& iface) const; + struct LookupLinkItemScope { cmLocalGenerator const* LG; @@ -1113,8 +1116,8 @@ private: mutable std::map<std::string, BTs<std::string>> LanguageStandardMap; - cmProp GetPropertyWithPairedLanguageSupport(std::string const& lang, - const char* suffix) const; + cmValue GetPropertyWithPairedLanguageSupport(std::string const& lang, + const char* suffix) const; void ComputeLinkImplementationRuntimeLibraries( const std::string& config, cmOptionalLinkImplementation& impl) const; diff --git a/Source/cmGetCMakePropertyCommand.cxx b/Source/cmGetCMakePropertyCommand.cxx index 79cbe443c..42bd206f7 100644 --- a/Source/cmGetCMakePropertyCommand.cxx +++ b/Source/cmGetCMakePropertyCommand.cxx @@ -7,9 +7,9 @@ #include "cmExecutionStatus.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" -#include "cmProperty.h" #include "cmState.h" #include "cmStringAlgorithms.h" +#include "cmValue.h" // cmGetCMakePropertyCommand bool cmGetCMakePropertyCommand(std::vector<std::string> const& args, @@ -24,12 +24,12 @@ bool cmGetCMakePropertyCommand(std::vector<std::string> const& args, std::string output = "NOTFOUND"; if (args[1] == "VARIABLES") { - if (cmProp varsProp = status.GetMakefile().GetProperty("VARIABLES")) { + if (cmValue varsProp = status.GetMakefile().GetProperty("VARIABLES")) { output = *varsProp; } } else if (args[1] == "MACROS") { output.clear(); - if (cmProp macrosProp = status.GetMakefile().GetProperty("MACROS")) { + if (cmValue macrosProp = status.GetMakefile().GetProperty("MACROS")) { output = *macrosProp; } } else if (args[1] == "COMPONENTS") { @@ -37,7 +37,7 @@ bool cmGetCMakePropertyCommand(std::vector<std::string> const& args, status.GetMakefile().GetGlobalGenerator()->GetInstallComponents(); output = cmJoin(*components, ";"); } else { - cmProp prop = nullptr; + cmValue prop = nullptr; if (!args[1].empty()) { prop = status.GetMakefile().GetState()->GetGlobalProperty(args[1]); } diff --git a/Source/cmGetDirectoryPropertyCommand.cxx b/Source/cmGetDirectoryPropertyCommand.cxx index 7fbd479ac..d892cfa75 100644 --- a/Source/cmGetDirectoryPropertyCommand.cxx +++ b/Source/cmGetDirectoryPropertyCommand.cxx @@ -7,12 +7,14 @@ #include "cmMakefile.h" #include "cmMessageType.h" #include "cmPolicies.h" -#include "cmProperty.h" #include "cmSystemTools.h" +#include "cmValue.h" namespace { void StoreResult(cmMakefile& makefile, std::string const& variable, const char* prop); +void StoreResult(cmMakefile& makefile, std::string const& variable, + cmValue prop); } // cmGetDirectoryPropertyCommand @@ -76,7 +78,6 @@ bool cmGetDirectoryPropertyCommand(std::vector<std::string> const& args, return false; } - const char* prop = nullptr; if (*i == "DEFINITIONS") { switch (status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0059)) { case cmPolicies::WARN: @@ -94,8 +95,7 @@ bool cmGetDirectoryPropertyCommand(std::vector<std::string> const& args, break; } } - prop = cmToCStr(dir->GetProperty(*i)); - StoreResult(status.GetMakefile(), variable, prop); + StoreResult(status.GetMakefile(), variable, dir->GetProperty(*i)); return true; } @@ -105,4 +105,9 @@ void StoreResult(cmMakefile& makefile, std::string const& variable, { makefile.AddDefinition(variable, prop ? prop : ""); } +void StoreResult(cmMakefile& makefile, std::string const& variable, + cmValue prop) +{ + makefile.AddDefinition(variable, prop); +} } diff --git a/Source/cmGetFilenameComponentCommand.cxx b/Source/cmGetFilenameComponentCommand.cxx index 40e8a05d6..abe7d32a7 100644 --- a/Source/cmGetFilenameComponentCommand.cxx +++ b/Source/cmGetFilenameComponentCommand.cxx @@ -4,10 +4,10 @@ #include "cmExecutionStatus.h" #include "cmMakefile.h" -#include "cmProperty.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" // cmGetFilenameComponentCommand bool cmGetFilenameComponentCommand(std::vector<std::string> const& args, @@ -22,7 +22,7 @@ bool cmGetFilenameComponentCommand(std::vector<std::string> const& args, // Check and see if the value has been stored in the cache // already, if so use that value if (args.size() >= 4 && args.back() == "CACHE") { - cmProp cacheValue = status.GetMakefile().GetDefinition(args.front()); + cmValue cacheValue = status.GetMakefile().GetDefinition(args.front()); if (cacheValue && !cmIsNOTFOUND(*cacheValue)) { return true; } diff --git a/Source/cmGetPropertyCommand.cxx b/Source/cmGetPropertyCommand.cxx index cb657f9ee..162860a00 100644 --- a/Source/cmGetPropertyCommand.cxx +++ b/Source/cmGetPropertyCommand.cxx @@ -2,6 +2,8 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmGetPropertyCommand.h" +#include <cstddef> + #include "cmExecutionStatus.h" #include "cmGlobalGenerator.h" #include "cmInstalledFile.h" @@ -18,6 +20,7 @@ #include "cmSystemTools.h" #include "cmTarget.h" #include "cmTest.h" +#include "cmValue.h" #include "cmake.h" class cmMessenger; @@ -32,10 +35,6 @@ enum OutType OutSet }; -// Implementation of result storage. -bool StoreResult(OutType infoType, cmMakefile& makefile, - const std::string& variable, const char* value); - // Implementation of each property type. bool HandleGlobalMode(cmExecutionStatus& status, const std::string& name, OutType infoType, const std::string& variable, @@ -253,8 +252,10 @@ bool cmGetPropertyCommand(std::vector<std::string> const& args, namespace { +// Implementation of result storage. +template <typename ValueType> bool StoreResult(OutType infoType, cmMakefile& makefile, - const std::string& variable, const char* value) + const std::string& variable, ValueType value) { if (infoType == OutSet) { makefile.AddDefinition(variable, value ? "1" : "0"); @@ -268,6 +269,12 @@ bool StoreResult(OutType infoType, cmMakefile& makefile, } return true; } +template <> +bool StoreResult(OutType infoType, cmMakefile& makefile, + const std::string& variable, std::nullptr_t value) +{ + return StoreResult(infoType, makefile, variable, cmValue(value)); +} bool HandleGlobalMode(cmExecutionStatus& status, const std::string& name, OutType infoType, const std::string& variable, @@ -280,9 +287,8 @@ bool HandleGlobalMode(cmExecutionStatus& status, const std::string& name, // Get the property. cmake* cm = status.GetMakefile().GetCMakeInstance(); - return StoreResult( - infoType, status.GetMakefile(), variable, - cmToCStr(cm->GetState()->GetGlobalProperty(propertyName))); + return StoreResult(infoType, status.GetMakefile(), variable, + cm->GetState()->GetGlobalProperty(propertyName)); } bool HandleDirectoryMode(cmExecutionStatus& status, const std::string& name, @@ -329,7 +335,7 @@ bool HandleDirectoryMode(cmExecutionStatus& status, const std::string& name, // Get the property. return StoreResult(infoType, status.GetMakefile(), variable, - cmToCStr(mf->GetProperty(propertyName))); + mf->GetProperty(propertyName)); } bool HandleTargetMode(cmExecutionStatus& status, const std::string& name, @@ -361,12 +367,11 @@ bool HandleTargetMode(cmExecutionStatus& status, const std::string& name, } cmListFileBacktrace bt = status.GetMakefile().GetBacktrace(); cmMessenger* messenger = status.GetMakefile().GetMessenger(); - cmProp prop = target->GetComputedProperty(propertyName, messenger, bt); + cmValue prop = target->GetComputedProperty(propertyName, messenger, bt); if (!prop) { prop = target->GetProperty(propertyName); } - return StoreResult(infoType, status.GetMakefile(), variable, - cmToCStr(prop)); + return StoreResult(infoType, status.GetMakefile(), variable, prop); } status.SetError(cmStrCat("could not find TARGET ", name, ". Perhaps it has not yet been created.")); @@ -391,7 +396,7 @@ bool HandleSourceMode(cmExecutionStatus& status, const std::string& name, if (cmSourceFile* sf = directory_makefile.GetOrCreateSource(source_file_absolute_path)) { return StoreResult(infoType, status.GetMakefile(), variable, - cmToCStr(sf->GetPropertyForUser(propertyName))); + sf->GetPropertyForUser(propertyName)); } status.SetError( cmStrCat("given SOURCE name that could not be found or created: ", @@ -428,9 +433,8 @@ bool HandleVariableMode(cmExecutionStatus& status, const std::string& name, return false; } - return StoreResult( - infoType, status.GetMakefile(), variable, - cmToCStr(status.GetMakefile().GetDefinition(propertyName))); + return StoreResult(infoType, status.GetMakefile(), variable, + status.GetMakefile().GetDefinition(propertyName)); } bool HandleCacheMode(cmExecutionStatus& status, const std::string& name, @@ -442,12 +446,12 @@ bool HandleCacheMode(cmExecutionStatus& status, const std::string& name, return false; } - cmProp value = nullptr; + cmValue value = nullptr; if (status.GetMakefile().GetState()->GetCacheEntryValue(name)) { value = status.GetMakefile().GetState()->GetCacheEntryProperty( name, propertyName); } - StoreResult(infoType, status.GetMakefile(), variable, cmToCStr(value)); + StoreResult(infoType, status.GetMakefile(), variable, value); return true; } diff --git a/Source/cmGetSourceFilePropertyCommand.cxx b/Source/cmGetSourceFilePropertyCommand.cxx index 5301b6618..40ae1126c 100644 --- a/Source/cmGetSourceFilePropertyCommand.cxx +++ b/Source/cmGetSourceFilePropertyCommand.cxx @@ -4,9 +4,9 @@ #include "cmExecutionStatus.h" #include "cmMakefile.h" -#include "cmProperty.h" #include "cmSetPropertyCommand.h" #include "cmSourceFile.h" +#include "cmValue.h" bool cmGetSourceFilePropertyCommand(std::vector<std::string> const& args, cmExecutionStatus& status) @@ -58,7 +58,7 @@ bool cmGetSourceFilePropertyCommand(std::vector<std::string> const& args, } if (sf) { - cmProp prop = nullptr; + cmValue prop = nullptr; if (!args[property_arg_index].empty()) { prop = sf->GetPropertyForUser(args[property_arg_index]); } diff --git a/Source/cmGetTargetPropertyCommand.cxx b/Source/cmGetTargetPropertyCommand.cxx index 78a17d2c3..12c82216b 100644 --- a/Source/cmGetTargetPropertyCommand.cxx +++ b/Source/cmGetTargetPropertyCommand.cxx @@ -10,8 +10,8 @@ #include "cmMakefile.h" #include "cmMessageType.h" #include "cmPolicies.h" -#include "cmProperty.h" #include "cmTarget.h" +#include "cmValue.h" class cmMessenger; @@ -42,7 +42,7 @@ bool cmGetTargetPropertyCommand(std::vector<std::string> const& args, } } } else if (!args[2].empty()) { - cmProp prop_cstr = nullptr; + cmValue prop_cstr = nullptr; cmListFileBacktrace bt = mf.GetBacktrace(); cmMessenger* messenger = mf.GetMessenger(); prop_cstr = tgt->GetComputedProperty(args[2], messenger, bt); @@ -62,6 +62,7 @@ bool cmGetTargetPropertyCommand(std::vector<std::string> const& args, case cmPolicies::WARN: issueMessage = true; e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0045) << "\n"; + CM_FALLTHROUGH; case cmPolicies::OLD: break; case cmPolicies::REQUIRED_IF_USED: @@ -69,6 +70,7 @@ bool cmGetTargetPropertyCommand(std::vector<std::string> const& args, case cmPolicies::NEW: issueMessage = true; messageType = MessageType::FATAL_ERROR; + break; } if (issueMessage) { e << "get_target_property() called with non-existent target \"" diff --git a/Source/cmGetTestPropertyCommand.cxx b/Source/cmGetTestPropertyCommand.cxx index cf8c1d5fa..a4ac9f686 100644 --- a/Source/cmGetTestPropertyCommand.cxx +++ b/Source/cmGetTestPropertyCommand.cxx @@ -5,6 +5,7 @@ #include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmTest.h" +#include "cmValue.h" bool cmGetTestPropertyCommand(std::vector<std::string> const& args, cmExecutionStatus& status) @@ -19,12 +20,12 @@ bool cmGetTestPropertyCommand(std::vector<std::string> const& args, cmMakefile& mf = status.GetMakefile(); cmTest* test = mf.GetTest(testName); if (test) { - const char* prop = nullptr; + cmValue prop; if (!args[1].empty()) { prop = test->GetProperty(args[1]); } if (prop) { - mf.AddDefinition(var, prop); + mf.AddDefinition(var, prop->c_str()); return true; } } diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx index 32238e4bd..47cefaeaa 100644 --- a/Source/cmGhsMultiTargetGenerator.cxx +++ b/Source/cmGhsMultiTargetGenerator.cxx @@ -19,7 +19,6 @@ #include "cmLocalGhsMultiGenerator.h" #include "cmMakefile.h" #include "cmOutputConverter.h" -#include "cmProperty.h" #include "cmSourceFile.h" #include "cmSourceFileLocation.h" #include "cmSourceGroup.h" @@ -29,6 +28,7 @@ #include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" +#include "cmValue.h" cmGhsMultiTargetGenerator::cmGhsMultiTargetGenerator(cmGeneratorTarget* target) : GeneratorTarget(target) @@ -43,7 +43,7 @@ cmGhsMultiTargetGenerator::cmGhsMultiTargetGenerator(cmGeneratorTarget* target) #endif { // Store the configuration name that is being used - if (cmProp config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE")) { + if (cmValue config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE")) { // Use the build type given by the user. this->ConfigName = *config; } else { @@ -376,7 +376,7 @@ void cmGhsMultiTargetGenerator::WriteCustomCommandsHelper( #ifdef _WIN32 std::string check_error = "if %errorlevel% neq 0 exit /b %errorlevel%"; #else - std::string check_error = "if [[ $? -ne 0 ]]; then exit 1; fi"; + std::string check_error = "if [ $? -ne 0 ]; then exit 1; fi"; #endif #ifdef _WIN32 @@ -453,7 +453,7 @@ void cmGhsMultiTargetGenerator::WriteSourceProperty( std::ostream& fout, const cmSourceFile* sf, std::string const& propName, std::string const& propFlag) { - cmProp prop = sf->GetProperty(propName); + cmValue prop = sf->GetProperty(propName); if (prop) { std::vector<std::string> list = cmExpandedList(*prop); for (const std::string& p : list) { @@ -705,7 +705,7 @@ void cmGhsMultiTargetGenerator::WriteCustomCommandLine( void cmGhsMultiTargetGenerator::WriteObjectLangOverride( std::ostream& fout, const cmSourceFile* sourceFile) { - cmProp rawLangProp = sourceFile->GetProperty("LANGUAGE"); + cmValue rawLangProp = sourceFile->GetProperty("LANGUAGE"); if (rawLangProp) { std::string sourceLangProp(*rawLangProp); std::string const& extension = sourceFile->GetExtension(); @@ -717,7 +717,7 @@ void cmGhsMultiTargetGenerator::WriteObjectLangOverride( bool cmGhsMultiTargetGenerator::DetermineIfIntegrityApp() { - if (cmProp p = this->GeneratorTarget->GetProperty("ghs_integrity_app")) { + if (cmValue p = this->GeneratorTarget->GetProperty("ghs_integrity_app")) { return cmIsOn(*p); } std::vector<cmSourceFile*> sources; diff --git a/Source/cmGlobalCommonGenerator.cxx b/Source/cmGlobalCommonGenerator.cxx index 9e5bbca00..3ae66f0ab 100644 --- a/Source/cmGlobalCommonGenerator.cxx +++ b/Source/cmGlobalCommonGenerator.cxx @@ -11,13 +11,12 @@ #include "cmGeneratorTarget.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" -#include "cmProperty.h" #include "cmStateDirectory.h" #include "cmStateSnapshot.h" #include "cmStateTypes.h" -#include "cmStringAlgorithms.h" - -class cmake; +#include "cmSystemTools.h" +#include "cmValue.h" +#include "cmake.h" cmGlobalCommonGenerator::cmGlobalCommonGenerator(cmake* cm) : cmGlobalGenerator(cm) @@ -48,7 +47,7 @@ cmGlobalCommonGenerator::ComputeDirectoryTargets() const DirectoryTarget::Target t; t.GT = gt.get(); const std::string EXCLUDE_FROM_ALL("EXCLUDE_FROM_ALL"); - if (cmProp exclude = gt->GetProperty(EXCLUDE_FROM_ALL)) { + if (cmValue exclude = gt->GetProperty(EXCLUDE_FROM_ALL)) { for (const std::string& config : configs) { cmGeneratorExpressionInterpreter genexInterpreter(lg.get(), config, gt.get()); @@ -95,3 +94,33 @@ bool cmGlobalCommonGenerator::IsExcludedFromAllInConfig( } return !t.ExcludedFromAllInConfigs.empty(); } + +std::string cmGlobalCommonGenerator::GetEditCacheCommand() const +{ + // If generating for an extra IDE, the edit_cache target cannot + // launch a terminal-interactive tool, so always use cmake-gui. + if (!this->GetExtraGeneratorName().empty()) { + return cmSystemTools::GetCMakeGUICommand(); + } + + // Use an internal cache entry to track the latest dialog used + // to edit the cache, and use that for the edit_cache target. + cmake* cm = this->GetCMakeInstance(); + std::string editCacheCommand = cm->GetCMakeEditCommand(); + if (!cm->GetCacheDefinition("CMAKE_EDIT_COMMAND") || + !editCacheCommand.empty()) { + if (this->SupportsDirectConsole() && editCacheCommand.empty()) { + editCacheCommand = cmSystemTools::GetCMakeCursesCommand(); + } + if (editCacheCommand.empty()) { + editCacheCommand = cmSystemTools::GetCMakeGUICommand(); + } + if (!editCacheCommand.empty()) { + cm->AddCacheEntry("CMAKE_EDIT_COMMAND", editCacheCommand, + "Path to cache edit program executable.", + cmStateEnums::INTERNAL); + } + } + cmValue edit_cmd = cm->GetCacheDefinition("CMAKE_EDIT_COMMAND"); + return edit_cmd ? *edit_cmd : std::string(); +} diff --git a/Source/cmGlobalCommonGenerator.h b/Source/cmGlobalCommonGenerator.h index 2aa9d2782..fed9ce81b 100644 --- a/Source/cmGlobalCommonGenerator.h +++ b/Source/cmGlobalCommonGenerator.h @@ -42,4 +42,9 @@ public: std::map<std::string, DirectoryTarget> ComputeDirectoryTargets() const; bool IsExcludedFromAllInConfig(const DirectoryTarget::Target& t, const std::string& config); + +protected: + virtual bool SupportsDirectConsole() const { return true; } + const char* GetEditCacheTargetName() const override { return "edit_cache"; } + std::string GetEditCacheCommand() const override; }; diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 919377812..9914902ef 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -44,12 +44,12 @@ #include "cmMakefile.h" #include "cmMessageType.h" #include "cmPolicies.h" -#include "cmProperty.h" #include "cmRange.h" #include "cmSourceFile.h" #include "cmState.h" #include "cmStateDirectory.h" #include "cmStateTypes.h" +#include "cmValue.h" #include "cmVersion.h" #include "cmWorkingDirectory.h" #include "cmake.h" @@ -199,7 +199,7 @@ std::string cmGlobalGenerator::SelectMakeProgram( { std::string makeProgram = inMakeProgram; if (cmIsOff(makeProgram)) { - cmProp makeProgramCSTR = + cmValue makeProgramCSTR = this->CMakeInstance->GetCacheDefinition("CMAKE_MAKE_PROGRAM"); if (cmIsOff(makeProgramCSTR)) { makeProgram = makeDefault; @@ -235,14 +235,14 @@ void cmGlobalGenerator::ResolveLanguageCompiler(const std::string& lang, if (!optional && (path.empty() || !cmSystemTools::FileExists(path))) { return; } - cmProp cname = + cmValue cname = this->GetCMakeInstance()->GetState()->GetInitializedCacheValue(langComp); // Split compiler from arguments std::vector<std::string> cnameArgVec; if (cname && !cname->empty()) { cmExpandList(*cname, cnameArgVec); - cname = &cnameArgVec.front(); + cname = cmValue(cnameArgVec.front()); } std::string changeVars; @@ -258,7 +258,7 @@ void cmGlobalGenerator::ResolveLanguageCompiler(const std::string& lang, cmSystemTools::ConvertToUnixSlashes(cnameString); cmSystemTools::ConvertToUnixSlashes(pathString); if (cnameString != pathString) { - cmProp cvars = this->GetCMakeInstance()->GetState()->GetGlobalProperty( + cmValue cvars = this->GetCMakeInstance()->GetState()->GetGlobalProperty( "__CMAKE_DELETE_CACHE_CHANGE_VARS_"); if (cvars) { changeVars += *cvars; @@ -498,6 +498,18 @@ bool cmGlobalGenerator::CheckLanguages( void cmGlobalGenerator::EnableLanguage( std::vector<std::string> const& languages, cmMakefile* mf, bool optional) { + if (!this->IsMultiConfig()) { + std::string envBuildType; + if (!mf->GetDefinition("CMAKE_BUILD_TYPE") && + cmSystemTools::GetEnv("CMAKE_BUILD_TYPE", envBuildType)) { + mf->AddCacheDefinition( + "CMAKE_BUILD_TYPE", envBuildType, + "Choose the type of build. Options include: empty, " + "Debug, Release, RelWithDebInfo, MinSizeRel.", + cmStateEnums::STRING); + } + } + if (languages.empty()) { cmSystemTools::Error("EnableLanguage must have a lang specified!"); cmSystemTools::SetFatalErrorOccured(); @@ -581,16 +593,6 @@ void cmGlobalGenerator::EnableLanguage( } } - if (readCMakeSystem) { - // Find the native build tool for this generator. - // This has to be done early so that MSBuild can be used to examine the - // cross-compilation environment. - if (this->GetFindMakeProgramStage() == FindMakeProgramStage::Early && - !this->FindMakeProgram(mf)) { - return; - } - } - // Load the CMakeDetermineSystem.cmake file and find out // what platform we are running on if (!mf->GetDefinition("CMAKE_SYSTEM")) { @@ -664,8 +666,7 @@ void cmGlobalGenerator::EnableLanguage( } // Find the native build tool for this generator. - if (this->GetFindMakeProgramStage() == FindMakeProgramStage::Late && - !this->FindMakeProgram(mf)) { + if (!this->FindMakeProgram(mf)) { return; } } @@ -789,7 +790,7 @@ void cmGlobalGenerator::EnableLanguage( std::string compilerName = cmStrCat("CMAKE_", lang, "_COMPILER"); std::string compilerEnv = cmStrCat("CMAKE_", lang, "_COMPILER_ENV_VAR"); std::ostringstream noCompiler; - cmProp compilerFile = mf->GetDefinition(compilerName); + cmValue compilerFile = mf->GetDefinition(compilerName); if (!cmNonempty(compilerFile) || cmIsNOTFOUND(*compilerFile)) { /* clang-format off */ noCompiler << @@ -826,7 +827,7 @@ void cmGlobalGenerator::EnableLanguage( cmSystemTools::RemoveFile(compilerLangFile); if (!this->CMakeInstance->GetIsInTryCompile()) { this->PrintCompilerAdvice(noCompiler, lang, - cmToCStr(mf->GetDefinition(compilerEnv))); + mf->GetDefinition(compilerEnv)); mf->IssueMessage(MessageType::FATAL_ERROR, noCompiler.str()); fatalError = true; } @@ -910,7 +911,7 @@ void cmGlobalGenerator::EnableLanguage( void cmGlobalGenerator::PrintCompilerAdvice(std::ostream& os, std::string const& lang, - const char* envVar) const + cmValue envVar) const { // Subclasses override this method if they do not support this advice. os << "Tell CMake where to find the compiler by setting "; @@ -953,6 +954,7 @@ void cmGlobalGenerator::CheckCompilerIdCompatibility( mf->IssueMessage( MessageType::FATAL_ERROR, cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0025)); + break; case cmPolicies::NEW: // NEW behavior is to keep AppleClang. break; @@ -1019,6 +1021,7 @@ void cmGlobalGenerator::CheckCompilerIdCompatibility( mf->IssueMessage( MessageType::FATAL_ERROR, cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0089)); + break; case cmPolicies::NEW: // NEW behavior is to keep AppleClang. break; @@ -1105,7 +1108,7 @@ void cmGlobalGenerator::SetLanguageEnabledMaps(const std::string& l, } std::string linkerPrefVar = "CMAKE_" + l + "_LINKER_PREFERENCE"; - cmProp linkerPref = mf->GetDefinition(linkerPrefVar); + cmValue linkerPref = mf->GetDefinition(linkerPrefVar); int preference = 0; if (cmNonempty(linkerPref)) { if (sscanf(linkerPref->c_str(), "%d", &preference) != 1) { @@ -1131,7 +1134,7 @@ void cmGlobalGenerator::SetLanguageEnabledMaps(const std::string& l, this->LanguageToLinkerPreference[l] = preference; std::string outputExtensionVar = "CMAKE_" + l + "_OUTPUT_EXTENSION"; - if (cmProp p = mf->GetDefinition(outputExtensionVar)) { + if (cmValue p = mf->GetDefinition(outputExtensionVar)) { std::string outputExtension = *p; this->LanguageToOutputExtension[l] = outputExtension; this->OutputExtensions[outputExtension] = outputExtension; @@ -1167,10 +1170,10 @@ void cmGlobalGenerator::FillExtensionToLanguageMap(const std::string& l, } } -const char* cmGlobalGenerator::GetGlobalSetting(std::string const& name) const +cmValue cmGlobalGenerator::GetGlobalSetting(std::string const& name) const { assert(!this->Makefiles.empty()); - return cmToCStr(this->Makefiles[0]->GetDefinition(name)); + return this->Makefiles[0]->GetDefinition(name); } bool cmGlobalGenerator::GlobalSettingIsOn(std::string const& name) const @@ -1183,7 +1186,7 @@ std::string cmGlobalGenerator::GetSafeGlobalSetting( std::string const& name) const { assert(!this->Makefiles.empty()); - return this->Makefiles[0]->GetSafeDefinition(name); + return this->Makefiles[0]->GetDefinition(name); } bool cmGlobalGenerator::IgnoreFile(const char* ext) const @@ -1251,10 +1254,8 @@ void cmGlobalGenerator::Configure() this->CreateDefaultGlobalTargets(globalTargets); for (const auto& mf : this->Makefiles) { - auto& targets = mf->GetTargets(); for (GlobalTargetInfo const& globalTarget : globalTargets) { - targets.emplace(globalTarget.Name, - this->CreateGlobalTarget(globalTarget, mf.get())); + this->CreateGlobalTarget(globalTarget, mf.get()); } } } @@ -1401,6 +1402,9 @@ bool cmGlobalGenerator::Compute() this->SupportsDefaultConfigs())) { return false; } + if (!this->InspectConfigTypeVariables()) { + return false; + } // Some generators track files replaced during the Generate. // Start with an empty vector: @@ -1708,10 +1712,8 @@ void cmGlobalGenerator::FinalizeTargetCompileInfo() // Construct per-target generator information. for (const auto& mf : this->Makefiles) { - const cmStringRange noconfig_compile_definitions = + const cmBTStringRange noconfig_compile_definitions = mf->GetCompileDefinitionsEntries(); - const cmBacktraceRange noconfig_compile_definitions_bts = - mf->GetCompileDefinitionsBacktraces(); for (auto& target : mf->GetTargets()) { cmTarget* t = &target.second; @@ -1725,12 +1727,8 @@ void cmGlobalGenerator::FinalizeTargetCompileInfo() continue; } - { - auto btIt = noconfig_compile_definitions_bts.begin(); - auto it = noconfig_compile_definitions.begin(); - for (; it != noconfig_compile_definitions.end(); ++it, ++btIt) { - t->InsertCompileDefinition(*it, *btIt); - } + for (auto const& def : noconfig_compile_definitions) { + t->InsertCompileDefinition(def); } cmPolicies::PolicyStatus polSt = @@ -1742,7 +1740,7 @@ void cmGlobalGenerator::FinalizeTargetCompileInfo() for (std::string const& c : configs) { std::string defPropName = cmStrCat("COMPILE_DEFINITIONS_", cmSystemTools::UpperCase(c)); - if (cmProp val = mf->GetProperty(defPropName)) { + if (cmValue val = mf->GetProperty(defPropName)) { t->AppendProperty(defPropName, *val); } } @@ -1771,9 +1769,8 @@ void cmGlobalGenerator::CreateGeneratorTargets( std::map<cmTarget*, cmGeneratorTarget*> const& importedMap) { if (targetTypes == AllTargets) { - for (auto& target : mf->GetTargets()) { - cmTarget* t = &target.second; - lg->AddGeneratorTarget(cm::make_unique<cmGeneratorTarget>(t, lg)); + for (cmTarget* target : mf->GetOrderedTargets()) { + lg->AddGeneratorTarget(cm::make_unique<cmGeneratorTarget>(target, lg)); } } @@ -1857,7 +1854,7 @@ void cmGlobalGenerator::CheckTargetProperties() } } std::vector<std::string> incs; - cmProp incDirProp = target.second.GetProperty("INCLUDE_DIRECTORIES"); + cmValue incDirProp = target.second.GetProperty("INCLUDE_DIRECTORIES"); if (!incDirProp) { continue; } @@ -2121,7 +2118,7 @@ void cmGlobalGenerator::AddMakefile(std::unique_ptr<cmMakefile> mf) // update progress // estimate how many lg there will be - cmProp numGenC = this->CMakeInstance->GetState()->GetInitializedCacheValue( + cmValue numGenC = this->CMakeInstance->GetState()->GetInitializedCacheValue( "CMAKE_NUMBER_OF_MAKEFILES"); if (!numGenC) { @@ -2180,11 +2177,10 @@ void cmGlobalGenerator::EnableLanguagesFromGenerator(cmGlobalGenerator* gen, { this->SetConfiguredFilesPath(gen); this->TryCompileOuterMakefile = mf; - cmProp make = + cmValue make = gen->GetCMakeInstance()->GetCacheDefinition("CMAKE_MAKE_PROGRAM"); - this->GetCMakeInstance()->AddCacheEntry("CMAKE_MAKE_PROGRAM", cmToCStr(make), - "make program", - cmStateEnums::FILEPATH); + this->GetCMakeInstance()->AddCacheEntry( + "CMAKE_MAKE_PROGRAM", make, "make program", cmStateEnums::FILEPATH); // copy the enabled languages this->GetCMakeInstance()->GetState()->SetEnabledLanguages( gen->GetCMakeInstance()->GetState()->GetEnabledLanguages()); @@ -2244,7 +2240,7 @@ bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root, } cmMakefile* mf = root->GetMakefile(); const std::string EXCLUDE_FROM_ALL = "EXCLUDE_FROM_ALL"; - if (cmProp exclude = target->GetProperty(EXCLUDE_FROM_ALL)) { + if (cmValue exclude = target->GetProperty(EXCLUDE_FROM_ALL)) { // Expand the property value per configuration. unsigned int trueCount = 0; unsigned int falseCount = 0; @@ -2538,7 +2534,7 @@ void cmGlobalGenerator::AddGlobalTarget_Package( if (this->GetPreinstallTargetName()) { gti.Depends.emplace_back(this->GetPreinstallTargetName()); } else { - cmProp noPackageAll = + cmValue noPackageAll = mf->GetDefinition("CMAKE_SKIP_PACKAGE_ALL_DEPENDENCY"); if (cmIsOff(noPackageAll)) { gti.Depends.emplace_back(this->GetAllTargetName()); @@ -2719,7 +2715,7 @@ void cmGlobalGenerator::AddGlobalTarget_Install( if (this->GetPreinstallTargetName()) { gti.Depends.emplace_back(this->GetPreinstallTargetName()); } else { - cmProp noall = mf->GetDefinition("CMAKE_SKIP_INSTALL_ALL_DEPENDENCY"); + cmValue noall = mf->GetDefinition("CMAKE_SKIP_INSTALL_ALL_DEPENDENCY"); if (cmIsOff(noall)) { gti.Depends.emplace_back(this->GetAllTargetName()); } @@ -2740,7 +2736,7 @@ void cmGlobalGenerator::AddGlobalTarget_Install( singleLine.push_back(cfgArg); cfgArg = "-DEFFECTIVE_PLATFORM_NAME=$(EFFECTIVE_PLATFORM_NAME)"; } else { - cfgArg += cmToCStr(mf->GetDefinition("CMAKE_CFG_INTDIR")); + cfgArg += *mf->GetDefinition("CMAKE_CFG_INTDIR"); } singleLine.push_back(cfgArg); } @@ -2785,7 +2781,7 @@ void cmGlobalGenerator::AddGlobalTarget_Install( std::string cmGlobalGenerator::GetPredefinedTargetsFolder() const { - cmProp prop = this->GetCMakeInstance()->GetState()->GetGlobalProperty( + cmValue prop = this->GetCMakeInstance()->GetState()->GetGlobalProperty( "PREDEFINED_TARGETS_FOLDER"); if (prop) { @@ -2797,7 +2793,7 @@ std::string cmGlobalGenerator::GetPredefinedTargetsFolder() const bool cmGlobalGenerator::UseFolderProperty() const { - cmProp prop = + cmValue prop = this->GetCMakeInstance()->GetState()->GetGlobalProperty("USE_FOLDERS"); // If this property is defined, let the setter turn this on or off... @@ -2812,12 +2808,19 @@ bool cmGlobalGenerator::UseFolderProperty() const return false; } -cmTarget cmGlobalGenerator::CreateGlobalTarget(GlobalTargetInfo const& gti, - cmMakefile* mf) +void cmGlobalGenerator::CreateGlobalTarget(GlobalTargetInfo const& gti, + cmMakefile* mf) { // Package - cmTarget target(gti.Name, cmStateEnums::GLOBAL_TARGET, - cmTarget::VisibilityNormal, mf, gti.PerConfig); + auto tb = + mf->CreateNewTarget(gti.Name, cmStateEnums::GLOBAL_TARGET, gti.PerConfig); + + // Do nothing if gti.Name is already used + if (!tb.second) { + return; + } + + cmTarget& target = tb.first; target.SetProperty("EXCLUDE_FROM_ALL", "TRUE"); std::vector<std::string> no_outputs; @@ -2841,8 +2844,6 @@ cmTarget cmGlobalGenerator::CreateGlobalTarget(GlobalTargetInfo const& gti, if (this->UseFolderProperty()) { target.SetProperty("FOLDER", this->GetPredefinedTargetsFolder()); } - - return target; } std::string cmGlobalGenerator::GenerateRuleFile( @@ -3143,10 +3144,10 @@ void cmGlobalGenerator::WriteSummary(cmGeneratorTarget* target) #ifndef CMAKE_BOOTSTRAP // Check whether labels are enabled for this target. - cmProp targetLabels = target->GetProperty("LABELS"); - cmProp directoryLabels = + cmValue targetLabels = target->GetProperty("LABELS"); + cmValue directoryLabels = target->Target->GetMakefile()->GetProperty("LABELS"); - cmProp cmakeDirectoryLabels = + cmValue cmakeDirectoryLabels = target->Target->GetMakefile()->GetDefinition("CMAKE_DIRECTORY_LABELS"); if (targetLabels || directoryLabels || cmakeDirectoryLabels) { Json::Value lj_root(Json::objectValue); @@ -3214,7 +3215,7 @@ void cmGlobalGenerator::WriteSummary(cmGeneratorTarget* target) std::string const& sfp = sf->ResolveFullPath(); fout << sfp << "\n"; lj_source["file"] = sfp; - if (cmProp svalue = sf->GetProperty("LABELS")) { + if (cmValue svalue = sf->GetProperty("LABELS")) { labels.clear(); Json::Value& lj_source_labels = lj_source["labels"] = Json::arrayValue; cmExpandList(*svalue, labels); diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 147146e13..96696aa8a 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -29,6 +29,7 @@ #include "cmTarget.h" #include "cmTargetDepend.h" #include "cmTransformDepfile.h" +#include "cmValue.h" #if !defined(CMAKE_BOOTSTRAP) # include <cm3p/json/value.h> @@ -152,6 +153,8 @@ public: */ virtual void Configure(); + virtual bool InspectConfigTypeVariables() { return true; } + bool Compute(); virtual void AddExtraIDETargets() {} @@ -308,7 +311,7 @@ public: cmExportSetMap& GetExportSets() { return this->ExportSets; } - const char* GetGlobalSetting(std::string const& name) const; + cmValue GetGlobalSetting(std::string const& name) const; bool GlobalSettingIsOn(std::string const& name) const; std::string GetSafeGlobalSetting(std::string const& name) const; @@ -443,6 +446,8 @@ public: virtual bool IsVisualStudio() const { return false; } + virtual bool IsVisualStudioAtLeast10() const { return false; } + virtual bool IsNinja() const { return false; } /** Return true if we know the exact location of object files. @@ -549,7 +554,7 @@ protected: virtual bool CheckLanguages(std::vector<std::string> const& languages, cmMakefile* mf) const; virtual void PrintCompilerAdvice(std::ostream& os, std::string const& lang, - const char* envVar) const; + cmValue envVar) const; virtual bool ComputeTargetDepends(); @@ -596,7 +601,7 @@ protected: void AddGlobalTarget_RebuildCache( std::vector<GlobalTargetInfo>& targets) const; void AddGlobalTarget_Install(std::vector<GlobalTargetInfo>& targets); - cmTarget CreateGlobalTarget(GlobalTargetInfo const& gti, cmMakefile* mf); + void CreateGlobalTarget(GlobalTargetInfo const& gti, cmMakefile* mf); std::string FindMakeProgramFile; std::string ConfiguredFilesPath; @@ -622,17 +627,6 @@ protected: std::string GetPredefinedTargetsFolder() const; - enum class FindMakeProgramStage - { - Early, - Late, - }; - - virtual FindMakeProgramStage GetFindMakeProgramStage() const - { - return FindMakeProgramStage::Late; - } - private: using TargetMap = std::unordered_map<std::string, cmTarget*>; using GeneratorTargetMap = diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx index 7cf3e9363..b1c0488d4 100644 --- a/Source/cmGlobalGhsMultiGenerator.cxx +++ b/Source/cmGlobalGhsMultiGenerator.cxx @@ -18,11 +18,11 @@ #include "cmLocalGenerator.h" #include "cmLocalGhsMultiGenerator.h" #include "cmMakefile.h" -#include "cmProperty.h" #include "cmState.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" #include "cmVersion.h" #include "cmake.h" @@ -99,7 +99,7 @@ bool cmGlobalGhsMultiGenerator::SetGeneratorToolset(std::string const& ts, /* set the build tool to use */ std::string gbuild(tsp + ((tsp.back() == '/') ? "" : "/") + DEFAULT_BUILD_PROGRAM); - cmProp prevTool = mf->GetDefinition("CMAKE_MAKE_PROGRAM"); + cmValue prevTool = mf->GetDefinition("CMAKE_MAKE_PROGRAM"); /* check if the toolset changed from last generate */ if (prevTool && (gbuild != *prevTool)) { @@ -186,8 +186,7 @@ void cmGlobalGhsMultiGenerator::EnableLanguage( mf->AddDefinition("GHSMULTI", "1"); // identifier for user CMake files - const char* tgtPlatform = - cmToCStrSafe(mf->GetDefinition("GHS_TARGET_PLATFORM")); + const char* tgtPlatform = mf->GetDefinition("GHS_TARGET_PLATFORM")->c_str(); if (!tgtPlatform) { cmSystemTools::Message("Green Hills MULTI: GHS_TARGET_PLATFORM not " "specified; defaulting to \"integrity\""); @@ -216,7 +215,7 @@ bool cmGlobalGhsMultiGenerator::FindMakeProgram(cmMakefile* /*mf*/) void cmGlobalGhsMultiGenerator::GetToolset(cmMakefile* mf, std::string& tsd, const std::string& ts) { - cmProp ghsRoot = mf->GetDefinition("GHS_TOOLSET_ROOT"); + cmValue ghsRoot = mf->GetDefinition("GHS_TOOLSET_ROOT"); if (cmNonempty(ghsRoot)) { tsd = *ghsRoot; @@ -334,7 +333,7 @@ void cmGlobalGhsMultiGenerator::WriteTopLevelProject(std::ostream& fout, fout << "# Top Level Project File\n"; // Specify BSP option if supplied by user - cmProp bspName = + cmValue bspName = this->GetCMakeInstance()->GetCacheDefinition("GHS_BSP_NAME"); if (!cmIsOff(bspName)) { fout << " -bsp " << *bspName << '\n'; @@ -343,7 +342,7 @@ void cmGlobalGhsMultiGenerator::WriteTopLevelProject(std::ostream& fout, // Specify OS DIR if supplied by user // -- not all platforms require this entry in the project file if (!cmIsOff(this->OsDir)) { - cmProp osDirOption = + cmValue osDirOption = this->GetCMakeInstance()->GetCacheDefinition("GHS_OS_DIR_OPTION"); std::replace(this->OsDir.begin(), this->OsDir.end(), '\\', '/'); fout << " "; @@ -378,8 +377,8 @@ void cmGlobalGhsMultiGenerator::WriteProjectLine( std::ostream& fout, cmGeneratorTarget const* target, std::string& rootBinaryDir) { - cmProp projName = target->GetProperty("GENERATOR_FILE_NAME"); - cmProp projType = target->GetProperty("GENERATOR_FILE_NAME_EXT"); + cmValue projName = target->GetProperty("GENERATOR_FILE_NAME"); + cmValue projType = target->GetProperty("GENERATOR_FILE_NAME_EXT"); if (projName && projType) { cmLocalGenerator* lg = target->GetLocalGenerator(); std::string dir = lg->GetCurrentBinaryDirectory(); @@ -564,7 +563,7 @@ cmGlobalGhsMultiGenerator::GenerateBuildCommand( { GeneratedMakeCommand makeCommand = {}; std::string gbuild; - if (cmProp gbuildCached = + if (cmValue gbuildCached = this->CMakeInstance->GetCacheDefinition("CMAKE_MAKE_PROGRAM")) { gbuild = *gbuildCached; } @@ -617,7 +616,7 @@ void cmGlobalGhsMultiGenerator::WriteMacros(std::ostream& fout, cmLocalGenerator* root) { fout << "macro PROJ_NAME=" << root->GetProjectName() << '\n'; - cmProp ghsGpjMacros = + cmValue ghsGpjMacros = this->GetCMakeInstance()->GetCacheDefinition("GHS_GPJ_MACROS"); if (ghsGpjMacros) { std::vector<std::string> expandedList = cmExpandedList(*ghsGpjMacros); @@ -632,15 +631,15 @@ void cmGlobalGhsMultiGenerator::WriteHighLevelDirectives( { /* set primary target */ std::string tgt; - cmProp t = + cmValue t = this->GetCMakeInstance()->GetCacheDefinition("GHS_PRIMARY_TARGET"); if (cmNonempty(t)) { tgt = *t; this->GetCMakeInstance()->MarkCliAsUsed("GHS_PRIMARY_TARGET"); } else { - cmProp a = + cmValue a = this->GetCMakeInstance()->GetCacheDefinition("CMAKE_GENERATOR_PLATFORM"); - cmProp p = + cmValue p = this->GetCMakeInstance()->GetCacheDefinition("GHS_TARGET_PLATFORM"); tgt = cmStrCat((a ? *a : ""), '_', (p ? *p : ""), ".tgt"); } @@ -653,7 +652,7 @@ void cmGlobalGhsMultiGenerator::WriteHighLevelDirectives( << "/CMakeFiles/custom_target.bod" << '\n'; /* clang-format on */ - cmProp const customization = + cmValue const customization = this->GetCMakeInstance()->GetCacheDefinition("GHS_CUSTOMIZATION"); if (cmNonempty(customization)) { fout << "customization=" diff --git a/Source/cmGlobalJOMMakefileGenerator.cxx b/Source/cmGlobalJOMMakefileGenerator.cxx index fc3123a44..40deebb04 100644 --- a/Source/cmGlobalJOMMakefileGenerator.cxx +++ b/Source/cmGlobalJOMMakefileGenerator.cxx @@ -39,8 +39,9 @@ void cmGlobalJOMMakefileGenerator::GetDocumentation( entry.Brief = "Generates JOM makefiles."; } -void cmGlobalJOMMakefileGenerator::PrintCompilerAdvice( - std::ostream& os, std::string const& lang, const char* envVar) const +void cmGlobalJOMMakefileGenerator::PrintCompilerAdvice(std::ostream& os, + std::string const& lang, + cmValue envVar) const { if (lang == "CXX" || lang == "C") { /* clang-format off */ diff --git a/Source/cmGlobalJOMMakefileGenerator.h b/Source/cmGlobalJOMMakefileGenerator.h index 2d58f9119..58860dd64 100644 --- a/Source/cmGlobalJOMMakefileGenerator.h +++ b/Source/cmGlobalJOMMakefileGenerator.h @@ -50,5 +50,5 @@ protected: private: void PrintCompilerAdvice(std::ostream& os, std::string const& lang, - const char* envVar) const override; + cmValue envVar) const override; }; diff --git a/Source/cmGlobalNMakeMakefileGenerator.cxx b/Source/cmGlobalNMakeMakefileGenerator.cxx index f08b1da36..a038f871e 100644 --- a/Source/cmGlobalNMakeMakefileGenerator.cxx +++ b/Source/cmGlobalNMakeMakefileGenerator.cxx @@ -42,7 +42,7 @@ bool cmGlobalNMakeMakefileGenerator::FindMakeProgram(cmMakefile* mf) if (!this->cmGlobalGenerator::FindMakeProgram(mf)) { return false; } - if (cmProp nmakeCommand = mf->GetDefinition("CMAKE_MAKE_PROGRAM")) { + if (cmValue nmakeCommand = mf->GetDefinition("CMAKE_MAKE_PROGRAM")) { std::vector<std::string> command{ *nmakeCommand, "-?" }; std::string out; std::string err; @@ -70,7 +70,7 @@ bool cmGlobalNMakeMakefileGenerator::FindMakeProgram(cmMakefile* mf) void cmGlobalNMakeMakefileGenerator::CheckNMakeFeatures() { this->NMakeSupportsUTF8 = !cmSystemTools::VersionCompare( - cmSystemTools::OP_LESS, this->NMakeVersion.c_str(), "9"); + cmSystemTools::OP_LESS, this->NMakeVersion, "9"); } void cmGlobalNMakeMakefileGenerator::GetDocumentation( @@ -81,7 +81,7 @@ void cmGlobalNMakeMakefileGenerator::GetDocumentation( } void cmGlobalNMakeMakefileGenerator::PrintCompilerAdvice( - std::ostream& os, std::string const& lang, const char* envVar) const + std::ostream& os, std::string const& lang, cmValue envVar) const { if (lang == "CXX" || lang == "C") { /* clang-format off */ diff --git a/Source/cmGlobalNMakeMakefileGenerator.h b/Source/cmGlobalNMakeMakefileGenerator.h index 402b89fda..4f202b5a4 100644 --- a/Source/cmGlobalNMakeMakefileGenerator.h +++ b/Source/cmGlobalNMakeMakefileGenerator.h @@ -61,5 +61,5 @@ private: void CheckNMakeFeatures(); void PrintCompilerAdvice(std::ostream& os, std::string const& lang, - const char* envVar) const override; + cmValue envVar) const override; }; diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 971a462a6..7122b9f8f 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -35,7 +35,6 @@ #include "cmMessageType.h" #include "cmNinjaLinkLineComputer.h" #include "cmOutputConverter.h" -#include "cmProperty.h" #include "cmRange.h" #include "cmScanDepFormat.h" #include "cmState.h" @@ -46,6 +45,7 @@ #include "cmSystemTools.h" #include "cmTarget.h" #include "cmTargetDepend.h" +#include "cmValue.h" #include "cmVersion.h" #include "cmake.h" @@ -382,7 +382,7 @@ void cmGlobalNinjaGenerator::WriteCustomCommandBuild( if (restat) { vars["restat"] = "1"; } - if (uses_terminal && this->SupportsConsolePool()) { + if (uses_terminal && this->SupportsDirectConsole()) { vars["pool"] = "console"; } else if (!job_pool.empty()) { vars["pool"] = job_pool; @@ -558,9 +558,8 @@ void cmGlobalNinjaGenerator::GetDocumentation(cmDocumentationEntry& entry) void cmGlobalNinjaGenerator::Generate() { // Check minimum Ninja version. - if (cmSystemTools::VersionCompare(cmSystemTools::OP_LESS, - this->NinjaVersion.c_str(), - RequiredNinjaVersion().c_str())) { + if (cmSystemTools::VersionCompare(cmSystemTools::OP_LESS, this->NinjaVersion, + RequiredNinjaVersion())) { std::ostringstream msg; msg << "The detected version of Ninja (" << this->NinjaVersion; msg << ") is less than the version of Ninja required by CMake ("; @@ -569,9 +568,6 @@ void cmGlobalNinjaGenerator::Generate() msg.str()); return; } - if (!this->InspectConfigTypeVariables()) { - return; - } if (!this->OpenBuildFileStreams()) { return; } @@ -695,7 +691,7 @@ bool cmGlobalNinjaGenerator::FindMakeProgram(cmMakefile* mf) if (!this->cmGlobalGenerator::FindMakeProgram(mf)) { return false; } - if (cmProp ninjaCommand = mf->GetDefinition("CMAKE_MAKE_PROGRAM")) { + if (cmValue ninjaCommand = mf->GetDefinition("CMAKE_MAKE_PROGRAM")) { this->NinjaCommand = *ninjaCommand; std::vector<std::string> command; command.push_back(this->NinjaCommand); @@ -721,21 +717,21 @@ bool cmGlobalNinjaGenerator::FindMakeProgram(cmMakefile* mf) void cmGlobalNinjaGenerator::CheckNinjaFeatures() { - this->NinjaSupportsConsolePool = !cmSystemTools::VersionCompare( - cmSystemTools::OP_LESS, this->NinjaVersion.c_str(), - RequiredNinjaVersionForConsolePool().c_str()); + this->NinjaSupportsConsolePool = + !cmSystemTools::VersionCompare(cmSystemTools::OP_LESS, this->NinjaVersion, + RequiredNinjaVersionForConsolePool()); this->NinjaSupportsImplicitOuts = !cmSystemTools::VersionCompare( - cmSystemTools::OP_LESS, this->NinjaVersion.c_str(), - cmGlobalNinjaGenerator::RequiredNinjaVersionForImplicitOuts().c_str()); - this->NinjaSupportsManifestRestat = !cmSystemTools::VersionCompare( - cmSystemTools::OP_LESS, this->NinjaVersion.c_str(), - RequiredNinjaVersionForManifestRestat().c_str()); - this->NinjaSupportsMultilineDepfile = !cmSystemTools::VersionCompare( - cmSystemTools::OP_LESS, this->NinjaVersion.c_str(), - RequiredNinjaVersionForMultilineDepfile().c_str()); - this->NinjaSupportsDyndeps = !cmSystemTools::VersionCompare( - cmSystemTools::OP_LESS, this->NinjaVersion.c_str(), - RequiredNinjaVersionForDyndeps().c_str()); + cmSystemTools::OP_LESS, this->NinjaVersion, + cmGlobalNinjaGenerator::RequiredNinjaVersionForImplicitOuts()); + this->NinjaSupportsManifestRestat = + !cmSystemTools::VersionCompare(cmSystemTools::OP_LESS, this->NinjaVersion, + RequiredNinjaVersionForManifestRestat()); + this->NinjaSupportsMultilineDepfile = + !cmSystemTools::VersionCompare(cmSystemTools::OP_LESS, this->NinjaVersion, + RequiredNinjaVersionForMultilineDepfile()); + this->NinjaSupportsDyndeps = + !cmSystemTools::VersionCompare(cmSystemTools::OP_LESS, this->NinjaVersion, + RequiredNinjaVersionForDyndeps()); if (!this->NinjaSupportsDyndeps) { // The ninja version number is not new enough to have upstream support. // Our ninja branch adds ".dyndep-#" to its version number, @@ -753,21 +749,21 @@ void cmGlobalNinjaGenerator::CheckNinjaFeatures() } this->NinjaSupportsUnconditionalRecompactTool = !cmSystemTools::VersionCompare( - cmSystemTools::OP_LESS, this->NinjaVersion.c_str(), - RequiredNinjaVersionForUnconditionalRecompactTool().c_str()); - this->NinjaSupportsRestatTool = !cmSystemTools::VersionCompare( - cmSystemTools::OP_LESS, this->NinjaVersion.c_str(), - RequiredNinjaVersionForRestatTool().c_str()); - this->NinjaSupportsMultipleOutputs = !cmSystemTools::VersionCompare( - cmSystemTools::OP_LESS, this->NinjaVersion.c_str(), - RequiredNinjaVersionForMultipleOutputs().c_str()); + cmSystemTools::OP_LESS, this->NinjaVersion, + RequiredNinjaVersionForUnconditionalRecompactTool()); + this->NinjaSupportsRestatTool = + !cmSystemTools::VersionCompare(cmSystemTools::OP_LESS, this->NinjaVersion, + RequiredNinjaVersionForRestatTool()); + this->NinjaSupportsMultipleOutputs = + !cmSystemTools::VersionCompare(cmSystemTools::OP_LESS, this->NinjaVersion, + RequiredNinjaVersionForMultipleOutputs()); this->NinjaSupportsMetadataOnRegeneration = !cmSystemTools::VersionCompare( - cmSystemTools::OP_LESS, this->NinjaVersion.c_str(), - RequiredNinjaVersionForMetadataOnRegeneration().c_str()); + cmSystemTools::OP_LESS, this->NinjaVersion, + RequiredNinjaVersionForMetadataOnRegeneration()); #ifdef _WIN32 - this->NinjaSupportsCodePage = !cmSystemTools::VersionCompare( - cmSystemTools::OP_LESS, this->NinjaVersion.c_str(), - RequiredNinjaVersionForCodePage().c_str()); + this->NinjaSupportsCodePage = + !cmSystemTools::VersionCompare(cmSystemTools::OP_LESS, this->NinjaVersion, + RequiredNinjaVersionForCodePage()); if (this->NinjaSupportsCodePage) { this->CheckNinjaCodePage(); } else { @@ -920,14 +916,7 @@ void cmGlobalNinjaGenerator::EnableLanguage( std::vector<std::string> const& langs, cmMakefile* mf, bool optional) { if (this->IsMultiConfig()) { - if (!mf->GetDefinition("CMAKE_CONFIGURATION_TYPES")) { - mf->AddCacheDefinition( - "CMAKE_CONFIGURATION_TYPES", "Debug;Release;RelWithDebInfo", - "Semicolon separated list of supported configuration types, only " - "supports Debug, Release, MinSizeRel, and RelWithDebInfo, anything " - "else will be ignored", - cmStateEnums::STRING); - } + mf->InitCMAKE_CONFIGURATION_TYPES("Debug;Release;RelWithDebInfo"); } this->cmGlobalGenerator::EnableLanguage(langs, mf, optional); @@ -936,29 +925,21 @@ void cmGlobalNinjaGenerator::EnableLanguage( continue; } this->ResolveLanguageCompiler(l, mf, optional); - } #ifdef _WIN32 - const bool clangGnuMode = - ((mf->GetSafeDefinition("CMAKE_C_COMPILER_ID") == "Clang") && - (mf->GetSafeDefinition("CMAKE_C_COMPILER_FRONTEND_VARIANT") == "GNU")) || - ((mf->GetSafeDefinition("CMAKE_CXX_COMPILER_ID") == "Clang") && - (mf->GetSafeDefinition("CMAKE_CXX_COMPILER_FRONTEND_VARIANT") == "GNU")); - - if (clangGnuMode || - ((mf->GetSafeDefinition("CMAKE_C_SIMULATE_ID") != "MSVC") && - (mf->GetSafeDefinition("CMAKE_CXX_SIMULATE_ID") != "MSVC") && - (mf->IsOn("CMAKE_COMPILER_IS_MINGW") || - (mf->GetSafeDefinition("CMAKE_C_COMPILER_ID") == "GNU") || - (mf->GetSafeDefinition("CMAKE_CXX_COMPILER_ID") == "GNU") || - (mf->GetSafeDefinition("CMAKE_C_COMPILER_ID") == "Clang") || - (mf->GetSafeDefinition("CMAKE_CXX_COMPILER_ID") == "Clang") || - (mf->GetSafeDefinition("CMAKE_C_COMPILER_ID") == "ARMClang") || - (mf->GetSafeDefinition("CMAKE_CXX_COMPILER_ID") == "ARMClang") || - (mf->GetSafeDefinition("CMAKE_C_COMPILER_ID") == "QCC") || - (mf->GetSafeDefinition("CMAKE_CXX_COMPILER_ID") == "QCC")))) { - this->UsingGCCOnWindows = true; - } + std::string const& compilerId = + mf->GetSafeDefinition(cmStrCat("CMAKE_", l, "_COMPILER_ID")); + std::string const& simulateId = + mf->GetSafeDefinition(cmStrCat("CMAKE_", l, "_SIMULATE_ID")); + std::string const& compilerFrontendVariant = mf->GetSafeDefinition( + cmStrCat("CMAKE_", l, "_COMPILER_FRONTEND_VARIANT")); + if ((compilerId == "Clang" && compilerFrontendVariant == "GNU") || + (simulateId != "MSVC" && + (compilerId == "GNU" || compilerId == "QCC" || + cmHasLiteralSuffix(compilerId, "Clang")))) { + this->UsingGCCOnWindows = true; + } #endif + } } // Implemented by: @@ -1021,13 +1002,6 @@ bool cmGlobalNinjaGenerator::HasRule(const std::string& name) // Private virtual overrides -std::string cmGlobalNinjaGenerator::GetEditCacheCommand() const -{ - // Ninja by design does not run interactive tools in the terminal, - // so our only choice is cmake-gui. - return cmSystemTools::GetCMakeGUICommand(); -} - void cmGlobalNinjaGenerator::ComputeTargetObjectDirectory( cmGeneratorTarget* gt) const { @@ -1286,7 +1260,7 @@ void cmGlobalNinjaGenerator::AppendTargetOutputs( break; } } - // FALLTHROUGH + CM_FALLTHROUGH; case cmStateEnums::EXECUTABLE: { outputs.push_back(this->ConvertToNinjaPath(target->GetFullPath( config, cmStateEnums::RuntimeBinaryArtifact, realname))); @@ -1298,7 +1272,7 @@ void cmGlobalNinjaGenerator::AppendTargetOutputs( break; } } - // FALLTHROUGH + CM_FALLTHROUGH; case cmStateEnums::GLOBAL_TARGET: case cmStateEnums::INTERFACE_LIBRARY: case cmStateEnums::UTILITY: { @@ -1849,7 +1823,7 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os) // Use 'console' pool to get non buffered output of the CMake re-run call // Available since Ninja 1.5 - if (this->SupportsConsolePool()) { + if (this->SupportsDirectConsole()) { reBuild.Variables["pool"] = "console"; } @@ -1943,7 +1917,7 @@ std::string cmGlobalNinjaGenerator::NinjaCmd() const return "ninja"; } -bool cmGlobalNinjaGenerator::SupportsConsolePool() const +bool cmGlobalNinjaGenerator::SupportsDirectConsole() const { return this->NinjaSupportsConsolePool; } diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index bb4ce2bf2..84fc06c1c 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -220,7 +220,6 @@ public: { return "package_source"; } - const char* GetEditCacheTargetName() const override { return "edit_cache"; } const char* GetRebuildCacheTargetName() const override { return "rebuild_cache"; @@ -406,7 +405,7 @@ public: return "1.10.2"; } static std::string RequiredNinjaVersionForCodePage() { return "1.11"; } - bool SupportsConsolePool() const; + bool SupportsDirectConsole() const override; bool SupportsImplicitOuts() const; bool SupportsManifestRestat() const; bool SupportsMultilineDepfile() const; @@ -482,14 +481,11 @@ protected: const std::set<std::string>& all, const std::set<std::string>& defaults, const std::vector<std::string>& items); - virtual bool InspectConfigTypeVariables() { return true; } - std::set<std::string> CrossConfigs; std::set<std::string> DefaultConfigs; std::string DefaultFileConfig; private: - std::string GetEditCacheCommand() const override; bool FindMakeProgram(cmMakefile* mf) override; void CheckNinjaFeatures(); void CheckNinjaCodePage(); diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index 9c3de1eed..055654091 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -20,12 +20,12 @@ #include "cmMakefile.h" #include "cmMakefileTargetGenerator.h" #include "cmOutputConverter.h" -#include "cmProperty.h" #include "cmState.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTargetDepend.h" +#include "cmValue.h" #include "cmake.h" cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3(cmake* cm) @@ -78,36 +78,6 @@ void cmGlobalUnixMakefileGenerator3::GetDocumentation( entry.Brief = "Generates standard UNIX makefiles."; } -std::string cmGlobalUnixMakefileGenerator3::GetEditCacheCommand() const -{ - // If generating for an extra IDE, the edit_cache target cannot - // launch a terminal-interactive tool, so always use cmake-gui. - if (!this->GetExtraGeneratorName().empty()) { - return cmSystemTools::GetCMakeGUICommand(); - } - - // Use an internal cache entry to track the latest dialog used - // to edit the cache, and use that for the edit_cache target. - cmake* cm = this->GetCMakeInstance(); - std::string editCacheCommand = cm->GetCMakeEditCommand(); - if (!cm->GetCacheDefinition("CMAKE_EDIT_COMMAND") || - !editCacheCommand.empty()) { - if (editCacheCommand.empty()) { - editCacheCommand = cmSystemTools::GetCMakeCursesCommand(); - } - if (editCacheCommand.empty()) { - editCacheCommand = cmSystemTools::GetCMakeGUICommand(); - } - if (!editCacheCommand.empty()) { - cm->AddCacheEntry("CMAKE_EDIT_COMMAND", editCacheCommand.c_str(), - "Path to cache edit program executable.", - cmStateEnums::INTERNAL); - } - } - cmProp edit_cmd = cm->GetCacheDefinition("CMAKE_EDIT_COMMAND"); - return edit_cmd ? *edit_cmd : std::string(); -} - void cmGlobalUnixMakefileGenerator3::ComputeTargetObjectDirectory( cmGeneratorTarget* gt) const { @@ -714,7 +684,7 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2( } bool targetMessages = true; - if (cmProp tgtMsg = + if (cmValue tgtMsg = this->GetCMakeInstance()->GetState()->GetGlobalProperty( "TARGET_MESSAGES")) { targetMessages = cmIsOn(*tgtMsg); diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h index 7c950cca1..94ee47633 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.h +++ b/Source/cmGlobalUnixMakefileGenerator3.h @@ -228,7 +228,6 @@ protected: { return "package_source"; } - const char* GetEditCacheTargetName() const override { return "edit_cache"; } const char* GetRebuildCacheTargetName() const override { return "rebuild_cache"; @@ -278,7 +277,6 @@ protected: private: const char* GetBuildIgnoreErrorsFlag() const override { return "-i"; } - std::string GetEditCacheCommand() const override; std::map<cmStateSnapshot, std::set<cmGeneratorTarget const*>, cmStateSnapshot::StrictWeakOrder> diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx index fdb71554c..6cab49269 100644 --- a/Source/cmGlobalVisualStudio10Generator.cxx +++ b/Source/cmGlobalVisualStudio10Generator.cxx @@ -88,7 +88,7 @@ public: void GetDocumentation(cmDocumentationEntry& entry) const override { entry.Name = std::string(vs10generatorName) + " [arch]"; - entry.Brief = "Generates Visual Studio 2010 project files. " + entry.Brief = "Deprecated. Generates Visual Studio 2010 project files. " "Optional [arch] can be \"Win64\" or \"IA64\"."; } @@ -139,7 +139,6 @@ cmGlobalVisualStudio10Generator::cmGlobalVisualStudio10Generator( "ProductDir", vc10Express, cmSystemTools::KeyWOW64_32); this->CudaEnabled = false; - this->MSBuildCommandInitialized = false; { std::string envPlatformToolset; if (cmSystemTools::GetEnv("PlatformToolset", envPlatformToolset) && @@ -581,6 +580,13 @@ bool cmGlobalVisualStudio10Generator::InitializeWindowsCE(cmMakefile* mf) this->DefaultPlatformToolset = this->SelectWindowsCEToolset(); + if (this->GetVersion() == cmGlobalVisualStudioGenerator::VS12) { + // VS 12 .NET CF defaults to .NET framework 3.9 for Windows CE. + this->DefaultTargetFrameworkVersion = "v3.9"; + this->DefaultTargetFrameworkIdentifier = "WindowsEmbeddedCompact"; + this->DefaultTargetFrameworkTargetsVersion = "v8.0"; + } + return true; } @@ -857,6 +863,12 @@ std::string const& cmGlobalVisualStudio10Generator::GetMSBuildCommand() return this->MSBuildCommand; } +cm::optional<std::string> +cmGlobalVisualStudio10Generator::FindMSBuildCommandEarly(cmMakefile*) +{ + return this->GetMSBuildCommand(); +} + std::string cmGlobalVisualStudio10Generator::FindMSBuildCommand() { std::string msbuild; diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h index b7ae1eecf..6e6239065 100644 --- a/Source/cmGlobalVisualStudio10Generator.h +++ b/Source/cmGlobalVisualStudio10Generator.h @@ -20,6 +20,8 @@ class cmGlobalVisualStudio10Generator : public cmGlobalVisualStudio8Generator public: static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory(); + bool IsVisualStudioAtLeast10() const override { return true; } + bool MatchesGeneratorName(const std::string& name) const override; bool SetSystemName(std::string const& s, cmMakefile* mf) override; @@ -132,6 +134,8 @@ public: bool GetSupportsUnityBuilds() const { return this->SupportsUnityBuilds; } + virtual cm::optional<std::string> FindMSBuildCommandEarly(cmMakefile* mf); + bool FindMakeProgram(cmMakefile* mf) override; bool IsIPOSupported() const override { return true; } @@ -222,6 +226,7 @@ protected: bool SystemIsWindowsPhone = false; bool SystemIsWindowsStore = false; bool SystemIsAndroid = false; + bool MSBuildCommandInitialized = false; private: class Factory; @@ -243,7 +248,6 @@ private: LongestSourcePath LongestSource; std::string MSBuildCommand; - bool MSBuildCommandInitialized; std::set<std::string> AndroidExecutableWarnings; virtual std::string FindMSBuildCommand(); std::string FindDevEnvCommand() override; diff --git a/Source/cmGlobalVisualStudio14Generator.cxx b/Source/cmGlobalVisualStudio14Generator.cxx index b46f1b9b0..ff1642f8b 100644 --- a/Source/cmGlobalVisualStudio14Generator.cxx +++ b/Source/cmGlobalVisualStudio14Generator.cxx @@ -239,7 +239,7 @@ std::string cmGlobalVisualStudio14Generator::GetWindows10SDKMaxVersion( { // if the given value is set, it can either be OFF/FALSE or a valid SDK // string - if (cmProp value = mf->GetDefinition( + if (cmValue value = mf->GetDefinition( "CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION_MAXIMUM")) { // If the value is some off/false value, then there is NO maximum set. diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx index 0083c407d..50975ffdf 100644 --- a/Source/cmGlobalVisualStudio71Generator.cxx +++ b/Source/cmGlobalVisualStudio71Generator.cxx @@ -102,7 +102,7 @@ void cmGlobalVisualStudio71Generator::WriteProject(std::ostream& fout, ext = ".csproj"; project = "Project(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \""; } - cmProp targetExt = t->GetProperty("GENERATOR_FILE_NAME_EXT"); + cmValue targetExt = t->GetProperty("GENERATOR_FILE_NAME_EXT"); if (targetExt) { ext = *targetExt; } @@ -157,11 +157,11 @@ void cmGlobalVisualStudio71Generator::WriteProjectDepends( // executables to the libraries it uses are also done here void cmGlobalVisualStudio71Generator::WriteExternalProject( std::ostream& fout, const std::string& name, const std::string& location, - const char* typeGuid, - const std::set<BT<std::pair<std::string, bool>>>& depends) + cmValue typeGuid, const std::set<BT<std::pair<std::string, bool>>>& depends) { fout << "Project(\"{" - << (typeGuid ? typeGuid : this->ExternalProjectType(location)) + << (typeGuid ? typeGuid + : std::string(this->ExternalProjectType(location))) << "}\") = \"" << name << "\", \"" << this->ConvertToSolutionPath(location) << "\", \"{" << this->GetGUID(name) << "}\"\n"; @@ -198,8 +198,8 @@ void cmGlobalVisualStudio71Generator::WriteProjectConfigurations( std::vector<std::string> mapConfig; const char* dstConfig = i.c_str(); if (target.GetProperty("EXTERNAL_MSPROJECT")) { - if (cmProp m = target.GetProperty("MAP_IMPORTED_CONFIG_" + - cmSystemTools::UpperCase(i))) { + if (cmValue m = target.GetProperty("MAP_IMPORTED_CONFIG_" + + cmSystemTools::UpperCase(i))) { cmExpandList(*m, mapConfig); if (!mapConfig.empty()) { dstConfig = mapConfig[0].c_str(); diff --git a/Source/cmGlobalVisualStudio71Generator.h b/Source/cmGlobalVisualStudio71Generator.h index 7d3819966..cb3b8c13b 100644 --- a/Source/cmGlobalVisualStudio71Generator.h +++ b/Source/cmGlobalVisualStudio71Generator.h @@ -33,7 +33,7 @@ protected: const std::string& platformMapping = "") override; void WriteExternalProject( std::ostream& fout, const std::string& name, const std::string& path, - const char* typeGuid, + cmValue typeGuid, const std::set<BT<std::pair<std::string, bool>>>& depends) override; // Folders are not supported by VS 7.1. diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx index 0c85a044e..6876e6179 100644 --- a/Source/cmGlobalVisualStudio7Generator.cxx +++ b/Source/cmGlobalVisualStudio7Generator.cxx @@ -37,6 +37,7 @@ static cmVS7FlagTable cmVS7ExtraFlagTable[] = { cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue }, { "PrecompiledHeaderThrough", "Yu", "Precompiled Header Name", "", cmVS7FlagTable::UserValueRequired }, + { "UsePrecompiledHeader", "Y-", "Don't use precompiled header", "0", 0 }, { "WholeProgramOptimization", "LTCG", "WholeProgramOptimization", "true", 0 }, @@ -107,14 +108,7 @@ void cmGlobalVisualStudio7Generator::EnableLanguage( { mf->AddDefinition("CMAKE_GENERATOR_RC", "rc"); mf->AddDefinition("CMAKE_GENERATOR_NO_COMPILER_ENV", "1"); - if (!mf->GetDefinition("CMAKE_CONFIGURATION_TYPES")) { - mf->AddCacheDefinition( - "CMAKE_CONFIGURATION_TYPES", "Debug;Release;MinSizeRel;RelWithDebInfo", - "Semicolon separated list of supported configuration types, " - "only supports Debug, Release, MinSizeRel, and RelWithDebInfo, " - "anything else will be ignored.", - cmStateEnums::STRING); - } + mf->InitCMAKE_CONFIGURATION_TYPES("Debug;Release;MinSizeRel;RelWithDebInfo"); // Create list of configurations requested by user's cache, if any. this->cmGlobalVisualStudioGenerator::EnableLanguage(lang, mf, optional); @@ -303,6 +297,25 @@ void cmGlobalVisualStudio7Generator::Generate() this->CallVisualStudioMacro(MacroReload, GetSLNFile(this->LocalGenerators[0].get())); } + + if (this->Version == VS10 && !this->CMakeInstance->GetIsInTryCompile()) { + std::string cmakeWarnVS10; + if (cmValue cached = this->CMakeInstance->GetState()->GetCacheEntryValue( + "CMAKE_WARN_VS10")) { + this->CMakeInstance->MarkCliAsUsed("CMAKE_WARN_VS10"); + cmakeWarnVS10 = *cached; + } else { + cmSystemTools::GetEnv("CMAKE_WARN_VS10", cmakeWarnVS10); + } + if (cmakeWarnVS10.empty() || !cmIsOff(cmakeWarnVS10)) { + this->CMakeInstance->IssueMessage( + MessageType::WARNING, + "The \"Visual Studio 10 2010\" generator is deprecated " + "and will be removed in a future version of CMake." + "\n" + "Add CMAKE_WARN_VS10=OFF to the cache to disable this warning."); + } + } } void cmGlobalVisualStudio7Generator::OutputSLNFile( @@ -342,17 +355,17 @@ void cmGlobalVisualStudio7Generator::WriteTargetConfigurations( if (!target->IsInBuildSystem()) { continue; } - cmProp expath = target->GetProperty("EXTERNAL_MSPROJECT"); + cmValue expath = target->GetProperty("EXTERNAL_MSPROJECT"); if (expath) { std::set<std::string> allConfigurations(configs.begin(), configs.end()); - cmProp mapping = target->GetProperty("VS_PLATFORM_MAPPING"); + cmValue mapping = target->GetProperty("VS_PLATFORM_MAPPING"); this->WriteProjectConfigurations(fout, target->GetName(), *target, configs, allConfigurations, mapping ? *mapping : ""); } else { const std::set<std::string>& configsPartOfDefaultBuild = this->IsPartOfDefaultBuild(configs, projectTargets, target); - cmProp vcprojName = target->GetProperty("GENERATOR_FILE_NAME"); + cmValue vcprojName = target->GetProperty("GENERATOR_FILE_NAME"); if (vcprojName) { this->WriteProjectConfigurations(fout, *vcprojName, *target, configs, configsPartOfDefaultBuild); @@ -374,18 +387,17 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution( bool written = false; // handle external vc project files - cmProp expath = target->GetProperty("EXTERNAL_MSPROJECT"); + cmValue expath = target->GetProperty("EXTERNAL_MSPROJECT"); if (expath) { std::string project = target->GetName(); std::string location = *expath; - this->WriteExternalProject( - fout, project, location, - cmToCStr(target->GetProperty("VS_PROJECT_TYPE")), - target->GetUtilities()); + this->WriteExternalProject(fout, project, location, + target->GetProperty("VS_PROJECT_TYPE"), + target->GetUtilities()); written = true; } else { - cmProp vcprojName = target->GetProperty("GENERATOR_FILE_NAME"); + cmValue vcprojName = target->GetProperty("GENERATOR_FILE_NAME"); if (vcprojName) { cmLocalGenerator* lg = target->GetLocalGenerator(); std::string dir = lg->GetCurrentBinaryDirectory(); @@ -438,7 +450,7 @@ void cmGlobalVisualStudio7Generator::WriteTargetDepends( if (!target->IsInBuildSystem()) { continue; } - cmProp vcprojName = target->GetProperty("GENERATOR_FILE_NAME"); + cmValue vcprojName = target->GetProperty("GENERATOR_FILE_NAME"); if (vcprojName) { std::string dir = target->GetLocalGenerator()->GetCurrentSourceDirectory(); @@ -526,7 +538,7 @@ void cmGlobalVisualStudio7Generator::WriteSLNGlobalSections( extensibilityAddInsOverridden = true; } fout << "\tGlobalSection(" << name << ") = " << sectionType << "\n"; - cmProp p = root->GetMakefile()->GetProperty(it); + cmValue p = root->GetMakefile()->GetProperty(it); std::vector<std::string> keyValuePairs = cmExpandedList(p ? *p : ""); for (std::string const& itPair : keyValuePairs) { const std::string::size_type posEqual = itPair.find('='); @@ -625,7 +637,7 @@ std::string cmGlobalVisualStudio7Generator::WriteUtilityDepend( std::string cmGlobalVisualStudio7Generator::GetGUID(std::string const& name) { std::string const& guidStoreName = name + "_GUID_CMAKE"; - if (cmProp storedGUID = + if (cmValue storedGUID = this->CMakeInstance->GetCacheDefinition(guidStoreName)) { return *storedGUID; } @@ -675,7 +687,7 @@ std::set<std::string> cmGlobalVisualStudio7Generator::IsPartOfDefaultBuild( "CMAKE_VS_INCLUDE_" + t + "_TO_DEFAULT_BUILD"; // inspect CMAKE_VS_INCLUDE_<t>_TO_DEFAULT_BUILD properties for (std::string const& i : configs) { - cmProp propertyValue = + cmValue propertyValue = target->Target->GetMakefile()->GetDefinition(propertyName); if (propertyValue && cmIsOn(cmGeneratorExpression::Evaluate( diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h index 148762eac..8e762cf90 100644 --- a/Source/cmGlobalVisualStudio7Generator.h +++ b/Source/cmGlobalVisualStudio7Generator.h @@ -6,6 +6,7 @@ #include "cmGlobalGeneratorFactory.h" #include "cmGlobalVisualStudioGenerator.h" +#include "cmValue.h" class cmTarget; struct cmIDEFlagTable; @@ -142,7 +143,7 @@ protected: virtual void WriteExternalProject( std::ostream& fout, const std::string& name, const std::string& path, - const char* typeGuid, + cmValue typeGuid, const std::set<BT<std::pair<std::string, bool>>>& dependencies) = 0; std::string ConvertToSolutionPath(const std::string& path); diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx index b19212e47..1e45813bb 100644 --- a/Source/cmGlobalVisualStudio8Generator.cxx +++ b/Source/cmGlobalVisualStudio8Generator.cxx @@ -67,12 +67,55 @@ void cmGlobalVisualStudio8Generator::AddPlatformDefinitions(cmMakefile* mf) bool cmGlobalVisualStudio8Generator::SetGeneratorPlatform(std::string const& p, cmMakefile* mf) { - if (!this->PlatformInGeneratorName) { - this->GeneratorPlatform = p; - return this->cmGlobalVisualStudio7Generator::SetGeneratorPlatform("", mf); - } else { + if (this->PlatformInGeneratorName) { + // This is an old-style generator name that contains the platform name. + // No explicit platform specification is supported, so pass it through + // to our base class implementation, which errors on non-empty platforms. return this->cmGlobalVisualStudio7Generator::SetGeneratorPlatform(p, mf); } + + this->GeneratorPlatform = p; + + // FIXME: Add CMAKE_GENERATOR_PLATFORM field to set the framework. + // For now, just report the generator's default, if any. + if (cm::optional<std::string> const& targetFrameworkVersion = + this->GetTargetFrameworkVersion()) { + mf->AddDefinition("CMAKE_VS_TARGET_FRAMEWORK_VERSION", + *targetFrameworkVersion); + } + if (cm::optional<std::string> const& targetFrameworkIdentifier = + this->GetTargetFrameworkIdentifier()) { + mf->AddDefinition("CMAKE_VS_TARGET_FRAMEWORK_IDENTIFIER", + *targetFrameworkIdentifier); + } + if (cm::optional<std::string> const& targetFrameworkTargetsVersion = + this->GetTargetFrameworkTargetsVersion()) { + mf->AddDefinition("CMAKE_VS_TARGET_FRAMEWORK_TARGETS_VERSION", + *targetFrameworkTargetsVersion); + } + + // The generator name does not contain the platform name, and so supports + // explicit platform specification. We handled that above, so pass an + // empty platform name to our base class implementation so it does not error. + return this->cmGlobalVisualStudio7Generator::SetGeneratorPlatform("", mf); +} + +cm::optional<std::string> const& +cmGlobalVisualStudio8Generator::GetTargetFrameworkVersion() const +{ + return this->DefaultTargetFrameworkVersion; +} + +cm::optional<std::string> const& +cmGlobalVisualStudio8Generator::GetTargetFrameworkIdentifier() const +{ + return this->DefaultTargetFrameworkIdentifier; +} + +cm::optional<std::string> const& +cmGlobalVisualStudio8Generator::GetTargetFrameworkTargetsVersion() const +{ + return this->DefaultTargetFrameworkTargetsVersion; } std::string cmGlobalVisualStudio8Generator::GetGenerateStampList() @@ -245,8 +288,8 @@ void cmGlobalVisualStudio8Generator::WriteProjectConfigurations( std::vector<std::string> mapConfig; const char* dstConfig = i.c_str(); if (target.GetProperty("EXTERNAL_MSPROJECT")) { - if (cmProp m = target.GetProperty("MAP_IMPORTED_CONFIG_" + - cmSystemTools::UpperCase(i))) { + if (cmValue m = target.GetProperty("MAP_IMPORTED_CONFIG_" + + cmSystemTools::UpperCase(i))) { cmExpandList(*m, mapConfig); if (!mapConfig.empty()) { dstConfig = mapConfig[0].c_str(); @@ -287,14 +330,14 @@ bool cmGlobalVisualStudio8Generator::NeedsDeploy( return false; } - if (cmProp prop = target.GetProperty("VS_SOLUTION_DEPLOY")) { + if (cmValue prop = target.GetProperty("VS_SOLUTION_DEPLOY")) { // If set, it dictates behavior return cmIsOn( cmGeneratorExpression::Evaluate(*prop, target.LocalGenerator, config)); } // To be deprecated, disable deployment even if target supports it. - if (cmProp prop = target.GetProperty("VS_NO_SOLUTION_DEPLOY")) { + if (cmValue prop = target.GetProperty("VS_NO_SOLUTION_DEPLOY")) { if (cmIsOn(cmGeneratorExpression::Evaluate(*prop, target.LocalGenerator, config))) { // If true, always disable deployment @@ -370,6 +413,7 @@ static cmVS7FlagTable cmVS8ExtraFlagTable[] = { cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue }, { "PrecompiledHeaderThrough", "Yu", "Precompiled Header Name", "", cmVS7FlagTable::UserValueRequired }, + { "UsePrecompiledHeader", "Y-", "Don't use precompiled header", "0", 0 }, // There is no YX option in the VS8 IDE. // Exception handling mode. If no entries match, it will be FALSE. diff --git a/Source/cmGlobalVisualStudio8Generator.h b/Source/cmGlobalVisualStudio8Generator.h index 96e3553f2..b6ecdf07f 100644 --- a/Source/cmGlobalVisualStudio8Generator.h +++ b/Source/cmGlobalVisualStudio8Generator.h @@ -2,6 +2,8 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #pragma once +#include <cm/optional> + #include "cmGlobalVisualStudio71Generator.h" /** \class cmGlobalVisualStudio8Generator @@ -24,6 +26,10 @@ public: bool SetGeneratorPlatform(std::string const& p, cmMakefile* mf) override; + cm::optional<std::string> const& GetTargetFrameworkVersion() const; + cm::optional<std::string> const& GetTargetFrameworkIdentifier() const; + cm::optional<std::string> const& GetTargetFrameworkTargetsVersion() const; + /** * Override Configure and Generate to add the build-system check * target. @@ -76,4 +82,8 @@ protected: std::string Name; std::string WindowsCEVersion; + + cm::optional<std::string> DefaultTargetFrameworkVersion; + cm::optional<std::string> DefaultTargetFrameworkIdentifier; + cm::optional<std::string> DefaultTargetFrameworkTargetsVersion; }; diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx index cdecea03a..f9bd67e08 100644 --- a/Source/cmGlobalVisualStudioGenerator.cxx +++ b/Source/cmGlobalVisualStudioGenerator.cxx @@ -519,7 +519,7 @@ std::string cmGlobalVisualStudioGenerator::GetUtilityDepend( std::string cmGlobalVisualStudioGenerator::GetStartupProjectName( cmLocalGenerator const* root) const { - cmProp n = root->GetMakefile()->GetProperty("VS_STARTUP_PROJECT"); + cmValue n = root->GetMakefile()->GetProperty("VS_STARTUP_PROJECT"); if (cmNonempty(n)) { std::string startup = *n; if (this->FindTarget(startup)) { @@ -820,7 +820,7 @@ bool cmGlobalVisualStudioGenerator::TargetIsFortranOnly( // This allows the project to control the language choice in // a target with none of its own sources, e.g. when also using // object libraries. - cmProp linkLang = gt->GetProperty("LINKER_LANGUAGE"); + cmValue linkLang = gt->GetProperty("LINKER_LANGUAGE"); if (cmNonempty(linkLang)) { languages.insert(*linkLang); } diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h index 151f39f12..23c8a0290 100644 --- a/Source/cmGlobalVisualStudioGenerator.h +++ b/Source/cmGlobalVisualStudioGenerator.h @@ -167,11 +167,6 @@ protected: void WriteSLNHeader(std::ostream& fout); - FindMakeProgramStage GetFindMakeProgramStage() const override - { - return FindMakeProgramStage::Early; - } - bool ComputeTargetDepends() override; class VSDependSet : public std::set<std::string> { @@ -201,7 +196,7 @@ protected: private: virtual std::string GetVSMakeProgram() = 0; void PrintCompilerAdvice(std::ostream&, std::string const&, - const char*) const override + cmValue) const override { } diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.cxx b/Source/cmGlobalVisualStudioVersionedGenerator.cxx index d0ad53e98..b5a6b9fdc 100644 --- a/Source/cmGlobalVisualStudioVersionedGenerator.cxx +++ b/Source/cmGlobalVisualStudioVersionedGenerator.cxx @@ -401,6 +401,12 @@ cmGlobalVisualStudioVersionedGenerator::cmGlobalVisualStudioVersionedGenerator( this->DefaultPlatformName = VSHostPlatformName(); this->DefaultPlatformToolsetHostArchitecture = VSHostArchitecture(); } + if (this->Version >= cmGlobalVisualStudioGenerator::VS17) { + // FIXME: Search for an existing framework? Under '%ProgramFiles(x86)%', + // see 'Reference Assemblies\Microsoft\Framework\.NETFramework'. + // Use a version installed by VS 2022 without a separate component. + this->DefaultTargetFrameworkVersion = "v4.7.2"; + } } bool cmGlobalVisualStudioVersionedGenerator::MatchesGeneratorName( @@ -436,6 +442,11 @@ bool cmGlobalVisualStudioVersionedGenerator::MatchesGeneratorName( bool cmGlobalVisualStudioVersionedGenerator::SetGeneratorInstance( std::string const& i, cmMakefile* mf) { + if (this->LastGeneratorInstanceString && + i == *(this->LastGeneratorInstanceString)) { + return true; + } + if (!i.empty()) { if (!this->vsSetupAPIHelper.SetVSInstance(i)) { std::ostringstream e; @@ -467,11 +478,16 @@ bool cmGlobalVisualStudioVersionedGenerator::SetGeneratorInstance( // Save the selected instance persistently. std::string genInstance = mf->GetSafeDefinition("CMAKE_GENERATOR_INSTANCE"); if (vsInstance != genInstance) { - this->CMakeInstance->AddCacheEntry( - "CMAKE_GENERATOR_INSTANCE", vsInstance.c_str(), - "Generator instance identifier.", cmStateEnums::INTERNAL); + this->CMakeInstance->AddCacheEntry("CMAKE_GENERATOR_INSTANCE", vsInstance, + "Generator instance identifier.", + cmStateEnums::INTERNAL); } + // The selected instance may have a different MSBuild than previously found. + this->MSBuildCommandInitialized = false; + + this->LastGeneratorInstanceString = i; + return true; } @@ -712,6 +728,17 @@ cmGlobalVisualStudioVersionedGenerator::GetWindows10SDKMaxVersionDefault( return std::string(); } +cm::optional<std::string> +cmGlobalVisualStudioVersionedGenerator::FindMSBuildCommandEarly(cmMakefile* mf) +{ + std::string instance = mf->GetSafeDefinition("CMAKE_GENERATOR_INSTANCE"); + if (!this->SetGeneratorInstance(instance, mf)) { + cmSystemTools::SetFatalErrorOccured(); + return {}; + } + return this->cmGlobalVisualStudio14Generator::FindMSBuildCommandEarly(mf); +} + std::string cmGlobalVisualStudioVersionedGenerator::FindMSBuildCommand() { std::string msbuild; diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.h b/Source/cmGlobalVisualStudioVersionedGenerator.h index f07492dff..2aed65b87 100644 --- a/Source/cmGlobalVisualStudioVersionedGenerator.h +++ b/Source/cmGlobalVisualStudioVersionedGenerator.h @@ -8,6 +8,8 @@ #include <memory> #include <string> +#include <cm/optional> + #include "cmGlobalVisualStudio14Generator.h" #include "cmVSSetupHelper.h" @@ -29,6 +31,8 @@ public: bool GetVSInstance(std::string& dir) const; + cm::optional<std::string> FindMSBuildCommandEarly(cmMakefile* mf) override; + cm::optional<std::string> GetVSInstanceVersion() const override; AuxToolset FindAuxToolset(std::string& version, @@ -72,4 +76,5 @@ private: class Factory17; friend class Factory17; mutable cmVSSetupAPIHelper vsSetupAPIHelper; + cm::optional<std::string> LastGeneratorInstanceString; }; diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 77403b076..f34ef6270 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -431,14 +431,7 @@ void cmGlobalXCodeGenerator::EnableLanguage( { mf->AddDefinition("XCODE", "1"); mf->AddDefinition("XCODE_VERSION", this->VersionString); - if (!mf->GetDefinition("CMAKE_CONFIGURATION_TYPES")) { - mf->AddCacheDefinition( - "CMAKE_CONFIGURATION_TYPES", "Debug;Release;MinSizeRel;RelWithDebInfo", - "Semicolon separated list of supported configuration types, " - "only supports Debug, Release, MinSizeRel, and RelWithDebInfo, " - "anything else will be ignored.", - cmStateEnums::STRING); - } + mf->InitCMAKE_CONFIGURATION_TYPES("Debug;Release;MinSizeRel;RelWithDebInfo"); mf->AddDefinition("CMAKE_GENERATOR_NO_COMPILER_ENV", "1"); this->cmGlobalGenerator::EnableLanguage(lang, mf, optional); this->ComputeArchitectures(mf); @@ -948,11 +941,11 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFile( gtgt->AddExplicitLanguageFlags(flags, *sf); const std::string COMPILE_FLAGS("COMPILE_FLAGS"); - if (cmProp cflags = sf->GetProperty(COMPILE_FLAGS)) { + if (cmValue cflags = sf->GetProperty(COMPILE_FLAGS)) { lg->AppendFlags(flags, genexInterpreter.Evaluate(*cflags, COMPILE_FLAGS)); } const std::string COMPILE_OPTIONS("COMPILE_OPTIONS"); - if (cmProp coptions = sf->GetProperty(COMPILE_OPTIONS)) { + if (cmValue coptions = sf->GetProperty(COMPILE_OPTIONS)) { lg->AppendCompileOptions( flags, genexInterpreter.Evaluate(*coptions, COMPILE_OPTIONS)); } @@ -960,7 +953,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFile( // Add per-source definitions. BuildObjectListOrString flagsBuild(this, false); const std::string COMPILE_DEFINITIONS("COMPILE_DEFINITIONS"); - if (cmProp compile_defs = sf->GetProperty(COMPILE_DEFINITIONS)) { + if (cmValue compile_defs = sf->GetProperty(COMPILE_DEFINITIONS)) { this->AppendDefines( flagsBuild, genexInterpreter.Evaluate(*compile_defs, COMPILE_DEFINITIONS).c_str(), @@ -981,7 +974,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFile( // Add per-source include directories. std::vector<std::string> includes; const std::string INCLUDE_DIRECTORIES("INCLUDE_DIRECTORIES"); - if (cmProp cincludes = sf->GetProperty(INCLUDE_DIRECTORIES)) { + if (cmValue cincludes = sf->GetProperty(INCLUDE_DIRECTORIES)) { lg->AppendIncludeDirectories( includes, genexInterpreter.Evaluate(*cincludes, INCLUDE_DIRECTORIES), *sf); @@ -1013,7 +1006,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFile( } // Add user-specified file attributes. - cmProp extraFileAttributes = sf->GetProperty("XCODE_FILE_ATTRIBUTES"); + cmValue extraFileAttributes = sf->GetProperty("XCODE_FILE_ATTRIBUTES"); if (extraFileAttributes) { // Expand the list of attributes. std::vector<std::string> attributes = cmExpandedList(*extraFileAttributes); @@ -1104,7 +1097,7 @@ std::string GetSourcecodeValueFromFileExtension( } else if (ext == "h") { sourcecode += ".c.h"; } else if (ext == "hxx" || ext == "hpp" || ext == "txx" || ext == "pch" || - ext == "hh") { + ext == "hh" || ext == "inl") { sourcecode += ".cpp.h"; } else if (ext == "png" || ext == "gif" || ext == "jpg") { keepLastKnownFileType = true; @@ -1201,9 +1194,9 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeFileReferenceFromPath( bool useLastKnownFileType = false; std::string fileType; if (sf) { - if (cmProp e = sf->GetProperty("XCODE_EXPLICIT_FILE_TYPE")) { + if (cmValue e = sf->GetProperty("XCODE_EXPLICIT_FILE_TYPE")) { fileType = *e; - } else if (cmProp l = sf->GetProperty("XCODE_LAST_KNOWN_FILE_TYPE")) { + } else if (cmValue l = sf->GetProperty("XCODE_LAST_KNOWN_FILE_TYPE")) { useLastKnownFileType = true; fileType = *l; } @@ -1674,7 +1667,7 @@ void cmGlobalXCodeGenerator::ForceLinkerLanguage(cmGeneratorTarget* gtgt) fout << "\n"; } if (cmSourceFile* sf = mf->GetOrCreateSource(fname)) { - sf->SetProperty("LANGUAGE", llang.c_str()); + sf->SetProperty("LANGUAGE", llang); gtgt->AddSource(fname); } } @@ -1763,9 +1756,6 @@ void cmGlobalXCodeGenerator::CreateCustomCommands( if (sourceFile->GetCustomCommand() && visited.insert(sourceFile).second) { commands.push_back(*sourceFile->GetCustomCommand()); - if (this->XcodeBuildSystem >= BuildSystem::Twelve) { - this->CustomCommandRoots[sourceFile].insert(gtgt); - } } } // create custom commands phase @@ -2420,7 +2410,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt, this->CurrentLocalGenerator->GetStaticLibraryFlags( extraLinkOptions, configName, llang, gtgt); } else { - cmProp targetLinkFlags = gtgt->GetProperty("LINK_FLAGS"); + cmValue targetLinkFlags = gtgt->GetProperty("LINK_FLAGS"); if (targetLinkFlags) { this->CurrentLocalGenerator->AppendFlags(extraLinkOptions, *targetLinkFlags); @@ -2428,7 +2418,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt, if (!configName.empty()) { std::string linkFlagsVar = cmStrCat("LINK_FLAGS_", cmSystemTools::UpperCase(configName)); - if (cmProp linkFlags = gtgt->GetProperty(linkFlagsVar)) { + if (cmValue linkFlags = gtgt->GetProperty(linkFlagsVar)) { this->CurrentLocalGenerator->AppendFlags(extraLinkOptions, *linkFlags); } } @@ -2465,8 +2455,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt, std::string pnsuffix; gtgt->GetFullNameComponents(pnprefix, pnbase, pnsuffix, configName); - cmProp version = gtgt->GetProperty("VERSION"); - cmProp soversion = gtgt->GetProperty("SOVERSION"); + cmValue version = gtgt->GetProperty("VERSION"); + cmValue soversion = gtgt->GetProperty("SOVERSION"); if (!gtgt->HasSOName(configName) || gtgt->IsFrameworkOnApple()) { version = nullptr; soversion = nullptr; @@ -2530,7 +2520,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt, std::string fw_version = gtgt->GetFrameworkVersion(); buildSettings->AddAttribute("FRAMEWORK_VERSION", this->CreateString(fw_version)); - cmProp ext = gtgt->GetProperty("BUNDLE_EXTENSION"); + cmValue ext = gtgt->GetProperty("BUNDLE_EXTENSION"); if (ext) { buildSettings->AddAttribute("WRAPPER_EXTENSION", this->CreateString(*ext)); @@ -2571,7 +2561,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt, extraLinkOptions += " "; extraLinkOptions += createFlags; } - cmProp ext = gtgt->GetProperty("BUNDLE_EXTENSION"); + cmValue ext = gtgt->GetProperty("BUNDLE_EXTENSION"); if (ext) { buildSettings->AddAttribute("WRAPPER_EXTENSION", this->CreateString(*ext)); @@ -2605,7 +2595,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt, std::string fw_version = gtgt->GetFrameworkVersion(); buildSettings->AddAttribute("FRAMEWORK_VERSION", this->CreateString(fw_version)); - cmProp ext = gtgt->GetProperty("BUNDLE_EXTENSION"); + cmValue ext = gtgt->GetProperty("BUNDLE_EXTENSION"); if (ext) { buildSettings->AddAttribute("WRAPPER_EXTENSION", this->CreateString(*ext)); @@ -2644,7 +2634,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt, // Handle bundles and normal executables separately. if (gtgt->GetPropertyAsBool("MACOSX_BUNDLE")) { - cmProp ext = gtgt->GetProperty("BUNDLE_EXTENSION"); + cmValue ext = gtgt->GetProperty("BUNDLE_EXTENSION"); if (ext) { buildSettings->AddAttribute("WRAPPER_EXTENSION", this->CreateString(*ext)); @@ -3090,7 +3080,7 @@ const char* cmGlobalXCodeGenerator::GetTargetLinkFlagsVar( const char* cmGlobalXCodeGenerator::GetTargetFileType( cmGeneratorTarget* target) { - if (cmProp e = target->GetProperty("XCODE_EXPLICIT_FILE_TYPE")) { + if (cmValue e = target->GetProperty("XCODE_EXPLICIT_FILE_TYPE")) { return e->c_str(); } @@ -3123,7 +3113,7 @@ const char* cmGlobalXCodeGenerator::GetTargetFileType( const char* cmGlobalXCodeGenerator::GetTargetProductType( cmGeneratorTarget* target) { - if (cmProp e = target->GetProperty("XCODE_PRODUCT_TYPE")) { + if (cmValue e = target->GetProperty("XCODE_PRODUCT_TYPE")) { return e->c_str(); } @@ -3242,15 +3232,14 @@ std::string cmGlobalXCodeGenerator::GetOrCreateId(const std::string& name, const std::string& id) { std::string guidStoreName = cmStrCat(name, "_GUID_CMAKE"); - cmProp storedGUID = this->CMakeInstance->GetCacheDefinition(guidStoreName); + cmValue storedGUID = this->CMakeInstance->GetCacheDefinition(guidStoreName); if (storedGUID) { return *storedGUID; } - this->CMakeInstance->AddCacheEntry(guidStoreName, id.c_str(), - "Stored Xcode object GUID", - cmStateEnums::INTERNAL); + this->CMakeInstance->AddCacheEntry( + guidStoreName, id, "Stored Xcode object GUID", cmStateEnums::INTERNAL); return id; } @@ -3419,7 +3408,7 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target) std::map<std::string, std::vector<std::string>> targetProductNameMap; bool useLinkPhase = false; bool forceLinkPhase = false; - cmProp prop = + cmValue prop = target->GetTarget()->GetProperty("XCODE_LINK_BUILD_PHASE_MODE"); if (prop) { if (*prop == "BUILT_ONLY") { @@ -3792,7 +3781,7 @@ void cmGlobalXCodeGenerator::AddEmbeddedObjects( if (!(isFrameworkTarget || isBundleTarget || isCFBundleTarget)) { return; } - cmProp files = gt->GetProperty(embedPropertyName); + cmValue files = gt->GetProperty(embedPropertyName); if (!files) { return; } @@ -3807,7 +3796,7 @@ void cmGlobalXCodeGenerator::AddEmbeddedObjects( this->CreateString(dstSubfolderSpec)); copyFilesBuildPhase->AddAttribute( "name", this->CreateString(copyFilesBuildPhaseName)); - if (cmProp fwEmbedPath = + if (cmValue fwEmbedPath = gt->GetProperty(cmStrCat(embedPropertyName, "_PATH"))) { copyFilesBuildPhase->AddAttribute("dstPath", this->CreateString(*fwEmbedPath)); @@ -3817,7 +3806,7 @@ void cmGlobalXCodeGenerator::AddEmbeddedObjects( copyFilesBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing", this->CreateString("0")); cmXCodeObject* buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST); - // Collect all embedded frameworks and add them to build phase + // Collect all embedded frameworks and dylibs and add them to build phase std::vector<std::string> relFiles = cmExpandedList(*files); for (std::string const& relFile : relFiles) { cmXCodeObject* buildFile{ nullptr }; @@ -3847,7 +3836,8 @@ void cmGlobalXCodeGenerator::AddEmbeddedObjects( } else { buildFile = it->second; } - } else if (cmSystemTools::IsPathToFramework(relFile)) { + } else if (cmSystemTools::IsPathToFramework(relFile) || + cmSystemTools::IsPathToMacOSSharedLibrary(relFile)) { // This is a regular string path - create file reference auto it = this->EmbeddedLibRefs.find(relFile); if (it == this->EmbeddedLibRefs.end()) { @@ -3913,6 +3903,8 @@ void cmGlobalXCodeGenerator::AddEmbeddedFrameworks(cmXCodeObject* target) { static const auto dstSubfolderSpec = "10"; + // Despite the name, by default Xcode uses "Embed Frameworks" build phase for + // both frameworks and dynamic libraries this->AddEmbeddedObjects(target, "Embed Frameworks", "XCODE_EMBED_FRAMEWORKS", dstSubfolderSpec, NoActionOnCopyByDefault); @@ -4191,8 +4183,8 @@ bool cmGlobalXCodeGenerator::CreateXCodeObjects( this->CreateString(defaultConfigName)); cmXCodeObject* buildSettings = this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP); - cmProp sysroot = this->CurrentMakefile->GetDefinition("CMAKE_OSX_SYSROOT"); - cmProp deploymentTarget = + cmValue sysroot = this->CurrentMakefile->GetDefinition("CMAKE_OSX_SYSROOT"); + cmValue deploymentTarget = this->CurrentMakefile->GetDefinition("CMAKE_OSX_DEPLOYMENT_TARGET"); if (sysroot) { buildSettings->AddAttribute("SDKROOT", this->CreateString(*sysroot)); @@ -4225,7 +4217,7 @@ bool cmGlobalXCodeGenerator::CreateXCodeObjects( } if (this->GetLanguageEnabled("Swift")) { std::string swiftVersion; - if (cmProp vers = this->CurrentMakefile->GetDefinition( + if (cmValue vers = this->CurrentMakefile->GetDefinition( "CMAKE_Swift_LANGUAGE_VERSION")) { swiftVersion = *vers; } else if (this->XcodeVersion >= 102) { @@ -4348,7 +4340,7 @@ std::string cmGlobalXCodeGenerator::GetObjectsDirectory( void cmGlobalXCodeGenerator::ComputeArchitectures(cmMakefile* mf) { this->Architectures.clear(); - cmProp sysroot = mf->GetDefinition("CMAKE_OSX_SYSROOT"); + cmValue sysroot = mf->GetDefinition("CMAKE_OSX_SYSROOT"); if (sysroot) { mf->GetDefExpandList("CMAKE_OSX_ARCHITECTURES", this->Architectures); } @@ -4361,7 +4353,7 @@ void cmGlobalXCodeGenerator::ComputeArchitectures(cmMakefile* mf) // With no ARCHS we use ONLY_ACTIVE_ARCH and possibly a // platform-specific default ARCHS placeholder value. // Look up the arch that Xcode chooses in this case. - if (cmProp arch = mf->GetDefinition("CMAKE_XCODE_ARCHS")) { + if (cmValue arch = mf->GetDefinition("CMAKE_XCODE_ARCHS")) { this->ObjectDirArchDefault = *arch; // We expect only one arch but choose the first just in case. std::string::size_type pos = this->ObjectDirArchDefault.find(';'); @@ -4555,7 +4547,7 @@ bool cmGlobalXCodeGenerator::OutputXCodeSharedSchemes( continue; } - cmProp testee = obj->GetTarget()->GetProperty("XCTEST_TESTEE"); + cmValue testee = obj->GetTarget()->GetProperty("XCTEST_TESTEE"); if (!testee) { continue; } @@ -4738,7 +4730,7 @@ std::string cmGlobalXCodeGenerator::LookupFlags( { if (!varNameLang.empty()) { std::string varName = cmStrCat(varNamePrefix, varNameLang, varNameSuffix); - if (cmProp varValue = this->CurrentMakefile->GetDefinition(varName)) { + if (cmValue varValue = this->CurrentMakefile->GetDefinition(varName)) { if (!varValue->empty()) { return *varValue; } @@ -4860,7 +4852,7 @@ bool cmGlobalXCodeGenerator::HasKnownObjectFileLocation( bool cmGlobalXCodeGenerator::UseEffectivePlatformName(cmMakefile* mf) const { - cmProp epnValue = this->GetCMakeInstance()->GetState()->GetGlobalProperty( + cmValue epnValue = this->GetCMakeInstance()->GetState()->GetGlobalProperty( "XCODE_EMIT_EFFECTIVE_PLATFORM_NAME"); if (!epnValue) { diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h index 1e1b344c9..4d7ee9010 100644 --- a/Source/cmGlobalXCodeGenerator.h +++ b/Source/cmGlobalXCodeGenerator.h @@ -138,11 +138,6 @@ protected: void AddExtraIDETargets() override; void Generate() override; - FindMakeProgramStage GetFindMakeProgramStage() const override - { - return FindMakeProgramStage::Early; - } - private: enum EmbedActionFlags { @@ -327,7 +322,7 @@ private: bool XcodeBuildCommandInitialized; void PrintCompilerAdvice(std::ostream&, std::string const&, - const char*) const override + cmValue) const override { } diff --git a/Source/cmGraphVizWriter.cxx b/Source/cmGraphVizWriter.cxx index 122bda52d..ab18e2a66 100644 --- a/Source/cmGraphVizWriter.cxx +++ b/Source/cmGraphVizWriter.cxx @@ -17,11 +17,11 @@ #include "cmLinkItem.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" -#include "cmProperty.h" #include "cmState.h" #include "cmStateSnapshot.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" #include "cmake.h" namespace { @@ -232,7 +232,7 @@ void cmGraphVizWriter::ReadSettings( #define set_if_set(var, cmakeDefinition) \ do { \ - cmProp value = mf.GetDefinition(cmakeDefinition); \ + cmValue value = mf.GetDefinition(cmakeDefinition); \ if (value) { \ (var) = *value; \ } \ @@ -244,7 +244,7 @@ void cmGraphVizWriter::ReadSettings( #define set_bool_if_set(var, cmakeDefinition) \ do { \ - cmProp value = mf.GetDefinition(cmakeDefinition); \ + cmValue value = mf.GetDefinition(cmakeDefinition); \ if (value) { \ (var) = cmIsOn(*value); \ } \ diff --git a/Source/cmIncludeCommand.cxx b/Source/cmIncludeCommand.cxx index ce1f030be..7b0320c1f 100644 --- a/Source/cmIncludeCommand.cxx +++ b/Source/cmIncludeCommand.cxx @@ -120,6 +120,7 @@ bool cmIncludeCommand(std::vector<std::string> const& args, case cmPolicies::WARN: e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0024) << "\n"; modal = "should"; + CM_FALLTHROUGH; case cmPolicies::OLD: break; case cmPolicies::REQUIRED_IF_USED: diff --git a/Source/cmIncludeDirectoryCommand.cxx b/Source/cmIncludeDirectoryCommand.cxx index b408f7210..23427a1a5 100644 --- a/Source/cmIncludeDirectoryCommand.cxx +++ b/Source/cmIncludeDirectoryCommand.cxx @@ -13,6 +13,7 @@ #include "cmMakefile.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" static void GetIncludes(cmMakefile& mf, const std::string& arg, std::vector<std::string>& incs); diff --git a/Source/cmIncludeExternalMSProjectCommand.cxx b/Source/cmIncludeExternalMSProjectCommand.cxx index 5b532ce0f..c8b4a39e7 100644 --- a/Source/cmIncludeExternalMSProjectCommand.cxx +++ b/Source/cmIncludeExternalMSProjectCommand.cxx @@ -77,9 +77,8 @@ bool cmIncludeExternalMSProjectCommand(std::vector<std::string> const& args, if (!customGuid.empty()) { std::string guidVariable = utility_name + "_GUID_CMAKE"; - mf.GetCMakeInstance()->AddCacheEntry(guidVariable, customGuid.c_str(), - "Stored GUID", - cmStateEnums::INTERNAL); + mf.GetCMakeInstance()->AddCacheEntry( + guidVariable, customGuid, "Stored GUID", cmStateEnums::INTERNAL); } // Create a target instance for this utility. diff --git a/Source/cmIncludeGuardCommand.cxx b/Source/cmIncludeGuardCommand.cxx index aefd0985f..e0a6958dd 100644 --- a/Source/cmIncludeGuardCommand.cxx +++ b/Source/cmIncludeGuardCommand.cxx @@ -7,6 +7,7 @@ #include "cmStateDirectory.h" #include "cmStateSnapshot.h" #include "cmSystemTools.h" +#include "cmValue.h" #include "cmake.h" namespace { diff --git a/Source/cmIncludeRegularExpressionCommand.cxx b/Source/cmIncludeRegularExpressionCommand.cxx index 655ebd6e4..cdcc7df71 100644 --- a/Source/cmIncludeRegularExpressionCommand.cxx +++ b/Source/cmIncludeRegularExpressionCommand.cxx @@ -14,7 +14,7 @@ bool cmIncludeRegularExpressionCommand(std::vector<std::string> const& args, } cmMakefile& mf = status.GetMakefile(); - mf.SetIncludeRegularExpression(args[0].c_str()); + mf.SetIncludeRegularExpression(args[0]); if (args.size() > 1) { mf.SetComplainRegularExpression(args[1]); diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx index 79109b508..eaf88f64a 100644 --- a/Source/cmInstallCommand.cxx +++ b/Source/cmInstallCommand.cxx @@ -35,7 +35,7 @@ #include "cmMakefile.h" #include "cmMessageType.h" #include "cmPolicies.h" -#include "cmProperty.h" +#include "cmRange.h" #include "cmRuntimeDependencyArchive.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" @@ -43,6 +43,7 @@ #include "cmSystemTools.h" #include "cmTarget.h" #include "cmTargetExport.h" +#include "cmValue.h" namespace { @@ -681,8 +682,8 @@ bool HandleTargetsMode(std::vector<std::string> const& args, te->LibraryGenerator = libraryGenerator.get(); te->RuntimeGenerator = runtimeGenerator.get(); te->ObjectsGenerator = objectGenerator.get(); - te->InterfaceIncludeDirectories = - cmJoin(includesArgs.GetIncludeDirs(), ";"); + target.AddInstallIncludeDirectories( + cmMakeRange(includesArgs.GetIncludeDirs())); te->NamelinkOnly = namelinkOnly; helper.Makefile->GetGlobalGenerator() ->GetExportSets()[exports] @@ -925,7 +926,7 @@ bool HandleTargetsMode(std::vector<std::string> const& args, } if (createInstallGeneratorsForTargetFileSets && !namelinkOnly) { - cmProp files = target.GetProperty("PRIVATE_HEADER"); + cmValue files = target.GetProperty("PRIVATE_HEADER"); if (cmNonempty(files)) { std::vector<std::string> relFiles = cmExpandedList(*files); std::vector<std::string> absFiles; @@ -1390,6 +1391,7 @@ bool HandleFilesMode(std::vector<std::string> const& args, case cmPolicies::WARN: e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0062) << "\n"; modal = "should"; + CM_FALLTHROUGH; case cmPolicies::OLD: break; case cmPolicies::REQUIRED_IF_USED: @@ -1397,6 +1399,7 @@ bool HandleFilesMode(std::vector<std::string> const& args, case cmPolicies::NEW: modal = "may"; messageType = MessageType::FATAL_ERROR; + break; } if (modal) { e << "The file\n " << file diff --git a/Source/cmInstallMode.h b/Source/cmInstallMode.h new file mode 100644 index 000000000..5343d34a4 --- /dev/null +++ b/Source/cmInstallMode.h @@ -0,0 +1,17 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#pragma once + +/** + * Enumerate types known to file(INSTALL). + */ +enum class cmInstallMode +{ + COPY, + ABS_SYMLINK, + ABS_SYMLINK_OR_COPY, + REL_SYMLINK, + REL_SYMLINK_OR_COPY, + SYMLINK, + SYMLINK_OR_COPY +}; diff --git a/Source/cmInstallSubdirectoryGenerator.cxx b/Source/cmInstallSubdirectoryGenerator.cxx index 794694ea3..0a8e065b5 100644 --- a/Source/cmInstallSubdirectoryGenerator.cxx +++ b/Source/cmInstallSubdirectoryGenerator.cxx @@ -57,6 +57,7 @@ void cmInstallSubdirectoryGenerator::GenerateScript(std::ostream& os) this->LocalGenerator->GetPolicyStatus(cmPolicies::CMP0082); switch (status) { case cmPolicies::WARN: + CM_FALLTHROUGH; case cmPolicies::OLD: // OLD behavior is handled in cmLocalGenerator::GenerateInstallRules() break; diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx index 35165cf72..ae11afca9 100644 --- a/Source/cmInstallTargetGenerator.cxx +++ b/Source/cmInstallTargetGenerator.cxx @@ -2,11 +2,13 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmInstallTargetGenerator.h" +#include <algorithm> #include <cassert> #include <map> #include <set> #include <sstream> #include <utility> +#include <vector> #include "cmComputeLinkInformation.h" #include "cmGeneratorExpression.h" @@ -18,11 +20,11 @@ #include "cmMessageType.h" #include "cmOutputConverter.h" #include "cmPolicies.h" -#include "cmProperty.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" +#include "cmValue.h" #include "cmake.h" namespace { @@ -208,7 +210,7 @@ cmInstallTargetGenerator::Files cmInstallTargetGenerator::GetFiles( // Get App Bundle Extension std::string ext; - if (cmProp p = this->Target->GetProperty("BUNDLE_EXTENSION")) { + if (cmValue p = this->Target->GetProperty("BUNDLE_EXTENSION")) { ext = *p; } else { ext = "app"; @@ -680,33 +682,52 @@ void cmInstallTargetGenerator::AddChrpathPatchRule( " this limitation."; mf->IssueMessage(MessageType::WARNING, msg.str()); } else { - // Note: These paths are kept unique to avoid - // install_name_tool corruption. - std::set<std::string> runpaths; - for (std::string const& i : oldRuntimeDirs) { - std::string runpath = - mf->GetGlobalGenerator()->ExpandCFGIntDir(i, config); - - if (runpaths.find(runpath) == runpaths.end()) { - runpaths.insert(runpath); - os << indent << "execute_process(COMMAND " << installNameTool - << "\n"; - os << indent << " -delete_rpath \"" << runpath << "\"\n"; - os << indent << " \"" << toDestDirPath << "\")\n"; + // To be consistent with older versions, runpath changes must be ordered, + // deleted first, then added, *and* the same path must only appear once. + std::map<std::string, std::string> runpath_change; + std::vector<std::string> ordered; + for (std::string const& dir : oldRuntimeDirs) { + // Normalize path and add to map of changes to make + auto iter_inserted = runpath_change.insert( + { mf->GetGlobalGenerator()->ExpandCFGIntDir(dir, config), + "delete" }); + if (iter_inserted.second) { + // Add path to ordered list of changes + ordered.push_back(iter_inserted.first->first); } } - runpaths.clear(); - for (std::string const& i : newRuntimeDirs) { - std::string runpath = - mf->GetGlobalGenerator()->ExpandCFGIntDir(i, config); + for (std::string const& dir : newRuntimeDirs) { + // Normalize path and add to map of changes to make + auto iter_inserted = runpath_change.insert( + { mf->GetGlobalGenerator()->ExpandCFGIntDir(dir, config), "add" }); + if (iter_inserted.second) { + // Add path to ordered list of changes + ordered.push_back(iter_inserted.first->first); + } else if (iter_inserted.first->second != "add") { + // Rpath was requested to be deleted and then later re-added. Drop it + // from the list by marking as an empty value. + iter_inserted.first->second.clear(); + } + } - if (runpaths.find(runpath) == runpaths.end()) { - os << indent << "execute_process(COMMAND " << installNameTool - << "\n"; - os << indent << " -add_rpath \"" << runpath << "\"\n"; - os << indent << " \"" << toDestDirPath << "\")\n"; + // Remove rpaths that are unchanged (value was set to empty) + ordered.erase( + std::remove_if(ordered.begin(), ordered.end(), + [&runpath_change](const std::string& runpath) { + return runpath_change.find(runpath)->second.empty(); + }), + ordered.end()); + + if (!ordered.empty()) { + os << indent << "execute_process(COMMAND " << installNameTool << "\n"; + for (std::string const& runpath : ordered) { + // Either 'add_rpath' or 'delete_rpath' since we've removed empty + // entries + os << indent << " -" << runpath_change.find(runpath)->second + << "_rpath \"" << runpath << "\"\n"; } + os << indent << " \"" << toDestDirPath << "\")\n"; } } } else { @@ -825,7 +846,7 @@ void cmInstallTargetGenerator::AddUniversalInstallRule( return; } - cmProp xcodeVersion = mf->GetDefinition("XCODE_VERSION"); + cmValue xcodeVersion = mf->GetDefinition("XCODE_VERSION"); if (!xcodeVersion || cmSystemTools::VersionCompareGreater("6", *xcodeVersion)) { return; diff --git a/Source/cmInstalledFile.cxx b/Source/cmInstalledFile.cxx index 32395d10e..0974eea56 100644 --- a/Source/cmInstalledFile.cxx +++ b/Source/cmInstalledFile.cxx @@ -8,6 +8,7 @@ #include "cmListFileCache.h" #include "cmMakefile.h" #include "cmStringAlgorithms.h" +#include "cmValue.h" cmInstalledFile::cmInstalledFile() = default; diff --git a/Source/cmLinkDirectoriesCommand.cxx b/Source/cmLinkDirectoriesCommand.cxx index 29140462a..1ec071b75 100644 --- a/Source/cmLinkDirectoriesCommand.cxx +++ b/Source/cmLinkDirectoriesCommand.cxx @@ -62,7 +62,7 @@ static void AddLinkDir(cmMakefile& mf, std::string const& dir, case cmPolicies::WARN: e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0015); mf.IssueMessage(MessageType::AUTHOR_WARNING, e.str()); - break; + CM_FALLTHROUGH; case cmPolicies::OLD: // OLD behavior does not convert break; diff --git a/Source/cmLinkItem.cxx b/Source/cmLinkItem.cxx index 4e50d7097..62e7ef425 100644 --- a/Source/cmLinkItem.cxx +++ b/Source/cmLinkItem.cxx @@ -32,7 +32,11 @@ bool operator<(cmLinkItem const& l, cmLinkItem const& r) { // Order among targets. if (l.Target && r.Target) { - return l.Target < r.Target; + if (l.Target != r.Target) { + return l.Target < r.Target; + } + // Order identical targets via cross-config. + return l.Cross < r.Cross; } // Order targets before strings. if (l.Target) { @@ -42,10 +46,10 @@ bool operator<(cmLinkItem const& l, cmLinkItem const& r) return false; } // Order among strings. - if (l.String < r.String) { - return true; + if (l.String != r.String) { + return l.String < r.String; } - // Order among cross-config. + // Order identical strings via cross-config. return l.Cross < r.Cross; } diff --git a/Source/cmLinkLineDeviceComputer.cxx b/Source/cmLinkLineDeviceComputer.cxx index 2ffff96b9..43f161be4 100644 --- a/Source/cmLinkLineDeviceComputer.cxx +++ b/Source/cmLinkLineDeviceComputer.cxx @@ -16,11 +16,11 @@ #include "cmListFileCache.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" -#include "cmProperty.h" #include "cmStateDirectory.h" #include "cmStateSnapshot.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" +#include "cmValue.h" class cmOutputConverter; @@ -177,7 +177,7 @@ bool requireDeviceLinking(cmGeneratorTarget& target, cmLocalGenerator& lg, return false; } - if (cmProp resolveDeviceSymbols = + if (cmValue resolveDeviceSymbols = target.GetProperty("CUDA_RESOLVE_DEVICE_SYMBOLS")) { // If CUDA_RESOLVE_DEVICE_SYMBOLS has been explicitly set we need // to honor the value no matter what it is. diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx index 09cd88e08..7d42fc827 100644 --- a/Source/cmListCommand.cxx +++ b/Source/cmListCommand.cxx @@ -25,12 +25,12 @@ #include "cmMakefile.h" #include "cmMessageType.h" #include "cmPolicies.h" -#include "cmProperty.h" #include "cmRange.h" #include "cmStringAlgorithms.h" #include "cmStringReplaceHelper.h" #include "cmSubcommandTable.h" #include "cmSystemTools.h" +#include "cmValue.h" namespace { @@ -46,7 +46,7 @@ bool GetIndexArg(const std::string& arg, int* idx, cmMakefile& mf) cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0121), " Invalid list index \"", arg, "\"."); mf.IssueMessage(MessageType::AUTHOR_WARNING, warn); - break; + CM_FALLTHROUGH; } case cmPolicies::OLD: // OLD behavior is to allow compatibility, so just ignore the @@ -79,7 +79,7 @@ bool GetListString(std::string& listString, const std::string& var, const cmMakefile& makefile) { // get the old value - cmProp cacheValue = makefile.GetDefinition(var); + cmValue cacheValue = makefile.GetDefinition(var); if (!cacheValue) { return false; } diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx index 4f7c95944..2e444f229 100644 --- a/Source/cmListFileCache.cxx +++ b/Source/cmListFileCache.cxx @@ -548,7 +548,7 @@ void cmListFileBacktrace::PrintTitle(std::ostream& out) const } cmListFileContext lfc = this->TopEntry->Context; cmStateSnapshot bottom = this->GetBottom(); - if (!bottom.GetState()->GetIsInTryCompile()) { + if (bottom.GetState()->GetProjectKind() == cmState::ProjectKind::Normal) { lfc.FilePath = cmSystemTools::RelativeIfUnder( bottom.GetState()->GetSourceDirectory(), lfc.FilePath); } @@ -579,7 +579,7 @@ void cmListFileBacktrace::PrintCallStack(std::ostream& out) const out << "Call Stack (most recent call first):\n"; } cmListFileContext lfc = cur->Context; - if (!bottom.GetState()->GetIsInTryCompile()) { + if (bottom.GetState()->GetProjectKind() == cmState::ProjectKind::Normal) { lfc.FilePath = cmSystemTools::RelativeIfUnder( bottom.GetState()->GetSourceDirectory(), lfc.FilePath); } diff --git a/Source/cmLocalCommonGenerator.cxx b/Source/cmLocalCommonGenerator.cxx index 211525a26..eca7a9eb6 100644 --- a/Source/cmLocalCommonGenerator.cxx +++ b/Source/cmLocalCommonGenerator.cxx @@ -8,11 +8,11 @@ #include "cmGeneratorTarget.h" #include "cmMakefile.h" #include "cmOutputConverter.h" -#include "cmProperty.h" #include "cmState.h" #include "cmStateDirectory.h" #include "cmStateSnapshot.h" #include "cmStringAlgorithms.h" +#include "cmValue.h" class cmGlobalGenerator; @@ -82,7 +82,7 @@ std::string cmLocalCommonGenerator::GetTargetFortranFlags( // If there is a separate module path flag then duplicate the // include path with it. This compiler does not search the include // path for modules. - if (cmProp modpath_flag = + if (cmValue modpath_flag = this->Makefile->GetDefinition("CMAKE_Fortran_MODPATH_FLAG")) { std::vector<std::string> includes; this->GetIncludeDirectories(includes, target, "C", config); diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 3b282de98..fc5e6e5f1 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -37,7 +37,6 @@ #include "cmInstallTargetGenerator.h" #include "cmLinkLineComputer.h" #include "cmMakefile.h" -#include "cmProperty.h" #include "cmRulePlaceholderExpander.h" #include "cmSourceFile.h" #include "cmSourceFileLocation.h" @@ -50,6 +49,7 @@ #include "cmSystemTools.h" #include "cmTarget.h" #include "cmTestGenerator.h" +#include "cmValue.h" #include "cmVersion.h" #include "cmake.h" @@ -107,10 +107,9 @@ cmLocalGenerator::cmLocalGenerator(cmGlobalGenerator* gg, cmMakefile* makefile) { std::vector<std::string> cpath; cmSystemTools::GetPath(cpath, "CPATH"); - for (std::string& cp : cpath) { + for (std::string const& cp : cpath) { if (cmSystemTools::FileIsFullPath(cp)) { - cp = cmSystemTools::CollapseFullPath(cp); - this->EnvCPATH.emplace(std::move(cp)); + this->EnvCPATH.emplace_back(cmSystemTools::CollapseFullPath(cp)); } } } @@ -118,21 +117,21 @@ cmLocalGenerator::cmLocalGenerator(cmGlobalGenerator* gg, cmMakefile* makefile) std::vector<std::string> enabledLanguages = this->GetState()->GetEnabledLanguages(); - if (cmProp sysrootCompile = + if (cmValue sysrootCompile = this->Makefile->GetDefinition("CMAKE_SYSROOT_COMPILE")) { this->CompilerSysroot = *sysrootCompile; } else { this->CompilerSysroot = this->Makefile->GetSafeDefinition("CMAKE_SYSROOT"); } - if (cmProp sysrootLink = + if (cmValue sysrootLink = this->Makefile->GetDefinition("CMAKE_SYSROOT_LINK")) { this->LinkerSysroot = *sysrootLink; } else { this->LinkerSysroot = this->Makefile->GetSafeDefinition("CMAKE_SYSROOT"); } - if (cmProp appleArchSysroots = + if (cmValue appleArchSysroots = this->Makefile->GetDefinition("CMAKE_APPLE_ARCH_SYSROOTS")) { std::string const& appleArchs = this->Makefile->GetSafeDefinition("CMAKE_OSX_ARCHITECTURES"); @@ -222,7 +221,7 @@ void cmLocalGenerator::ComputeObjectMaxPath() #else this->ObjectPathMax = 1000; #endif - cmProp plen = this->Makefile->GetDefinition("CMAKE_OBJECT_PATH_MAX"); + cmValue plen = this->Makefile->GetDefinition("CMAKE_OBJECT_PATH_MAX"); if (cmNonempty(plen)) { unsigned int pmax; if (sscanf(plen->c_str(), "%u", &pmax) == 1) { @@ -330,12 +329,12 @@ void cmLocalGenerator::GenerateTestFiles() fout << "set(CTEST_RESOURCE_SPEC_FILE \"" << resourceSpecFile << "\")\n"; } - cmProp testIncludeFile = this->Makefile->GetProperty("TEST_INCLUDE_FILE"); + cmValue testIncludeFile = this->Makefile->GetProperty("TEST_INCLUDE_FILE"); if (testIncludeFile) { fout << "include(\"" << *testIncludeFile << "\")\n"; } - cmProp testIncludeFiles = this->Makefile->GetProperty("TEST_INCLUDE_FILES"); + cmValue testIncludeFiles = this->Makefile->GetProperty("TEST_INCLUDE_FILES"); if (testIncludeFiles) { std::vector<std::string> includesList = cmExpandedList(*testIncludeFiles); for (std::string const& i : includesList) { @@ -359,9 +358,9 @@ void cmLocalGenerator::GenerateTestFiles() } // Add directory labels property - cmProp directoryLabels = + cmValue directoryLabels = this->Makefile->GetDefinition("CMAKE_DIRECTORY_LABELS"); - cmProp labels = this->Makefile->GetProperty("LABELS"); + cmValue labels = this->Makefile->GetProperty("LABELS"); if (labels || directoryLabels) { fout << "set_directory_properties(PROPERTIES LABELS "; @@ -426,27 +425,26 @@ void cmLocalGenerator::ProcessEvaluationFiles( void cmLocalGenerator::GenerateInstallRules() { // Compute the install prefix. - const char* prefix = - cmToCStr(this->Makefile->GetDefinition("CMAKE_INSTALL_PREFIX")); + cmValue installPrefix = + this->Makefile->GetDefinition("CMAKE_INSTALL_PREFIX"); + std::string prefix = installPrefix; #if defined(_WIN32) && !defined(__CYGWIN__) - std::string prefix_win32; - if (!prefix) { - if (!cmSystemTools::GetEnv("SystemDrive", prefix_win32)) { - prefix_win32 = "C:"; + if (!installPrefix) { + if (!cmSystemTools::GetEnv("SystemDrive", prefix)) { + prefix = "C:"; } - cmProp project_name = this->Makefile->GetDefinition("PROJECT_NAME"); + cmValue project_name = this->Makefile->GetDefinition("PROJECT_NAME"); if (cmNonempty(project_name)) { - prefix_win32 += "/Program Files/"; - prefix_win32 += *project_name; + prefix += "/Program Files/"; + prefix += *project_name; } else { - prefix_win32 += "/InstalledCMakeProject"; + prefix += "/InstalledCMakeProject"; } - prefix = prefix_win32.c_str(); } #elif defined(__HAIKU__) char dir[B_PATH_NAME_LENGTH]; - if (!prefix) { + if (!installPrefix) { if (find_directory(B_SYSTEM_DIRECTORY, -1, false, dir, sizeof(dir)) == B_OK) { prefix = dir; @@ -455,13 +453,13 @@ void cmLocalGenerator::GenerateInstallRules() } } #else - if (!prefix) { + if (!installPrefix) { prefix = "/usr/local"; } #endif - if (cmProp stagingPrefix = + if (cmValue stagingPrefix = this->Makefile->GetDefinition("CMAKE_STAGING_PREFIX")) { - prefix = stagingPrefix->c_str(); + prefix = *stagingPrefix; } // Compute the set of configurations. @@ -541,7 +539,7 @@ void cmLocalGenerator::GenerateInstallRules() /* clang-format on */ // Copy user-specified install options to the install code. - if (cmProp so_no_exe = + if (cmValue so_no_exe = this->Makefile->GetDefinition("CMAKE_INSTALL_SO_NO_EXE")) { /* clang-format off */ fout << @@ -554,7 +552,7 @@ void cmLocalGenerator::GenerateInstallRules() } // Copy cmake cross compile state to install code. - if (cmProp crosscompiling = + if (cmValue crosscompiling = this->Makefile->GetDefinition("CMAKE_CROSSCOMPILING")) { /* clang-format off */ fout << @@ -567,7 +565,7 @@ void cmLocalGenerator::GenerateInstallRules() } // Write default directory permissions. - if (cmProp defaultDirPermissions = this->Makefile->GetDefinition( + if (cmValue defaultDirPermissions = this->Makefile->GetDefinition( "CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS")) { /* clang-format off */ fout << @@ -583,7 +581,7 @@ void cmLocalGenerator::GenerateInstallRules() // Write out CMAKE_GET_RUNTIME_DEPENDENCIES_PLATFORM so that // installed code that uses `file(GET_RUNTIME_DEPENDENCIES)` // has same platform variable as when running cmake - if (cmProp platform = this->Makefile->GetDefinition( + if (cmValue platform = this->Makefile->GetDefinition( "CMAKE_GET_RUNTIME_DEPENDENCIES_PLATFORM")) { /* clang-format off */ fout << @@ -599,7 +597,7 @@ void cmLocalGenerator::GenerateInstallRules() // Write out CMAKE_GET_RUNTIME_DEPENDENCIES_TOOL so that // installed code that uses `file(GET_RUNTIME_DEPENDENCIES)` // has same tool selected as when running cmake - if (cmProp command = + if (cmValue command = this->Makefile->GetDefinition("CMAKE_GET_RUNTIME_DEPENDENCIES_TOOL")) { /* clang-format off */ fout << @@ -615,7 +613,7 @@ void cmLocalGenerator::GenerateInstallRules() // Write out CMAKE_GET_RUNTIME_DEPENDENCIES_COMMAND so that // installed code that uses `file(GET_RUNTIME_DEPENDENCIES)` // has same path to the tool as when running cmake - if (cmProp command = this->Makefile->GetDefinition( + if (cmValue command = this->Makefile->GetDefinition( "CMAKE_GET_RUNTIME_DEPENDENCIES_COMMAND")) { /* clang-format off */ fout << @@ -633,7 +631,7 @@ void cmLocalGenerator::GenerateInstallRules() // CMAKE_GET_RUNTIME_DEPENDENCIES_COMMAND has consistent // logic to fallback to CMAKE_OBJDUMP when `objdump` is // not on the path - if (cmProp command = this->Makefile->GetDefinition("CMAKE_OBJDUMP")) { + if (cmValue command = this->Makefile->GetDefinition("CMAKE_OBJDUMP")) { /* clang-format off */ fout << "# Set default install directory permissions.\n" @@ -826,8 +824,8 @@ cmStateSnapshot cmLocalGenerator::GetStateSnapshot() const return this->Makefile->GetStateSnapshot(); } -cmProp cmLocalGenerator::GetRuleLauncher(cmGeneratorTarget* target, - const std::string& prop) +cmValue cmLocalGenerator::GetRuleLauncher(cmGeneratorTarget* target, + const std::string& prop) { if (target) { return target->GetProperty(prop); @@ -859,36 +857,39 @@ std::string cmLocalGenerator::GetIncludeFlags( std::string const& includeFlag = this->Makefile->GetSafeDefinition(cmStrCat("CMAKE_INCLUDE_FLAG_", lang)); - const char* sep = cmToCStr( - this->Makefile->GetDefinition(cmStrCat("CMAKE_INCLUDE_FLAG_SEP_", lang))); bool quotePaths = false; if (this->Makefile->GetDefinition("CMAKE_QUOTE_INCLUDE_PATHS")) { quotePaths = true; } + std::string sep = " "; bool repeatFlag = true; // should the include flag be repeated like ie. -IA -IB - if (!sep) { - sep = " "; - } else { + if (cmValue incSep = this->Makefile->GetDefinition( + cmStrCat("CMAKE_INCLUDE_FLAG_SEP_", lang))) { // if there is a separator then the flag is not repeated but is only // given once i.e. -classpath a:b:c + sep = incSep; repeatFlag = false; } // Support special system include flag if it is available and the // normal flag is repeated for each directory. - cmProp sysIncludeFlag = nullptr; + cmValue sysIncludeFlag = nullptr; + cmValue sysIncludeFlagWarning = nullptr; if (repeatFlag) { sysIncludeFlag = this->Makefile->GetDefinition( cmStrCat("CMAKE_INCLUDE_SYSTEM_FLAG_", lang)); + sysIncludeFlagWarning = this->Makefile->GetDefinition( + cmStrCat("_CMAKE_INCLUDE_SYSTEM_FLAG_", lang, "_WARNING")); } - cmProp fwSearchFlag = this->Makefile->GetDefinition( + cmValue fwSearchFlag = this->Makefile->GetDefinition( cmStrCat("CMAKE_", lang, "_FRAMEWORK_SEARCH_FLAG")); - cmProp sysFwSearchFlag = this->Makefile->GetDefinition( + cmValue sysFwSearchFlag = this->Makefile->GetDefinition( cmStrCat("CMAKE_", lang, "_SYSTEM_FRAMEWORK_SEARCH_FLAG")); bool flagUsed = false; + bool sysIncludeFlagUsed = false; std::set<std::string> emitted; #ifdef __APPLE__ emitted.insert("/System/Library/Frameworks"); @@ -915,6 +916,7 @@ std::string cmLocalGenerator::GetIncludeFlags( if (sysIncludeFlag && target && target->IsSystemIncludeDirectory(i, config, lang)) { includeFlags << *sysIncludeFlag; + sysIncludeFlagUsed = true; } else { includeFlags << includeFlag; } @@ -931,6 +933,9 @@ std::string cmLocalGenerator::GetIncludeFlags( } includeFlags << sep; } + if (sysIncludeFlagUsed && sysIncludeFlagWarning) { + includeFlags << *sysIncludeFlagWarning; + } std::string flags = includeFlags.str(); // remove trailing separators if ((sep[0] != ' ') && !flags.empty() && flags.back() == sep[0]) { @@ -956,10 +961,10 @@ void cmLocalGenerator::AddCompileOptions(std::vector<BT<std::string>>& flags, { std::string langFlagRegexVar = cmStrCat("CMAKE_", lang, "_FLAG_REGEX"); - if (cmProp langFlagRegexStr = + if (cmValue langFlagRegexStr = this->Makefile->GetDefinition(langFlagRegexVar)) { // Filter flags acceptable to this language. - if (cmProp targetFlags = target->GetProperty("COMPILE_FLAGS")) { + if (cmValue targetFlags = target->GetProperty("COMPILE_FLAGS")) { std::vector<std::string> opts; cmSystemTools::ParseWindowsCommandLine(targetFlags->c_str(), opts); // Re-escape these flags since COMPILE_FLAGS were already parsed @@ -977,7 +982,7 @@ void cmLocalGenerator::AddCompileOptions(std::vector<BT<std::string>>& flags, langFlagRegexStr->c_str()); } else { // Use all flags. - if (cmProp targetFlags = target->GetProperty("COMPILE_FLAGS")) { + if (cmValue targetFlags = target->GetProperty("COMPILE_FLAGS")) { // COMPILE_FLAGS are not escaped for historical reasons. std::string compileFlags; this->AppendFlags(compileFlags, *targetFlags); @@ -993,7 +998,7 @@ void cmLocalGenerator::AddCompileOptions(std::vector<BT<std::string>>& flags, cmStandardLevelResolver standardResolver(this->Makefile); for (auto const& it : target->GetMaxLanguageStandards()) { - cmProp standard = target->GetLanguageStandard(it.first, config); + cmValue standard = target->GetLanguageStandard(it.first, config); if (!standard) { continue; } @@ -1024,7 +1029,7 @@ void cmLocalGenerator::AddCompileOptions(std::vector<BT<std::string>>& flags, // Add compile flag for the MSVC compiler only. cmMakefile* mf = this->GetMakefile(); - if (cmProp jmc = + if (cmValue jmc = mf->GetDefinition("CMAKE_" + lang + "_COMPILE_OPTIONS_JMC")) { // Handle Just My Code debugging flags, /JMC. @@ -1033,7 +1038,7 @@ void cmLocalGenerator::AddCompileOptions(std::vector<BT<std::string>>& flags, cmGeneratorTarget::ManagedType::Managed) { // add /JMC flags if target property VS_JUST_MY_CODE_DEBUGGING is set // to ON - if (cmProp jmcExprGen = + if (cmValue jmcExprGen = target->GetProperty("VS_JUST_MY_CODE_DEBUGGING")) { std::string isJMCEnabled = cmGeneratorExpression::Evaluate(*jmcExprGen, this, config); @@ -1239,19 +1244,31 @@ std::vector<BT<std::string>> cmLocalGenerator::GetIncludeDirectoriesImplicit( } } + bool const isCorCxx = (lang == "C" || lang == "CXX"); + + // Resolve symlinks in CPATH for comparison with resolved include paths. + // We do this here instead of when EnvCPATH is populated in case symlinks + // on disk have changed in the meantime. + std::set<std::string> resolvedEnvCPATH; + if (isCorCxx) { + for (std::string const& i : this->EnvCPATH) { + resolvedEnvCPATH.emplace(this->GlobalGenerator->GetRealPath(i)); + } + } + // Checks if this is not an excluded (implicit) include directory. - auto notExcluded = [this, &implicitSet, &implicitExclude, - &lang](std::string const& dir) { - return ( - // Do not exclude directories that are not in an excluded set. - ((!cm::contains(implicitSet, this->GlobalGenerator->GetRealPath(dir))) && - (!cm::contains(implicitExclude, dir))) + auto notExcluded = [this, &implicitSet, &implicitExclude, &resolvedEnvCPATH, + isCorCxx](std::string const& dir) -> bool { + std::string const& real_dir = this->GlobalGenerator->GetRealPath(dir); + return + // Do not exclude directories that are not in any excluded set. + !(cm::contains(implicitSet, real_dir) || + cm::contains(implicitExclude, dir)) // Do not exclude entries of the CPATH environment variable even though // they are implicitly searched by the compiler. They are meant to be // user-specified directories that can be re-ordered or converted to // -isystem without breaking real compiler builtin headers. - || - ((lang == "C" || lang == "CXX") && cm::contains(this->EnvCPATH, dir))); + || (isCorCxx && cm::contains(resolvedEnvCPATH, real_dir)); }; // Get the target-specific include directories. @@ -1480,7 +1497,7 @@ void cmLocalGenerator::GetTargetFlags( } } - cmProp targetLinkFlags = target->GetProperty("LINK_FLAGS"); + cmValue targetLinkFlags = target->GetProperty("LINK_FLAGS"); if (targetLinkFlags) { sharedLibFlags += *targetLinkFlags; sharedLibFlags += " "; @@ -1560,7 +1577,7 @@ void cmLocalGenerator::GetTargetFlags( exeFlags += " "; } - cmProp targetLinkFlags = target->GetProperty("LINK_FLAGS"); + cmValue targetLinkFlags = target->GetProperty("LINK_FLAGS"); if (targetLinkFlags) { exeFlags += *targetLinkFlags; exeFlags += " "; @@ -1656,7 +1673,7 @@ static std::string GetFrameworkFlags(const std::string& lang, } std::string fwSearchFlagVar = "CMAKE_" + lang + "_FRAMEWORK_SEARCH_FLAG"; - cmProp fwSearchFlag = mf->GetDefinition(fwSearchFlagVar); + cmValue fwSearchFlag = mf->GetDefinition(fwSearchFlagVar); if (!cmNonempty(fwSearchFlag)) { return std::string(); } @@ -1765,7 +1782,7 @@ void cmLocalGenerator::OutputLinkLibraries( std::string linkLanguage = cli.GetLinkLanguage(); std::string libPathFlag; - if (cmProp value = this->Makefile->GetDefinition( + if (cmValue value = this->Makefile->GetDefinition( "CMAKE_" + cli.GetLinkLanguage() + "_LIBRARY_PATH_FLAG")) { libPathFlag = *value; } else { @@ -1774,7 +1791,7 @@ void cmLocalGenerator::OutputLinkLibraries( } std::string libPathTerminator; - if (cmProp value = this->Makefile->GetDefinition( + if (cmValue value = this->Makefile->GetDefinition( "CMAKE_" + cli.GetLinkLanguage() + "_LIBRARY_PATH_TERMINATOR")) { libPathTerminator = *value; } else { @@ -1850,17 +1867,17 @@ std::string cmLocalGenerator::GetLinkLibsCMP0065( } bool cmLocalGenerator::AllAppleArchSysrootsAreTheSame( - const std::vector<std::string>& archs, const char* sysroot) + const std::vector<std::string>& archs, cmValue sysroot) { if (!sysroot) { return false; } return std::all_of(archs.begin(), archs.end(), - [this, &sysroot](std::string const& arch) -> bool { + [this, sysroot](std::string const& arch) -> bool { std::string const& archSysroot = this->AppleArchSysroots[arch]; - return cmIsOff(archSysroot) || archSysroot == sysroot; + return cmIsOff(archSysroot) || sysroot == archSysroot; }); } @@ -1885,15 +1902,15 @@ void cmLocalGenerator::AddArchitectureFlags(std::string& flags, } } - cmProp sysroot = this->Makefile->GetDefinition("CMAKE_OSX_SYSROOT"); + cmValue sysroot = this->Makefile->GetDefinition("CMAKE_OSX_SYSROOT"); if (sysroot && *sysroot == "/") { sysroot = nullptr; } std::string sysrootFlagVar = "CMAKE_" + lang + "_SYSROOT_FLAG"; - cmProp sysrootFlag = this->Makefile->GetDefinition(sysrootFlagVar); + cmValue sysrootFlag = this->Makefile->GetDefinition(sysrootFlagVar); if (cmNonempty(sysrootFlag)) { if (!this->AppleArchSysroots.empty() && - !this->AllAppleArchSysrootsAreTheSame(archs, cmToCStr(sysroot))) { + !this->AllAppleArchSysrootsAreTheSame(archs, sysroot)) { for (std::string const& arch : archs) { std::string const& archSysroot = this->AppleArchSysroots[arch]; if (cmIsOff(archSysroot)) { @@ -1914,11 +1931,11 @@ void cmLocalGenerator::AddArchitectureFlags(std::string& flags, } } - cmProp deploymentTarget = + cmValue deploymentTarget = this->Makefile->GetDefinition("CMAKE_OSX_DEPLOYMENT_TARGET"); std::string deploymentTargetFlagVar = "CMAKE_" + lang + "_OSX_DEPLOYMENT_TARGET_FLAG"; - cmProp deploymentTargetFlag = + cmValue deploymentTargetFlag = this->Makefile->GetDefinition(deploymentTargetFlagVar); if (cmNonempty(deploymentTargetFlag) && cmNonempty(deploymentTarget)) { flags += " "; @@ -1943,11 +1960,11 @@ void cmLocalGenerator::AddLanguageFlags(std::string& flags, std::string compilerSimulateId = this->Makefile->GetSafeDefinition( cmStrCat("CMAKE_", lang, "_SIMULATE_ID")); if (lang == "Swift") { - if (cmProp v = target->GetProperty("Swift_LANGUAGE_VERSION")) { - if (cmSystemTools::VersionCompare(cmSystemTools::OP_GREATER_EQUAL, - cmToCStr(this->Makefile->GetDefinition( - "CMAKE_Swift_COMPILER_VERSION")), - "4.2")) { + if (cmValue v = target->GetProperty("Swift_LANGUAGE_VERSION")) { + if (cmSystemTools::VersionCompare( + cmSystemTools::OP_GREATER_EQUAL, + this->Makefile->GetDefinition("CMAKE_Swift_COMPILER_VERSION"), + "4.2")) { this->AppendFlags(flags, "-swift-version " + *v); } } @@ -1974,7 +1991,7 @@ void cmLocalGenerator::AddLanguageFlags(std::string& flags, // Add VFS Overlay for Clang compilers if (compiler == "Clang") { - if (cmProp vfsOverlay = + if (cmValue vfsOverlay = this->Makefile->GetDefinition("CMAKE_CLANG_VFS_OVERLAY")) { if (compilerSimulateId == "MSVC") { this->AppendCompileOptions( @@ -1989,10 +2006,10 @@ void cmLocalGenerator::AddLanguageFlags(std::string& flags, } // Add MSVC runtime library flags. This is activated by the presence // of a default selection whether or not it is overridden by a property. - cmProp msvcRuntimeLibraryDefault = + cmValue msvcRuntimeLibraryDefault = this->Makefile->GetDefinition("CMAKE_MSVC_RUNTIME_LIBRARY_DEFAULT"); if (cmNonempty(msvcRuntimeLibraryDefault)) { - cmProp msvcRuntimeLibraryValue = + cmValue msvcRuntimeLibraryValue = target->GetProperty("MSVC_RUNTIME_LIBRARY"); if (!msvcRuntimeLibraryValue) { msvcRuntimeLibraryValue = msvcRuntimeLibraryDefault; @@ -2000,7 +2017,7 @@ void cmLocalGenerator::AddLanguageFlags(std::string& flags, std::string const msvcRuntimeLibrary = cmGeneratorExpression::Evaluate( *msvcRuntimeLibraryValue, this, config, target); if (!msvcRuntimeLibrary.empty()) { - if (cmProp msvcRuntimeLibraryOptions = this->Makefile->GetDefinition( + if (cmValue msvcRuntimeLibraryOptions = this->Makefile->GetDefinition( "CMAKE_" + lang + "_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_" + msvcRuntimeLibrary)) { this->AppendCompileOptions(flags, *msvcRuntimeLibraryOptions); @@ -2180,7 +2197,7 @@ void cmLocalGenerator::AddCompilerRequirementFlag( std::string const& optionFlagDef = standardResolver.GetCompileOptionDef(target, lang, config); if (!optionFlagDef.empty()) { - cmProp opt = target->Target->GetMakefile()->GetDefinition(optionFlagDef); + cmValue opt = target->Target->GetMakefile()->GetDefinition(optionFlagDef); if (opt) { std::vector<std::string> optVec = cmExpandedList(*opt); for (std::string const& i : optVec) { @@ -2197,13 +2214,13 @@ static void AddVisibilityCompileOption(std::string& flags, std::string* warnCMP0063) { std::string compileOption = "CMAKE_" + lang + "_COMPILE_OPTIONS_VISIBILITY"; - cmProp opt = lg->GetMakefile()->GetDefinition(compileOption); + cmValue opt = lg->GetMakefile()->GetDefinition(compileOption); if (!opt) { return; } std::string flagDefine = lang + "_VISIBILITY_PRESET"; - cmProp prop = target->GetProperty(flagDefine); + cmValue prop = target->GetProperty(flagDefine); if (!prop) { return; } @@ -2233,7 +2250,7 @@ static void AddInlineVisibilityCompileOption(std::string& flags, { std::string compileOption = cmStrCat("CMAKE_", lang, "_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN"); - cmProp opt = lg->GetMakefile()->GetDefinition(compileOption); + cmValue opt = lg->GetMakefile()->GetDefinition(compileOption); if (!opt) { return; } @@ -2430,7 +2447,7 @@ void cmLocalGenerator::AddISPCDependencies(cmGeneratorTarget* target) return; } - cmProp ispcHeaderSuffixProp = target->GetProperty("ISPC_HEADER_SUFFIX"); + cmValue ispcHeaderSuffixProp = target->GetProperty("ISPC_HEADER_SUFFIX"); assert(ispcHeaderSuffixProp); std::vector<std::string> ispcArchSuffixes = @@ -2443,7 +2460,7 @@ void cmLocalGenerator::AddISPCDependencies(cmGeneratorTarget* target) std::string rootObjectDir = target->GetObjectDirectory(config); std::string headerDir = rootObjectDir; - if (cmProp prop = target->GetProperty("ISPC_HEADER_DIRECTORY")) { + if (cmValue prop = target->GetProperty("ISPC_HEADER_DIRECTORY")) { headerDir = cmSystemTools::CollapseFullPath( cmStrCat(this->GetBinaryDirectory(), '/', *prop)); } @@ -2493,6 +2510,16 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target) static const std::array<std::string, 4> langs = { { "C", "CXX", "OBJC", "OBJCXX" } }; + bool haveAnyPch = false; + if (this->GetGlobalGenerator()->IsXcode()) { + for (const std::string& lang : langs) { + const std::string pchHeader = target->GetPchHeader(config, lang, ""); + if (!pchHeader.empty()) { + haveAnyPch = true; + } + } + } + for (const std::string& lang : langs) { auto langSources = std::count_if( sources.begin(), sources.end(), [lang](cmSourceFile* sf) { @@ -2533,17 +2560,22 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target) const std::string pchHeader = target->GetPchHeader(config, lang, arch); if (pchSource.empty() || pchHeader.empty()) { + if (this->GetGlobalGenerator()->IsXcode() && haveAnyPch) { + for (auto* sf : sources) { + sf->SetProperty("SKIP_PRECOMPILE_HEADERS", "ON"); + } + } continue; } - const std::string pchExtension = - this->Makefile->GetSafeDefinition("CMAKE_PCH_EXTENSION"); + cmValue pchExtension = + this->Makefile->GetDefinition("CMAKE_PCH_EXTENSION"); - if (pchExtension.empty()) { + if (pchExtension.IsEmpty()) { continue; } - cmProp ReuseFrom = + cmValue ReuseFrom = target->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM"); auto* pch_sf = this->Makefile->GetOrCreateSource( @@ -2590,8 +2622,8 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target) // MSVC 2008 is producing both .pdb and .idb files with /Zi. bool msvc2008OrLess = - cmSystemTools::VersionCompare( - cmSystemTools::OP_LESS, compilerVersion.c_str(), "16.0") && + cmSystemTools::VersionCompare(cmSystemTools::OP_LESS, + compilerVersion, "16.0") && compilerId == "MSVC"; // but not when used via toolset -Tv90 if (this->Makefile->GetSafeDefinition( @@ -2622,7 +2654,8 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target) cmStrCat(" ", this->ConvertToOutputFormat(pchSourceObj, SHELL)), true); - } else { + } else if (reuseTarget->GetType() == + cmStateEnums::OBJECT_LIBRARY) { target->Target->AppendProperty( "INTERFACE_LINK_LIBRARIES", cmStrCat("$<$<CONFIG:", config, @@ -2630,7 +2663,7 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target) } } } else { - pch_sf->SetProperty("PCH_EXTENSION", pchExtension.c_str()); + pch_sf->SetProperty("PCH_EXTENSION", pchExtension); } // Add pchHeader to source files, which will @@ -2665,8 +2698,8 @@ void cmLocalGenerator::CopyPchCompilePdb( cmStrCat(target->GetLocalGenerator()->GetCurrentBinaryDirectory(), "/", target->GetName(), ".dir/"); - const std::string copy_script = - cmStrCat(target_compile_pdb_dir, "copy_idb_pdb.cmake"); + const std::string copy_script = cmStrCat( + target_compile_pdb_dir, "copy_idb_pdb_", config.c_str(), ".cmake"); cmGeneratedFileStream file(copy_script); file << "# CMake generated file\n"; @@ -2721,7 +2754,7 @@ void cmLocalGenerator::CopyPchCompilePdb( bool stdPipesUTF8 = true; auto configGenex = [&](cm::string_view expr) -> std::string { - if (this->GetGlobalGenerator()->IsVisualStudio()) { + if (this->GetGlobalGenerator()->IsMultiConfig()) { return cmStrCat("$<$<CONFIG:", config, ">:", expr, ">"); } return std::string(expr); @@ -2740,8 +2773,8 @@ void cmLocalGenerator::CopyPchCompilePdb( std::vector<std::string> no_byproducts; std::vector<std::string> outputs; - outputs.push_back( - cmStrCat(target_compile_pdb_dir, pdb_prefix, ReuseFrom, ".pdb")); + outputs.push_back(configGenex( + cmStrCat(target_compile_pdb_dir, pdb_prefix, ReuseFrom, ".pdb"))); if (this->GetGlobalGenerator()->IsVisualStudio()) { this->AddCustomCommandToTarget( @@ -2771,13 +2804,13 @@ inline void RegisterUnitySources(cmGeneratorTarget* target, cmSourceFile* sf, std::string const& filename) { target->AddSourceFileToUnityBatch(sf->ResolveFullPath()); - sf->SetProperty("UNITY_SOURCE_FILE", filename.c_str()); + sf->SetProperty("UNITY_SOURCE_FILE", filename); } } void cmLocalGenerator::IncludeFileInUnitySources( cmGeneratedFileStream& unity_file, std::string const& sf_full_path, - cmProp beforeInclude, cmProp afterInclude, cmProp uniqueIdName) const + cmValue beforeInclude, cmValue afterInclude, cmValue uniqueIdName) const { if (cmNonempty(uniqueIdName)) { std::string pathToHash; @@ -2815,14 +2848,14 @@ void cmLocalGenerator::IncludeFileInUnitySources( std::vector<std::string> cmLocalGenerator::AddUnityFilesModeAuto( cmGeneratorTarget* target, std::string const& lang, - std::vector<cmSourceFile*> const& filtered_sources, cmProp beforeInclude, - cmProp afterInclude, std::string const& filename_base, size_t batchSize) + std::vector<cmSourceFile*> const& filtered_sources, cmValue beforeInclude, + cmValue afterInclude, std::string const& filename_base, size_t batchSize) { if (batchSize == 0) { batchSize = filtered_sources.size(); } - cmProp uniqueIdName = target->GetProperty("UNITY_BUILD_UNIQUE_ID"); + cmValue uniqueIdName = target->GetProperty("UNITY_BUILD_UNIQUE_ID"); std::vector<std::string> unity_files; for (size_t itemsLeft = filtered_sources.size(), chunk, batch = 0; @@ -2858,8 +2891,8 @@ std::vector<std::string> cmLocalGenerator::AddUnityFilesModeAuto( std::vector<std::string> cmLocalGenerator::AddUnityFilesModeGroup( cmGeneratorTarget* target, std::string const& lang, - std::vector<cmSourceFile*> const& filtered_sources, cmProp beforeInclude, - cmProp afterInclude, std::string const& filename_base) + std::vector<cmSourceFile*> const& filtered_sources, cmValue beforeInclude, + cmValue afterInclude, std::string const& filename_base) { std::vector<std::string> unity_files; @@ -2867,7 +2900,7 @@ std::vector<std::string> cmLocalGenerator::AddUnityFilesModeGroup( // without a group std::unordered_map<std::string, std::vector<cmSourceFile*>> explicit_mapping; for (cmSourceFile* sf : filtered_sources) { - if (cmProp value = sf->GetProperty("UNITY_GROUP")) { + if (cmValue value = sf->GetProperty("UNITY_GROUP")) { auto i = explicit_mapping.find(*value); if (i == explicit_mapping.end()) { std::vector<cmSourceFile*> sources{ sf }; @@ -2878,7 +2911,7 @@ std::vector<std::string> cmLocalGenerator::AddUnityFilesModeGroup( } } - cmProp uniqueIdName = target->GetProperty("UNITY_BUILD_UNIQUE_ID"); + cmValue uniqueIdName = target->GetProperty("UNITY_BUILD_UNIQUE_ID"); for (auto const& item : explicit_mapping) { auto const& name = item.first; @@ -2925,15 +2958,15 @@ void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target) std::vector<cmSourceFile*> sources; target->GetSourceFiles(sources, config); - cmProp batchSizeString = target->GetProperty("UNITY_BUILD_BATCH_SIZE"); + cmValue batchSizeString = target->GetProperty("UNITY_BUILD_BATCH_SIZE"); const size_t unityBatchSize = batchSizeString ? static_cast<size_t>(std::atoi(batchSizeString->c_str())) : 0; - cmProp beforeInclude = + cmValue beforeInclude = target->GetProperty("UNITY_BUILD_CODE_BEFORE_INCLUDE"); - cmProp afterInclude = target->GetProperty("UNITY_BUILD_CODE_AFTER_INCLUDE"); - cmProp unityMode = target->GetProperty("UNITY_BUILD_MODE"); + cmValue afterInclude = target->GetProperty("UNITY_BUILD_CODE_AFTER_INCLUDE"); + cmValue unityMode = target->GetProperty("UNITY_BUILD_MODE"); for (std::string lang : { "C", "CXX" }) { std::vector<cmSourceFile*> filtered_sources; @@ -2969,7 +3002,7 @@ void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target) auto* unity = this->GetMakefile()->GetOrCreateSource(file); target->AddSource(file, true); unity->SetProperty("SKIP_UNITY_BUILD_INCLUSION", "ON"); - unity->SetProperty("UNITY_SOURCE_FILE", file.c_str()); + unity->SetProperty("UNITY_SOURCE_FILE", file); } } } @@ -2993,7 +3026,7 @@ void cmLocalGenerator::AppendIPOLinkerFlags(std::string& flags, } const std::string name = "CMAKE_" + lang + "_LINK_OPTIONS_IPO"; - cmProp rawFlagsList = this->Makefile->GetDefinition(name); + cmValue rawFlagsList = this->Makefile->GetDefinition(name); if (!rawFlagsList) { return; } @@ -3039,6 +3072,30 @@ void cmLocalGenerator::AppendPositionIndependentLinkerFlags( } } +bool cmLocalGenerator::AppendLWYUFlags(std::string& flags, + const cmGeneratorTarget* target, + const std::string& lang) +{ + auto useLWYU = target->GetPropertyAsBool("LINK_WHAT_YOU_USE") && + (target->GetType() == cmStateEnums::TargetType::EXECUTABLE || + target->GetType() == cmStateEnums::TargetType::SHARED_LIBRARY || + target->GetType() == cmStateEnums::TargetType::MODULE_LIBRARY); + + if (useLWYU) { + const auto& lwyuFlag = this->GetMakefile()->GetSafeDefinition( + cmStrCat("CMAKE_", lang, "_LINK_WHAT_YOU_USE_FLAG")); + useLWYU = !lwyuFlag.empty(); + + if (useLWYU) { + std::vector<BT<std::string>> lwyuOpts; + lwyuOpts.emplace_back(lwyuFlag); + this->AppendFlags(flags, target->ResolveLinkerWrapper(lwyuOpts, lang)); + } + } + + return useLWYU; +} + void cmLocalGenerator::AppendCompileOptions(std::string& options, std::string const& options_list, const char* regex) const @@ -3184,7 +3241,7 @@ void cmLocalGenerator::JoinDefines(const std::set<std::string>& defines, // Lookup the define flag for the current language. std::string dflag = "-D"; if (!lang.empty()) { - cmProp df = + cmValue df = this->Makefile->GetDefinition(cmStrCat("CMAKE_", lang, "_DEFINE_FLAG")); if (cmNonempty(df)) { dflag = *df; @@ -3231,7 +3288,7 @@ void cmLocalGenerator::AppendFeatureOptions(std::string& flags, const std::string& lang, const char* feature) { - cmProp optionList = this->Makefile->GetDefinition( + cmValue optionList = this->Makefile->GetDefinition( cmStrCat("CMAKE_", lang, "_COMPILE_OPTIONS_", feature)); if (optionList) { std::vector<std::string> options = cmExpandedList(*optionList); @@ -3241,8 +3298,8 @@ void cmLocalGenerator::AppendFeatureOptions(std::string& flags, } } -cmProp cmLocalGenerator::GetFeature(const std::string& feature, - const std::string& config) +cmValue cmLocalGenerator::GetFeature(const std::string& feature, + const std::string& config) { std::string featureName = feature; // TODO: Define accumulation policy for features (prepend, append, @@ -3253,7 +3310,7 @@ cmProp cmLocalGenerator::GetFeature(const std::string& feature, } cmStateSnapshot snp = this->StateSnapshot; while (snp.IsValid()) { - if (cmProp value = snp.GetDirectory().GetProperty(featureName)) { + if (cmValue value = snp.GetDirectory().GetProperty(featureName)) { return value; } snp = snp.GetBuildsystemDirectoryParent(); @@ -3318,7 +3375,7 @@ void cmLocalGenerator::GenerateTargetInstallRules( } // Include the user-specified pre-install script for this target. - if (cmProp preinstall = l->GetProperty("PRE_INSTALL_SCRIPT")) { + if (cmValue preinstall = l->GetProperty("PRE_INSTALL_SCRIPT")) { cmInstallScriptGenerator g(*preinstall, false, "", false, false); g.Generate(os, config, configurationTypes); } @@ -3371,7 +3428,7 @@ void cmLocalGenerator::GenerateTargetInstallRules( } // Include the user-specified post-install script for this target. - if (cmProp postinstall = l->GetProperty("POST_INSTALL_SCRIPT")) { + if (cmValue postinstall = l->GetProperty("POST_INSTALL_SCRIPT")) { cmInstallScriptGenerator g(*postinstall, false, "", false, false); g.Generate(os, config, configurationTypes); } @@ -3596,8 +3653,8 @@ std::string cmLocalGenerator::GetObjectFileNameWithoutTarget( // Ensure that for the CMakeFiles/<target>.dir/generated_source_file // we don't end up having: // CMakeFiles/<target>.dir/CMakeFiles/<target>.dir/generated_source_file.obj - cmProp unitySourceFile = source.GetProperty("UNITY_SOURCE_FILE"); - cmProp pchExtension = source.GetProperty("PCH_EXTENSION"); + cmValue unitySourceFile = source.GetProperty("UNITY_SOURCE_FILE"); + cmValue pchExtension = source.GetProperty("PCH_EXTENSION"); const bool isPchObject = objectName.find("cmake_pch") != std::string::npos; if (unitySourceFile || pchExtension || isPchObject) { if (pchExtension) { @@ -3696,7 +3753,7 @@ KWIML_INT_uint64_t cmLocalGenerator::GetBackwardsCompatibility() unsigned int major = 0; unsigned int minor = 0; unsigned int patch = 0; - if (cmProp value = + if (cmValue value = this->Makefile->GetDefinition("CMAKE_BACKWARDS_COMPATIBILITY")) { switch (sscanf(value->c_str(), "%u.%u.%u", &major, &minor, &patch)) { case 2: @@ -3723,8 +3780,9 @@ bool cmLocalGenerator::NeedBackwardsCompatibility_2_4() // variable. switch (this->GetPolicyStatus(cmPolicies::CMP0001)) { case cmPolicies::WARN: - // WARN is just OLD without warning because user code does not - // always affect whether this check is done. + // WARN is just OLD without warning because user code does not + // always affect whether this check is done. + CM_FALLTHROUGH; case cmPolicies::OLD: // Old behavior is to check the variable. break; @@ -3791,7 +3849,7 @@ bool cmLocalGenerator::CheckDefinition(std::string const& define) const static void cmLGInfoProp(cmMakefile* mf, cmGeneratorTarget* target, const std::string& prop) { - if (cmProp val = target->GetProperty(prop)) { + if (cmValue val = target->GetProperty(prop)) { mf->AddDefinition(prop, *val); } } @@ -3801,7 +3859,7 @@ void cmLocalGenerator::GenerateAppleInfoPList(cmGeneratorTarget* target, const std::string& fname) { // Find the Info.plist template. - cmProp in = target->GetProperty("MACOSX_BUNDLE_INFO_PLIST"); + cmValue in = target->GetProperty("MACOSX_BUNDLE_INFO_PLIST"); std::string inFile = cmNonempty(in) ? *in : "MacOSXBundleInfo.plist.in"; if (!cmSystemTools::FileIsFullPath(inFile)) { std::string inMod = this->Makefile->GetModulesFile(inFile); @@ -3840,7 +3898,7 @@ void cmLocalGenerator::GenerateFrameworkInfoPList( const std::string& fname) { // Find the Info.plist template. - cmProp in = target->GetProperty("MACOSX_FRAMEWORK_INFO_PLIST"); + cmValue in = target->GetProperty("MACOSX_FRAMEWORK_INFO_PLIST"); std::string inFile = cmNonempty(in) ? *in : "MacOSXFrameworkInfo.plist.in"; if (!cmSystemTools::FileIsFullPath(inFile)) { std::string inMod = this->Makefile->GetModulesFile(inFile); diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 993280ac2..3614c8466 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -20,8 +20,8 @@ #include "cmMessageType.h" #include "cmOutputConverter.h" #include "cmPolicies.h" -#include "cmProperty.h" #include "cmStateSnapshot.h" +#include "cmValue.h" class cmCompiledGeneratorExpression; class cmComputeLinkInformation; @@ -171,6 +171,8 @@ public: cmGeneratorTarget* target, const std::string& config, const std::string& lang); + bool AppendLWYUFlags(std::string& flags, const cmGeneratorTarget* target, + const std::string& lang); enum class IncludePathStyle { @@ -245,7 +247,7 @@ public: void AppendFeatureOptions(std::string& flags, const std::string& lang, const char* feature); - cmProp GetFeature(const std::string& feature, const std::string& config); + cmValue GetFeature(const std::string& feature, const std::string& config); /** \brief Get absolute path to dependency \a name * @@ -545,7 +547,7 @@ public: void CreateEvaluationFileOutputs(const std::string& config); void ProcessEvaluationFiles(std::vector<std::string>& generatedFiles); - cmProp GetRuleLauncher(cmGeneratorTarget* target, const std::string& prop); + cmValue GetRuleLauncher(cmGeneratorTarget* target, const std::string& prop); protected: // The default implementation ignores the IncludePathStyle and always @@ -587,7 +589,7 @@ protected: std::string::size_type ObjectPathMax; std::set<std::string> ObjectMaxPathViolations; - std::set<std::string> EnvCPATH; + std::vector<std::string> EnvCPATH; using GeneratorTargetMap = std::unordered_map<std::string, cmGeneratorTarget*>; @@ -649,7 +651,7 @@ private: void ComputeObjectMaxPath(); bool AllAppleArchSysrootsAreTheSame(const std::vector<std::string>& archs, - const char* sysroot); + cmValue sysroot); void CopyPchCompilePdb(const std::string& config, cmGeneratorTarget* target, const std::string& ReuseFrom, @@ -657,16 +659,16 @@ private: std::vector<std::string> const& extensions); void IncludeFileInUnitySources(cmGeneratedFileStream& unity_file, std::string const& sf_full_path, - cmProp beforeInclude, cmProp afterInclude, - cmProp uniqueIdName) const; + cmValue beforeInclude, cmValue afterInclude, + cmValue uniqueIdName) const; std::vector<std::string> AddUnityFilesModeAuto( cmGeneratorTarget* target, std::string const& lang, - std::vector<cmSourceFile*> const& filtered_sources, cmProp beforeInclude, - cmProp afterInclude, std::string const& filename_base, size_t batchSize); + std::vector<cmSourceFile*> const& filtered_sources, cmValue beforeInclude, + cmValue afterInclude, std::string const& filename_base, size_t batchSize); std::vector<std::string> AddUnityFilesModeGroup( cmGeneratorTarget* target, std::string const& lang, - std::vector<cmSourceFile*> const& filtered_sources, cmProp beforeInclude, - cmProp afterInclude, std::string const& filename_base); + std::vector<cmSourceFile*> const& filtered_sources, cmValue beforeInclude, + cmValue afterInclude, std::string const& filename_base); }; #if !defined(CMAKE_BOOTSTRAP) diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx index e88f33c2f..8556fe6b5 100644 --- a/Source/cmLocalNinjaGenerator.cxx +++ b/Source/cmLocalNinjaGenerator.cxx @@ -27,7 +27,6 @@ #include "cmMessageType.h" #include "cmNinjaTargetGenerator.h" #include "cmPolicies.h" -#include "cmProperty.h" #include "cmRulePlaceholderExpander.h" #include "cmSourceFile.h" #include "cmState.h" @@ -35,6 +34,7 @@ #include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" +#include "cmValue.h" #include "cmake.h" cmLocalNinjaGenerator::cmLocalNinjaGenerator(cmGlobalGenerator* gg, @@ -279,7 +279,7 @@ void cmLocalNinjaGenerator::WriteNinjaRequiredVersion(std::ostream& os) std::string requiredVersion = cmGlobalNinjaGenerator::RequiredNinjaVersion(); // Ninja generator uses the 'console' pool if available (>= 1.5) - if (this->GetGlobalNinjaGenerator()->SupportsConsolePool()) { + if (this->GetGlobalNinjaGenerator()->SupportsDirectConsole()) { requiredVersion = cmGlobalNinjaGenerator::RequiredNinjaVersionForConsolePool(); } @@ -311,7 +311,7 @@ void cmLocalNinjaGenerator::WritePools(std::ostream& os) { cmGlobalNinjaGenerator::WriteDivider(os); - cmProp jobpools = + cmValue jobpools = this->GetCMakeInstance()->GetState()->GetGlobalProperty("JOB_POOLS"); if (!jobpools) { jobpools = this->GetMakefile()->GetDefinition("CMAKE_JOB_POOLS"); @@ -796,8 +796,9 @@ cmLocalNinjaGenerator::MakeCustomCommandGenerators( bool transformDepfile = false; switch (cc.GetCMP0116Status()) { - case cmPolicies::OLD: case cmPolicies::WARN: + CM_FALLTHROUGH; + case cmPolicies::OLD: break; case cmPolicies::REQUIRED_IF_USED: case cmPolicies::REQUIRED_ALWAYS: @@ -869,7 +870,7 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatements( std::string cmLocalNinjaGenerator::MakeCustomLauncher( cmCustomCommandGenerator const& ccg) { - cmProp property_value = this->Makefile->GetProperty("RULE_LAUNCH_CUSTOM"); + cmValue property_value = this->Makefile->GetProperty("RULE_LAUNCH_CUSTOM"); if (!cmNonempty(property_value)) { return std::string(); @@ -903,7 +904,7 @@ std::string cmLocalNinjaGenerator::MakeCustomLauncher( void cmLocalNinjaGenerator::AdditionalCleanFiles(const std::string& config) { - if (cmProp prop_value = + if (cmValue prop_value = this->Makefile->GetProperty("ADDITIONAL_CLEAN_FILES")) { std::vector<std::string> cleanFiles; { diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index 0667c55a3..7e39b91f1 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -33,7 +33,6 @@ #include "cmMakefile.h" #include "cmMakefileTargetGenerator.h" #include "cmOutputConverter.h" -#include "cmProperty.h" #include "cmRange.h" #include "cmRulePlaceholderExpander.h" #include "cmSourceFile.h" @@ -43,6 +42,7 @@ #include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTargetDepend.h" +#include "cmValue.h" #include "cmVersion.h" #include "cmake.h" @@ -570,7 +570,7 @@ void cmLocalUnixMakefileGenerator3::WriteMakeRule( // Mark the rule as symbolic if requested. if (symbolic) { - if (cmProp sym = + if (cmValue sym = this->Makefile->GetDefinition("CMAKE_MAKE_SYMBOLIC_RULE")) { os << tgt << space << ": " << *sym << "\n"; } @@ -884,7 +884,7 @@ void cmLocalUnixMakefileGenerator3::AppendRuleDepend( { // Add a dependency on the rule file itself unless an option to skip // it is specifically enabled by the user or project. - cmProp nodep = this->Makefile->GetDefinition("CMAKE_SKIP_RULE_DEPENDENCY"); + cmValue nodep = this->Makefile->GetDefinition("CMAKE_SKIP_RULE_DEPENDENCY"); if (cmIsOff(nodep)) { depends.emplace_back(ruleFileName); } @@ -999,7 +999,7 @@ void cmLocalUnixMakefileGenerator3::AppendCustomCommand( std::string launcher; // Short-circuit if there is no launcher. - cmProp val = this->GetRuleLauncher(target, "RULE_LAUNCH_CUSTOM"); + cmValue val = this->GetRuleLauncher(target, "RULE_LAUNCH_CUSTOM"); if (cmNonempty(val)) { // Expand rule variables referenced in the given launcher command. cmRulePlaceholderExpander::RuleVariables vars; @@ -1125,7 +1125,7 @@ void cmLocalUnixMakefileGenerator3::AppendDirectoryCleanCommand( { std::vector<std::string> cleanFiles; // Look for additional files registered for cleaning in this directory. - if (cmProp prop_value = + if (cmValue prop_value = this->Makefile->GetProperty("ADDITIONAL_CLEAN_FILES")) { cmExpandList(cmGeneratorExpression::Evaluate( *prop_value, this, @@ -1501,18 +1501,18 @@ bool cmLocalUnixMakefileGenerator3::ScanDependencies( // Lookup useful directory information. if (haveDirectoryInfo) { // Test whether we need to force Unix paths. - if (cmProp force = mf->GetDefinition("CMAKE_FORCE_UNIX_PATHS")) { + if (cmValue force = mf->GetDefinition("CMAKE_FORCE_UNIX_PATHS")) { if (!cmIsOff(force)) { cmSystemTools::SetForceUnixPaths(true); } } // Setup relative path top directories. - if (cmProp relativePathTopSource = + if (cmValue relativePathTopSource = mf->GetDefinition("CMAKE_RELATIVE_PATH_TOP_SOURCE")) { this->SetRelativePathTopSource(*relativePathTopSource); } - if (cmProp relativePathTopBinary = + if (cmValue relativePathTopBinary = mf->GetDefinition("CMAKE_RELATIVE_PATH_TOP_BINARY")) { this->SetRelativePathTopBinary(*relativePathTopBinary); } @@ -1582,7 +1582,7 @@ void cmLocalUnixMakefileGenerator3::CheckMultipleOutputs(bool verbose) cmMakefile* mf = this->Makefile; // Get the string listing the multiple output pairs. - cmProp pairs_string = mf->GetDefinition("CMAKE_MULTIPLE_OUTPUT_PAIRS"); + cmValue pairs_string = mf->GetDefinition("CMAKE_MULTIPLE_OUTPUT_PAIRS"); if (!pairs_string) { return; } @@ -1654,7 +1654,7 @@ void cmLocalUnixMakefileGenerator3::WriteLocalAllRules( std::vector<std::string> commands; std::vector<std::string> depends; - cmProp p = gt->GetProperty("EchoString"); + cmValue p = gt->GetProperty("EchoString"); const char* text = p ? p->c_str() : "Running external command ..."; depends.reserve(gt->GetUtilities().size()); for (BT<std::pair<std::string, bool>> const& u : gt->GetUtilities()) { @@ -1754,7 +1754,7 @@ void cmLocalUnixMakefileGenerator3::WriteLocalAllRules( recursiveTarget = cmStrCat(this->GetCurrentBinaryDirectory(), "/preinstall"); commands.clear(); depends.clear(); - cmProp noall = + cmValue noall = this->Makefile->GetDefinition("CMAKE_SKIP_INSTALL_ALL_DEPENDENCY"); if (cmIsOff(noall)) { // Drive the build before installing. @@ -1804,7 +1804,7 @@ void cmLocalUnixMakefileGenerator3::ClearDependencies(cmMakefile* mf, bool verbose) { // Get the list of target files to check - cmProp infoDef = mf->GetDefinition("CMAKE_DEPEND_INFO_FILES"); + cmValue infoDef = mf->GetDefinition("CMAKE_DEPEND_INFO_FILES"); if (!infoDef) { return; } @@ -1903,7 +1903,7 @@ void cmLocalUnixMakefileGenerator3::WriteDependLanguageInfo( // Tell the dependency scanner what compiler is used. std::string cidVar = cmStrCat("CMAKE_", lang, "_COMPILER_ID"); - cmProp cid = this->Makefile->GetDefinition(cidVar); + cmValue cid = this->Makefile->GetDefinition(cidVar); if (cmNonempty(cid)) { cmakefileStream << "set(CMAKE_" << lang << "_COMPILER_ID \"" << *cid << "\")\n"; @@ -1960,11 +1960,11 @@ void cmLocalUnixMakefileGenerator3::WriteDependLanguageInfo( // Store include transform rule properties. Write the directory // rules first because they may be overridden by later target rules. std::vector<std::string> transformRules; - if (cmProp xform = + if (cmValue xform = this->Makefile->GetProperty("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM")) { cmExpandList(*xform, transformRules); } - if (cmProp xform = + if (cmValue xform = target->GetProperty("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM")) { cmExpandList(*xform, transformRules); } diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h index 14dd0baf4..78aa7f9c2 100644 --- a/Source/cmLocalUnixMakefileGenerator3.h +++ b/Source/cmLocalUnixMakefileGenerator3.h @@ -299,7 +299,7 @@ private: cmGeneratorTarget const* target) { return this->CommandsVisited[target]; - }; + } std::map<cmGeneratorTarget const*, std::set<cmSourceFile const*>> CommandsVisited; diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 151470b4e..5d3e11a64 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -69,7 +69,7 @@ void cmLocalVisualStudio7Generator::AddHelperCommands() if (!l->IsInBuildSystem()) { continue; } - cmProp path = l->GetProperty("EXTERNAL_MSPROJECT"); + cmValue path = l->GetProperty("EXTERNAL_MSPROJECT"); if (path) { this->ReadAndStoreExternalGUID(l->GetName(), path->c_str()); } @@ -402,6 +402,7 @@ cmVS7FlagTable cmLocalVisualStudio7GeneratorFlagTable[] = { cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue }, { "PrecompiledHeaderThrough", "Yc", "Precompiled Header Name", "", cmVS7FlagTable::UserValueRequired }, + { "UsePrecompiledHeader", "Y-", "Don't use precompiled header", "0", 0 }, { "PrecompiledHeaderFile", "Fp", "Generated Precompiled Header", "", cmVS7FlagTable::UserValue }, // The YX and Yu options are in a per-global-generator table because @@ -566,7 +567,7 @@ public: } else { this->Stream << this->LG->EscapeForXML("\n"); } - std::string script = this->LG->ConstructScript(ccg); + std::string script = this->LG->ConstructScript(ccg, unmanaged); this->Stream << this->LG->EscapeForXML(script); } @@ -582,7 +583,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration( const std::string& libName, cmGeneratorTarget* target) { std::string mfcFlag; - if (cmProp p = this->Makefile->GetDefinition("CMAKE_MFC_FLAG")) { + if (cmValue p = this->Makefile->GetDefinition("CMAKE_MFC_FLAG")) { mfcFlag = cmGeneratorExpression::Evaluate(*p, this, configName); } else { mfcFlag = "0"; @@ -781,7 +782,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration( fout << "\t\t\t<Tool\n" << "\t\t\t\tName=\"" << tool << "\"\n"; if (this->FortranProject) { - cmProp target_mod_dir = target->GetProperty("Fortran_MODULE_DIRECTORY"); + cmValue target_mod_dir = target->GetProperty("Fortran_MODULE_DIRECTORY"); std::string modDir; if (target_mod_dir) { modDir = this->MaybeRelativeToCurBinDir(*target_mod_dir); @@ -938,7 +939,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool( " " + GetBuildTypeLinkerFlags("CMAKE_MODULE_LINKER_FLAGS", configName); } - cmProp targetLinkFlags = target->GetProperty("LINK_FLAGS"); + cmValue targetLinkFlags = target->GetProperty("LINK_FLAGS"); if (targetLinkFlags) { extraLinkOptions += " "; extraLinkOptions += *targetLinkFlags; @@ -1077,7 +1078,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool( } } std::string stackVar = cmStrCat("CMAKE_", linkLanguage, "_STACK_SIZE"); - cmProp stackVal = this->Makefile->GetDefinition(stackVar); + cmValue stackVal = this->Makefile->GetDefinition(stackVar); if (stackVal) { fout << "\t\t\t\tStackReserveSize=\"" << *stackVal << "\"\n"; } @@ -1168,7 +1169,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool( << "\"\n"; } std::string stackVar = cmStrCat("CMAKE_", linkLanguage, "_STACK_SIZE"); - cmProp stackVal = this->Makefile->GetDefinition(stackVar); + cmValue stackVal = this->Makefile->GetDefinition(stackVar); if (stackVal) { fout << "\t\t\t\tStackReserveSize=\"" << *stackVal << "\""; } @@ -1209,8 +1210,8 @@ void cmLocalVisualStudio7Generator::OutputDeploymentDebuggerTool( std::ostream& fout, std::string const& config, cmGeneratorTarget* target) { if (this->WindowsCEProject) { - cmProp dir = target->GetProperty("DEPLOYMENT_REMOTE_DIRECTORY"); - cmProp additionalFiles = + cmValue dir = target->GetProperty("DEPLOYMENT_REMOTE_DIRECTORY"); + cmValue additionalFiles = target->GetProperty("DEPLOYMENT_ADDITIONAL_FILES"); if (!dir && !additionalFiles) { @@ -1447,12 +1448,12 @@ cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo( needfc = true; } const std::string COMPILE_FLAGS("COMPILE_FLAGS"); - if (cmProp cflags = sf.GetProperty(COMPILE_FLAGS)) { + if (cmValue cflags = sf.GetProperty(COMPILE_FLAGS)) { fc.CompileFlags = genexInterpreter.Evaluate(*cflags, COMPILE_FLAGS); needfc = true; } const std::string COMPILE_OPTIONS("COMPILE_OPTIONS"); - if (cmProp coptions = sf.GetProperty(COMPILE_OPTIONS)) { + if (cmValue coptions = sf.GetProperty(COMPILE_OPTIONS)) { lg->AppendCompileOptions( fc.CompileFlags, genexInterpreter.Evaluate(*coptions, COMPILE_OPTIONS)); @@ -1504,25 +1505,25 @@ cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo( } } const std::string COMPILE_DEFINITIONS("COMPILE_DEFINITIONS"); - if (cmProp cdefs = sf.GetProperty(COMPILE_DEFINITIONS)) { + if (cmValue cdefs = sf.GetProperty(COMPILE_DEFINITIONS)) { fc.CompileDefs = genexInterpreter.Evaluate(*cdefs, COMPILE_DEFINITIONS); needfc = true; } std::string defPropName = cmStrCat("COMPILE_DEFINITIONS_", configUpper); - if (cmProp ccdefs = sf.GetProperty(defPropName)) { + if (cmValue ccdefs = sf.GetProperty(defPropName)) { fc.CompileDefsConfig = genexInterpreter.Evaluate(*ccdefs, COMPILE_DEFINITIONS); needfc = true; } const std::string INCLUDE_DIRECTORIES("INCLUDE_DIRECTORIES"); - if (cmProp cincs = sf.GetProperty(INCLUDE_DIRECTORIES)) { + if (cmValue cincs = sf.GetProperty(INCLUDE_DIRECTORIES)) { fc.IncludeDirs = genexInterpreter.Evaluate(*cincs, INCLUDE_DIRECTORIES); needfc = true; } // Check for extra object-file dependencies. - if (cmProp deps = sf.GetProperty("OBJECT_DEPENDS")) { + if (cmValue deps = sf.GetProperty("OBJECT_DEPENDS")) { std::vector<std::string> depends = cmExpandedList(*deps); const char* sep = ""; for (const std::string& d : depends) { @@ -1779,7 +1780,7 @@ void cmLocalVisualStudio7Generator::WriteCustomRule( } std::string comment = this->ConstructComment(ccg); - std::string script = this->ConstructScript(ccg); + std::string script = this->ConstructScript(ccg, unmanaged); if (this->FortranProject) { cmSystemTools::ReplaceString(script, "$(Configuration)", config); } @@ -1897,9 +1898,9 @@ void cmLocalVisualStudio7Generator::WriteProjectSCC(std::ostream& fout, { // if we have all the required Source code control tags // then add that to the project - cmProp vsProjectname = target->GetProperty("VS_SCC_PROJECTNAME"); - cmProp vsLocalpath = target->GetProperty("VS_SCC_LOCALPATH"); - cmProp vsProvider = target->GetProperty("VS_SCC_PROVIDER"); + cmValue vsProjectname = target->GetProperty("VS_SCC_PROJECTNAME"); + cmValue vsLocalpath = target->GetProperty("VS_SCC_LOCALPATH"); + cmValue vsProvider = target->GetProperty("VS_SCC_PROVIDER"); if (vsProvider && vsLocalpath && vsProjectname) { /* clang-format off */ @@ -1908,7 +1909,7 @@ void cmLocalVisualStudio7Generator::WriteProjectSCC(std::ostream& fout, << "\tSccProvider=\"" << *vsProvider << "\"\n"; /* clang-format on */ - cmProp vsAuxPath = target->GetProperty("VS_SCC_AUXPATH"); + cmValue vsAuxPath = target->GetProperty("VS_SCC_AUXPATH"); if (vsAuxPath) { fout << "\tSccAuxPath=\"" << *vsAuxPath << "\"\n"; } @@ -1928,7 +1929,7 @@ void cmLocalVisualStudio7Generator::WriteProjectStartFortran( << "\tProjectCreator=\"Intel Fortran\"\n" << "\tVersion=\"" << gg->GetIntelProjectVersion() << "\"\n"; /* clang-format on */ - cmProp p = target->GetProperty("VS_KEYWORD"); + cmValue p = target->GetProperty("VS_KEYWORD"); const char* keyword = p ? p->c_str() : "Console Application"; const char* projectType = 0; switch (target->GetType()) { @@ -1990,14 +1991,14 @@ void cmLocalVisualStudio7Generator::WriteProjectStart( << "\tProjectType=\"Visual C++\"\n"; /* clang-format on */ fout << "\tVersion=\"" << (gg->GetVersion() / 10) << ".00\"\n"; - cmProp p = target->GetProperty("PROJECT_LABEL"); + cmValue p = target->GetProperty("PROJECT_LABEL"); const std::string projLabel = p ? *p : libName; p = target->GetProperty("VS_KEYWORD"); const std::string keyword = p ? *p : "Win32Proj"; fout << "\tName=\"" << projLabel << "\"\n"; fout << "\tProjectGUID=\"{" << gg->GetGUID(libName) << "}\"\n"; this->WriteProjectSCC(fout, target); - if (cmProp targetFrameworkVersion = + if (cmValue targetFrameworkVersion = target->GetProperty("VS_DOTNET_TARGET_FRAMEWORK_VERSION")) { fout << "\tTargetFrameworkVersion=\"" << *targetFrameworkVersion << "\"\n"; } @@ -2142,7 +2143,7 @@ void cmLocalVisualStudio7Generator::ReadAndStoreExternalGUID( std::string guidStoreName = cmStrCat(name, "_GUID_CMAKE"); // save the GUID in the cache this->GlobalGenerator->GetCMakeInstance()->AddCacheEntry( - guidStoreName, parser.GUID.c_str(), "Stored GUID", cmStateEnums::INTERNAL); + guidStoreName, parser.GUID, "Stored GUID", cmStateEnums::INTERNAL); } std::string cmLocalVisualStudio7Generator::GetTargetDirectory( diff --git a/Source/cmLocalVisualStudioGenerator.cxx b/Source/cmLocalVisualStudioGenerator.cxx index 002f484bc..4ed1dd92b 100644 --- a/Source/cmLocalVisualStudioGenerator.cxx +++ b/Source/cmLocalVisualStudioGenerator.cxx @@ -124,7 +124,8 @@ const char* cmLocalVisualStudioGenerator::GetReportErrorLabel() const } std::string cmLocalVisualStudioGenerator::ConstructScript( - cmCustomCommandGenerator const& ccg, const std::string& newline_text) + cmCustomCommandGenerator const& ccg, IsManaged isManaged, + const std::string& newline_text) { bool useLocal = this->CustomCommandUseLocal(); std::string workingDirectory = ccg.GetWorkingDirectory(); @@ -171,8 +172,9 @@ std::string cmLocalVisualStudioGenerator::ConstructScript( // for visual studio IDE add extra stuff to the PATH // if CMAKE_MSVCIDE_RUN_PATH is set. - if (this->Makefile->GetDefinition("MSVC_IDE")) { - cmProp extraPath = this->Makefile->GetDefinition("CMAKE_MSVCIDE_RUN_PATH"); + if (this->GetGlobalGenerator()->IsVisualStudio()) { + cmValue extraPath = + this->Makefile->GetDefinition("CMAKE_MSVCIDE_RUN_PATH"); if (extraPath) { script += newline; newline = newline_text; @@ -236,6 +238,14 @@ std::string cmLocalVisualStudioGenerator::ConstructScript( script += newline; script += "if %errorlevel% neq 0 goto "; script += this->GetReportErrorLabel(); + if (isManaged == managed) { + // These aren't generated by default for C# projects. + script += newline; + script += this->GetReportErrorLabel(); + script += newline; + script += "exit /b 0"; + script += newline; + } } return script; diff --git a/Source/cmLocalVisualStudioGenerator.h b/Source/cmLocalVisualStudioGenerator.h index 91fb6b061..0e7f63ff5 100644 --- a/Source/cmLocalVisualStudioGenerator.h +++ b/Source/cmLocalVisualStudioGenerator.h @@ -31,7 +31,13 @@ public: virtual ~cmLocalVisualStudioGenerator(); /** Construct a script from the given list of command lines. */ + enum IsManaged + { + unmanaged, + managed + }; std::string ConstructScript(cmCustomCommandGenerator const& ccg, + IsManaged isManaged, const std::string& newline = "\n"); /** Label to which to jump in a batch file after a failed step in a diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index c970abe8a..83984f7a3 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -190,7 +190,7 @@ void cmMakefile::MaybeWarnCMP0074(std::string const& pkg) { // Warn if a <pkg>_ROOT variable we may use is set. std::string const varName = pkg + "_ROOT"; - cmProp var = this->GetDefinition(varName); + cmValue var = this->GetDefinition(varName); std::string env; cmSystemTools::GetEnv(varName, env); @@ -212,59 +212,31 @@ void cmMakefile::MaybeWarnCMP0074(std::string const& pkg) } } -cmStringRange cmMakefile::GetIncludeDirectoriesEntries() const +cmBTStringRange cmMakefile::GetIncludeDirectoriesEntries() const { return this->StateSnapshot.GetDirectory().GetIncludeDirectoriesEntries(); } -cmBacktraceRange cmMakefile::GetIncludeDirectoriesBacktraces() const -{ - return this->StateSnapshot.GetDirectory() - .GetIncludeDirectoriesEntryBacktraces(); -} - -cmStringRange cmMakefile::GetCompileOptionsEntries() const +cmBTStringRange cmMakefile::GetCompileOptionsEntries() const { return this->StateSnapshot.GetDirectory().GetCompileOptionsEntries(); } -cmBacktraceRange cmMakefile::GetCompileOptionsBacktraces() const -{ - return this->StateSnapshot.GetDirectory().GetCompileOptionsEntryBacktraces(); -} - -cmStringRange cmMakefile::GetCompileDefinitionsEntries() const +cmBTStringRange cmMakefile::GetCompileDefinitionsEntries() const { return this->StateSnapshot.GetDirectory().GetCompileDefinitionsEntries(); } -cmBacktraceRange cmMakefile::GetCompileDefinitionsBacktraces() const -{ - return this->StateSnapshot.GetDirectory() - .GetCompileDefinitionsEntryBacktraces(); -} - -cmStringRange cmMakefile::GetLinkOptionsEntries() const +cmBTStringRange cmMakefile::GetLinkOptionsEntries() const { return this->StateSnapshot.GetDirectory().GetLinkOptionsEntries(); } -cmBacktraceRange cmMakefile::GetLinkOptionsBacktraces() const -{ - return this->StateSnapshot.GetDirectory().GetLinkOptionsEntryBacktraces(); -} - -cmStringRange cmMakefile::GetLinkDirectoriesEntries() const +cmBTStringRange cmMakefile::GetLinkDirectoriesEntries() const { return this->StateSnapshot.GetDirectory().GetLinkDirectoriesEntries(); } -cmBacktraceRange cmMakefile::GetLinkDirectoriesBacktraces() const -{ - return this->StateSnapshot.GetDirectory() - .GetLinkDirectoriesEntryBacktraces(); -} - cmListFileBacktrace cmMakefile::GetBacktrace() const { return this->Backtrace; @@ -428,7 +400,7 @@ bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff, // Check for maximum recursion depth. int depth = CMake_DEFAULT_RECURSION_LIMIT; - cmProp depthStr = this->GetDefinition("CMAKE_MAXIMUM_RECURSION_DEPTH"); + cmValue depthStr = this->GetDefinition("CMAKE_MAXIMUM_RECURSION_DEPTH"); if (depthStr) { std::istringstream s(*depthStr); int d; @@ -614,7 +586,7 @@ void cmMakefile::IncludeScope::EnforceCMP0011() bool cmMakefile::ReadDependentFile(const std::string& filename, bool noPolicyScope) { - if (cmProp def = this->GetDefinition("CMAKE_CURRENT_LIST_FILE")) { + if (cmValue def = this->GetDefinition("CMAKE_CURRENT_LIST_FILE")) { this->AddDefinition("CMAKE_PARENT_LIST_FILE", *def); } std::string filenametoread = cmSystemTools::CollapseFullPath( @@ -846,6 +818,7 @@ void cmMakefile::EnforceDirectoryLevelRules() const // version. this->GetCMakeInstance()->IssueMessage(MessageType::AUTHOR_WARNING, msg.str(), this->Backtrace); + CM_FALLTHROUGH; case cmPolicies::OLD: // OLD behavior is to use policy version 2.4 set in // cmListFileCache. @@ -857,7 +830,7 @@ void cmMakefile::EnforceDirectoryLevelRules() const this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, msg.str(), this->Backtrace); cmSystemTools::SetFatalErrorOccured(); - return; + break; } } } @@ -952,10 +925,9 @@ void cmMakefile::DoGenerate(cmLocalGenerator& lg) void cmMakefile::Generate(cmLocalGenerator& lg) { this->DoGenerate(lg); - cmProp oldValue = this->GetDefinition("CMAKE_BACKWARDS_COMPATIBILITY"); + cmValue oldValue = this->GetDefinition("CMAKE_BACKWARDS_COMPATIBILITY"); if (oldValue && - cmSystemTools::VersionCompare(cmSystemTools::OP_LESS, oldValue->c_str(), - "2.4")) { + cmSystemTools::VersionCompare(cmSystemTools::OP_LESS, oldValue, "2.4")) { this->GetCMakeInstance()->IssueMessage( MessageType::FATAL_ERROR, "You have set CMAKE_BACKWARDS_COMPATIBILITY to a CMake version less " @@ -1030,6 +1002,7 @@ cmTarget* cmMakefile::GetCustomCommandTarget( case cmPolicies::WARN: e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0040) << "\n"; issueMessage = true; + CM_FALLTHROUGH; case cmPolicies::OLD: break; case cmPolicies::NEW: @@ -1037,6 +1010,7 @@ cmTarget* cmMakefile::GetCustomCommandTarget( case cmPolicies::REQUIRED_ALWAYS: issueMessage = true; messageType = MessageType::FATAL_ERROR; + break; } if (issueMessage) { @@ -1386,10 +1360,10 @@ void cmMakefile::AddLinkDirectory(std::string const& directory, bool before) { if (before) { this->StateSnapshot.GetDirectory().PrependLinkDirectoriesEntry( - directory, this->Backtrace); + BT<std::string>(directory, this->Backtrace)); } else { this->StateSnapshot.GetDirectory().AppendLinkDirectoriesEntry( - directory, this->Backtrace); + BT<std::string>(directory, this->Backtrace)); } } @@ -1434,7 +1408,7 @@ bool cmMakefile::ParseDefineFlag(std::string const& def, bool remove) const char* define = def.c_str() + 2; if (remove) { - if (cmProp cdefs = this->GetProperty("COMPILE_DEFINITIONS")) { + if (cmValue cdefs = this->GetProperty("COMPILE_DEFINITIONS")) { // Expand the list. std::vector<std::string> defs = cmExpandedList(*cdefs); @@ -1444,7 +1418,7 @@ bool cmMakefile::ParseDefineFlag(std::string const& def, bool remove) std::string ndefs = cmJoin(cmMakeRange(defBegin, defEnd), ";"); // Store the new list. - this->SetProperty("COMPILE_DEFINITIONS", ndefs.c_str()); + this->SetProperty("COMPILE_DEFINITIONS", ndefs); } } else { // Append the definition to the directory property. @@ -1465,30 +1439,29 @@ void cmMakefile::InitializeFromParent(cmMakefile* parent) // Include transform property. There is no per-config version. { const char* prop = "IMPLICIT_DEPENDS_INCLUDE_TRANSFORM"; - this->SetProperty(prop, cmToCStr(parent->GetProperty(prop))); + this->SetProperty(prop, parent->GetProperty(prop)); } // compile definitions property and per-config versions cmPolicies::PolicyStatus polSt = this->GetPolicyStatus(cmPolicies::CMP0043); if (polSt == cmPolicies::WARN || polSt == cmPolicies::OLD) { this->SetProperty("COMPILE_DEFINITIONS", - cmToCStr(parent->GetProperty("COMPILE_DEFINITIONS"))); + parent->GetProperty("COMPILE_DEFINITIONS")); std::vector<std::string> configs = this->GetGeneratorConfigs(cmMakefile::ExcludeEmptyConfig); for (std::string const& config : configs) { std::string defPropName = cmStrCat("COMPILE_DEFINITIONS_", cmSystemTools::UpperCase(config)); - cmProp prop = parent->GetProperty(defPropName); - this->SetProperty(defPropName, cmToCStr(prop)); + cmValue prop = parent->GetProperty(defPropName); + this->SetProperty(defPropName, prop); } } // labels - this->SetProperty("LABELS", cmToCStr(parent->GetProperty("LABELS"))); + this->SetProperty("LABELS", parent->GetProperty("LABELS")); // link libraries - this->SetProperty("LINK_LIBRARIES", - cmToCStr(parent->GetProperty("LINK_LIBRARIES"))); + this->SetProperty("LINK_LIBRARIES", parent->GetProperty("LINK_LIBRARIES")); // the initial project name this->StateSnapshot.SetProjectName(parent->StateSnapshot.GetProjectName()); @@ -1781,6 +1754,7 @@ void cmMakefile::ConfigureSubDirectory(cmMakefile* mf) << cmPolicies::GetPolicyWarning(cmPolicies::CMP0014); /* clang-format on */ this->IssueMessage(MessageType::AUTHOR_WARNING, e.str()); + CM_FALLTHROUGH; case cmPolicies::OLD: // OLD behavior does not warn. break; @@ -1791,6 +1765,7 @@ void cmMakefile::ConfigureSubDirectory(cmMakefile* mf) case cmPolicies::NEW: // NEW behavior prints the error. this->IssueMessage(MessageType::FATAL_ERROR, e.str()); + break; } return; } @@ -1877,16 +1852,16 @@ void cmMakefile::AddIncludeDirectories(const std::vector<std::string>& incs, std::string entryString = cmJoin(incs, ";"); if (before) { this->StateSnapshot.GetDirectory().PrependIncludeDirectoriesEntry( - entryString, this->Backtrace); + BT<std::string>(entryString, this->Backtrace)); } else { this->StateSnapshot.GetDirectory().AppendIncludeDirectoriesEntry( - entryString, this->Backtrace); + BT<std::string>(entryString, this->Backtrace)); } // Property on each target: for (auto& target : this->Targets) { cmTarget& t = target.second; - t.InsertInclude(entryString, this->Backtrace, before); + t.InsertInclude(BT<std::string>(entryString, this->Backtrace), before); } } @@ -1927,7 +1902,7 @@ void cmMakefile::AddCacheDefinition(const std::string& name, const char* value, cmStateEnums::CacheEntryType type, bool force) { - cmProp existingValue = this->GetState()->GetInitializedCacheValue(name); + cmValue existingValue = this->GetState()->GetInitializedCacheValue(name); // must be outside the following if() to keep it alive long enough std::string nvalue; @@ -1956,7 +1931,7 @@ void cmMakefile::AddCacheDefinition(const std::string& name, const char* value, nvalue += files[cc]; } - this->GetCMakeInstance()->AddCacheEntry(name, nvalue.c_str(), doc, type); + this->GetCMakeInstance()->AddCacheEntry(name, nvalue, doc, type); nvalue = *this->GetState()->GetInitializedCacheValue(name); value = nvalue.c_str(); } @@ -2045,7 +2020,7 @@ void cmMakefile::AddGlobalLinkInformation(cmTarget& target) default:; } - if (cmProp linkLibsProp = this->GetProperty("LINK_LIBRARIES")) { + if (cmValue linkLibsProp = this->GetProperty("LINK_LIBRARIES")) { std::vector<std::string> linkLibs = cmExpandedList(*linkLibsProp); for (auto j = linkLibs.begin(); j != linkLibs.end(); ++j) { @@ -2118,15 +2093,23 @@ cmTarget* cmMakefile::AddExecutable(const std::string& exeName, cmTarget* cmMakefile::AddNewTarget(cmStateEnums::TargetType type, const std::string& name) { - auto it = this->Targets - .emplace(name, - cmTarget(name, type, cmTarget::VisibilityNormal, this, - cmTarget::PerConfig::Yes)) - .first; + return &this->CreateNewTarget(name, type).first; +} + +std::pair<cmTarget&, bool> cmMakefile::CreateNewTarget( + const std::string& name, cmStateEnums::TargetType type, + cmTarget::PerConfig perConfig) +{ + auto ib = this->Targets.emplace( + name, cmTarget(name, type, cmTarget::VisibilityNormal, this, perConfig)); + auto it = ib.first; + if (!ib.second) { + return std::make_pair(std::ref(it->second), false); + } this->OrderedTargets.push_back(&it->second); this->GetGlobalGenerator()->IndexTarget(&it->second); this->GetStateSnapshot().GetDirectory().AddNormalTargetName(name); - return &it->second; + return std::make_pair(std::ref(it->second), true); } cmTarget* cmMakefile::AddNewUtilityTarget(const std::string& utilityName, @@ -2235,7 +2218,7 @@ cmSourceGroup* cmMakefile::GetOrCreateSourceGroup( cmSourceGroup* cmMakefile::GetOrCreateSourceGroup(const std::string& name) { std::string delimiters; - if (cmProp p = this->GetDefinition("SOURCE_GROUP_DELIMITER")) { + if (cmValue p = this->GetDefinition("SOURCE_GROUP_DELIMITER")) { delimiters = *p; } else { delimiters = "/\\"; @@ -2288,7 +2271,7 @@ void cmMakefile::ExpandVariablesCMP0019() } std::ostringstream w; - cmProp includeDirs = this->GetProperty("INCLUDE_DIRECTORIES"); + cmValue includeDirs = this->GetProperty("INCLUDE_DIRECTORIES"); if (includeDirs && mightExpandVariablesCMP0019(includeDirs->c_str())) { std::string dirs = *includeDirs; this->ExpandVariablesInString(dirs, true, true); @@ -2300,7 +2283,7 @@ void cmMakefile::ExpandVariablesCMP0019() << " " << dirs << "\n"; /* clang-format on */ } - this->SetProperty("INCLUDE_DIRECTORIES", dirs.c_str()); + this->SetProperty("INCLUDE_DIRECTORIES", dirs); } // Also for each target's INCLUDE_DIRECTORIES property: @@ -2326,7 +2309,7 @@ void cmMakefile::ExpandVariablesCMP0019() } } - if (cmProp linkDirsProp = this->GetProperty("LINK_DIRECTORIES")) { + if (cmValue linkDirsProp = this->GetProperty("LINK_DIRECTORIES")) { if (mightExpandVariablesCMP0019(linkDirsProp->c_str())) { std::string d = *linkDirsProp; const std::string orig = d; @@ -2342,7 +2325,7 @@ void cmMakefile::ExpandVariablesCMP0019() } } - if (cmProp linkLibsProp = this->GetProperty("LINK_LIBRARIES")) { + if (cmValue linkLibsProp = this->GetProperty("LINK_LIBRARIES")) { std::vector<std::string> linkLibs = cmExpandedList(*linkLibsProp); for (auto l = linkLibs.begin(); l != linkLibs.end(); ++l) { @@ -2386,7 +2369,7 @@ bool cmMakefile::IsOn(const std::string& name) const bool cmMakefile::IsSet(const std::string& name) const { - cmProp value = this->GetDefinition(name); + cmValue value = this->GetDefinition(name); if (!value) { return false; } @@ -2404,12 +2387,12 @@ bool cmMakefile::IsSet(const std::string& name) const bool cmMakefile::PlatformIs32Bit() const { - if (cmProp plat_abi = this->GetDefinition("CMAKE_INTERNAL_PLATFORM_ABI")) { + if (cmValue plat_abi = this->GetDefinition("CMAKE_INTERNAL_PLATFORM_ABI")) { if (*plat_abi == "ELF X32") { return false; } } - if (cmProp sizeof_dptr = this->GetDefinition("CMAKE_SIZEOF_VOID_P")) { + if (cmValue sizeof_dptr = this->GetDefinition("CMAKE_SIZEOF_VOID_P")) { return atoi(sizeof_dptr->c_str()) == 4; } return false; @@ -2417,7 +2400,7 @@ bool cmMakefile::PlatformIs32Bit() const bool cmMakefile::PlatformIs64Bit() const { - if (cmProp sizeof_dptr = this->GetDefinition("CMAKE_SIZEOF_VOID_P")) { + if (cmValue sizeof_dptr = this->GetDefinition("CMAKE_SIZEOF_VOID_P")) { return atoi(sizeof_dptr->c_str()) == 8; } return false; @@ -2425,7 +2408,7 @@ bool cmMakefile::PlatformIs64Bit() const bool cmMakefile::PlatformIsx32() const { - if (cmProp plat_abi = this->GetDefinition("CMAKE_INTERNAL_PLATFORM_ABI")) { + if (cmValue plat_abi = this->GetDefinition("CMAKE_INTERNAL_PLATFORM_ABI")) { if (*plat_abi == "ELF X32") { return true; } @@ -2475,7 +2458,7 @@ const char* cmMakefile::GetSONameFlag(const std::string& language) const name += language; } name += "_FLAG"; - return cmToCStr(this->GetDefinition(name)); + return this->GetDefinition(name).GetCStr(); } bool cmMakefile::CanIWriteThisFile(std::string const& fileName) const @@ -2498,7 +2481,7 @@ const std::string& cmMakefile::GetRequiredDefinition( const std::string& name) const { static std::string const empty; - cmProp def = this->GetDefinition(name); + cmValue def = this->GetDefinition(name); if (!def) { cmSystemTools::Error("Error required internal CMake variable not " "set, cmake may not be built correctly.\n" @@ -2511,7 +2494,7 @@ const std::string& cmMakefile::GetRequiredDefinition( bool cmMakefile::IsDefinitionSet(const std::string& name) const { - cmProp def = this->StateSnapshot.GetDefinition(name); + cmValue def = this->StateSnapshot.GetDefinition(name); if (!def) { def = this->GetState()->GetInitializedCacheValue(name); } @@ -2528,7 +2511,7 @@ bool cmMakefile::IsDefinitionSet(const std::string& name) const bool cmMakefile::IsNormalDefinitionSet(const std::string& name) const { - cmProp def = this->StateSnapshot.GetDefinition(name); + cmValue def = this->StateSnapshot.GetDefinition(name); #ifndef CMAKE_BOOTSTRAP if (cmVariableWatch* vv = this->GetVariableWatch()) { if (!def) { @@ -2540,9 +2523,9 @@ bool cmMakefile::IsNormalDefinitionSet(const std::string& name) const return def != nullptr; } -cmProp cmMakefile::GetDefinition(const std::string& name) const +cmValue cmMakefile::GetDefinition(const std::string& name) const { - cmProp def = this->StateSnapshot.GetDefinition(name); + cmValue def = this->StateSnapshot.GetDefinition(name); if (!def) { def = this->GetState()->GetInitializedCacheValue(name); } @@ -2553,7 +2536,7 @@ cmProp cmMakefile::GetDefinition(const std::string& name) const vv->VariableAccessed(name, def ? cmVariableWatch::VARIABLE_READ_ACCESS : cmVariableWatch::UNKNOWN_VARIABLE_READ_ACCESS, - cmToCStr(def), this); + def.GetCStr(), this); if (watch_function_executed) { // A callback was executed and may have caused re-allocation of the @@ -2571,19 +2554,14 @@ cmProp cmMakefile::GetDefinition(const std::string& name) const const std::string& cmMakefile::GetSafeDefinition(const std::string& name) const { - static std::string const empty; - cmProp def = this->GetDefinition(name); - if (!def) { - return empty; - } - return *def; + return this->GetDefinition(name); } bool cmMakefile::GetDefExpandList(const std::string& name, std::vector<std::string>& out, bool emptyArgs) const { - cmProp def = this->GetDefinition(name); + cmValue def = this->GetDefinition(name); if (!def) { return false; } @@ -2736,7 +2714,7 @@ MessageType cmMakefile::ExpandVariablesInStringOld( // Lookup the definition of VAR. std::string var(first + 1, last - first - 2); - if (cmProp val = this->GetDefinition(var)) { + if (cmValue val = this->GetDefinition(var)) { // Store the value in the output escaping as requested. if (escapeQuotes) { source.append(cmEscapeQuotes(*val)); @@ -2808,6 +2786,7 @@ MessageType cmMakefile::ExpandVariablesInStringOld( case cmPolicies::REQUIRED_ALWAYS: error << "\n" << cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0010); + break; case cmPolicies::NEW: // NEW behavior is to report the error. break; @@ -2941,7 +2920,7 @@ MessageType cmMakefile::ExpandVariablesInStringNew( openstack.pop_back(); result.append(last, in - last); std::string const& lookup = result.substr(var.loc); - cmProp value = nullptr; + cmValue value = nullptr; std::string varresult; std::string svalue; switch (var.domain) { @@ -2959,7 +2938,7 @@ MessageType cmMakefile::ExpandVariablesInStringNew( break; case ENVIRONMENT: if (cmSystemTools::GetEnv(lookup, svalue)) { - value = &svalue; + value = cmValue(svalue); } break; case CACHE: @@ -3086,7 +3065,7 @@ MessageType cmMakefile::ExpandVariablesInStringNew( if (filename && variable == lineVar) { varresult = std::to_string(line); } else { - cmProp def = this->GetDefinition(variable); + cmValue def = this->GetDefinition(variable); if (def) { varresult = *def; } else if (!this->SuppressSideEffects) { @@ -3105,8 +3084,8 @@ MessageType cmMakefile::ExpandVariablesInStringNew( break; } } - // Failed to find a valid @ expansion; treat it as literal. - /* FALLTHROUGH */ + // Failed to find a valid @ expansion; treat it as literal. + CM_FALLTHROUGH; default: { if (!openstack.empty() && !(isalnum(inc) || inc == '_' || inc == '/' || inc == '.' || @@ -3182,6 +3161,23 @@ void cmMakefile::RemoveVariablesInString(std::string& source, } } +void cmMakefile::InitCMAKE_CONFIGURATION_TYPES(std::string const& genDefault) +{ + if (this->GetDefinition("CMAKE_CONFIGURATION_TYPES")) { + return; + } + std::string initConfigs; + if (!cmSystemTools::GetEnv("CMAKE_CONFIGURATION_TYPES", initConfigs)) { + initConfigs = genDefault; + } + this->AddCacheDefinition( + "CMAKE_CONFIGURATION_TYPES", initConfigs, + "Semicolon separated list of supported configuration types, " + "only supports Debug, Release, MinSizeRel, and RelWithDebInfo, " + "anything else will be ignored.", + cmStateEnums::STRING); +} + std::string cmMakefile::GetDefaultConfiguration() const { if (this->GetGlobalGenerator()->IsMultiConfig()) { @@ -3542,8 +3538,8 @@ int cmMakefile::TryCompile(const std::string& srcdir, // make sure the same generator is used // use this program as the cmake to be run, it should not // be run that way but the cmake object requires a vailid path - cmake cm(cmake::RoleProject, cmState::Project); - cm.SetIsInTryCompile(true); + cmake cm(cmake::RoleProject, cmState::Project, + cmState::ProjectKind::TryCompile); auto gg = cm.CreateGlobalGenerator(this->GetGlobalGenerator()->GetName()); if (!gg) { this->IssueMessage(MessageType::INTERNAL_ERROR, @@ -3565,18 +3561,19 @@ int cmMakefile::TryCompile(const std::string& srcdir, cm.SetGeneratorToolset(this->GetSafeDefinition("CMAKE_GENERATOR_TOOLSET")); cm.LoadCache(); if (!cm.GetGlobalGenerator()->IsMultiConfig()) { - if (cmProp config = + if (cmValue config = this->GetDefinition("CMAKE_TRY_COMPILE_CONFIGURATION")) { // Tell the single-configuration generator which one to use. // Add this before the user-provided CMake arguments in case // one of the arguments is -DCMAKE_BUILD_TYPE=... - cm.AddCacheEntry("CMAKE_BUILD_TYPE", config->c_str(), - "Build configuration", cmStateEnums::STRING); + cm.AddCacheEntry("CMAKE_BUILD_TYPE", config, "Build configuration", + cmStateEnums::STRING); } } - cmProp recursionDepth = this->GetDefinition("CMAKE_MAXIMUM_RECURSION_DEPTH"); + cmValue recursionDepth = + this->GetDefinition("CMAKE_MAXIMUM_RECURSION_DEPTH"); if (recursionDepth) { - cm.AddCacheEntry("CMAKE_MAXIMUM_RECURSION_DEPTH", recursionDepth->c_str(), + cm.AddCacheEntry("CMAKE_MAXIMUM_RECURSION_DEPTH", recursionDepth, "Maximum recursion depth", cmStateEnums::STRING); } // if cmake args were provided then pass them in @@ -3709,7 +3706,7 @@ std::string cmMakefile::GetModulesFile(const std::string& filename, std::string moduleInCMakeModulePath; // Always search in CMAKE_MODULE_PATH: - cmProp cmakeModulePath = this->GetDefinition("CMAKE_MODULE_PATH"); + cmValue cmakeModulePath = this->GetDefinition("CMAKE_MODULE_PATH"); if (cmakeModulePath) { std::vector<std::string> modulePath = cmExpandedList(*cmakeModulePath); @@ -3750,7 +3747,7 @@ std::string cmMakefile::GetModulesFile(const std::string& filename, } if (!moduleInCMakeModulePath.empty() && !moduleInCMakeRoot.empty()) { - cmProp currentFile = this->GetDefinition("CMAKE_CURRENT_LIST_FILE"); + cmValue currentFile = this->GetDefinition("CMAKE_CURRENT_LIST_FILE"); std::string mods = cmSystemTools::GetCMakeRoot() + "/Modules/"; if (currentFile && cmSystemTools::IsSubDirectory(*currentFile, mods)) { switch (this->GetPolicyStatus(cmPolicies::CMP0017)) { @@ -3807,7 +3804,7 @@ void cmMakefile::ConfigureString(const std::string& input, std::string& output, // Replace #cmakedefine instances. if (this->cmDefineRegex.find(line)) { - cmProp def = this->GetDefinition(this->cmDefineRegex.match(2)); + cmValue def = this->GetDefinition(this->cmDefineRegex.match(2)); if (!cmIsOff(def)) { const std::string indentation = this->cmDefineRegex.match(1); cmSystemTools::ReplaceString(line, "#" + indentation + "cmakedefine", @@ -3820,7 +3817,7 @@ void cmMakefile::ConfigureString(const std::string& input, std::string& output, } } else if (this->cmDefine01Regex.find(line)) { const std::string indentation = this->cmDefine01Regex.match(1); - cmProp def = this->GetDefinition(this->cmDefine01Regex.match(2)); + cmValue def = this->GetDefinition(this->cmDefine01Regex.match(2)); cmSystemTools::ReplaceString(line, "#" + indentation + "cmakedefine01", "#" + indentation + "define"); output += line; @@ -3966,6 +3963,10 @@ void cmMakefile::SetProperty(const std::string& prop, const char* value) { this->StateSnapshot.GetDirectory().SetProperty(prop, value, this->Backtrace); } +void cmMakefile::SetProperty(const std::string& prop, cmValue value) +{ + this->StateSnapshot.GetDirectory().SetProperty(prop, value, this->Backtrace); +} void cmMakefile::AppendProperty(const std::string& prop, const std::string& value, bool asString) @@ -3974,26 +3975,25 @@ void cmMakefile::AppendProperty(const std::string& prop, this->Backtrace); } -cmProp cmMakefile::GetProperty(const std::string& prop) const +cmValue cmMakefile::GetProperty(const std::string& prop) const { // Check for computed properties. static std::string output; if (prop == "TESTS") { std::vector<std::string> keys; // get list of keys - std::transform(this->Tests.begin(), this->Tests.end(), - std::back_inserter(keys), - [](decltype(this->Tests)::value_type const& pair) { - return pair.first; - }); + const auto* t = this; + std::transform( + t->Tests.begin(), t->Tests.end(), std::back_inserter(keys), + [](decltype(t->Tests)::value_type const& pair) { return pair.first; }); output = cmJoin(keys, ";"); - return &output; + return cmValue(output); } return this->StateSnapshot.GetDirectory().GetProperty(prop); } -cmProp cmMakefile::GetProperty(const std::string& prop, bool chain) const +cmValue cmMakefile::GetProperty(const std::string& prop, bool chain) const { return this->StateSnapshot.GetDirectory().GetProperty(prop, chain); } @@ -4052,7 +4052,7 @@ void cmMakefile::GetTests(const std::string& config, void cmMakefile::AddCMakeDependFilesFromUser() { std::vector<std::string> deps; - if (cmProp deps_str = this->GetProperty("CMAKE_CONFIGURE_DEPENDS")) { + if (cmValue deps_str = this->GetProperty("CMAKE_CONFIGURE_DEPENDS")) { cmExpandList(*deps_str, deps); } for (std::string const& dep : deps) { @@ -4341,7 +4341,7 @@ static std::string const nMatchesVariable = "CMAKE_MATCH_COUNT"; void cmMakefile::ClearMatches() { - cmProp nMatchesStr = this->GetDefinition(nMatchesVariable); + cmValue nMatchesStr = this->GetDefinition(nMatchesVariable); if (!nMatchesStr) { return; } @@ -4394,7 +4394,7 @@ cmPolicies::PolicyStatus cmMakefile::GetPolicyStatus(cmPolicies::PolicyID id, bool cmMakefile::PolicyOptionalWarningEnabled(std::string const& var) const { // Check for an explicit CMAKE_POLICY_WARNING_CMP<NNNN> setting. - if (cmProp val = this->GetDefinition(var)) { + if (cmValue val = this->GetDefinition(var)) { return cmIsOn(val); } // Enable optional policy warnings with --debug-output, --trace, @@ -4426,13 +4426,12 @@ bool cmMakefile::SetPolicy(cmPolicies::PolicyID id, return false; } - // Deprecate old policies, especially those that require a lot - // of code to maintain the old behavior. - if (status == cmPolicies::OLD && id <= cmPolicies::CMP0081 && + // Deprecate old policies. + if (status == cmPolicies::OLD && id <= cmPolicies::CMP0088 && !(this->GetCMakeInstance()->GetIsInTryCompile() && ( // Policies set by cmCoreTryCompile::TryCompileCode. - id == cmPolicies::CMP0065))) { + id == cmPolicies::CMP0065 || id == cmPolicies::CMP0083))) { this->IssueMessage(MessageType::DEPRECATION_WARNING, cmPolicies::GetPolicyDeprecatedWarning(id)); } @@ -4511,7 +4510,8 @@ bool cmMakefile::IgnoreErrorsCMP0061() const bool ignoreErrors = true; switch (this->GetPolicyStatus(cmPolicies::CMP0061)) { case cmPolicies::WARN: - // No warning for this policy! + // No warning for this policy! + CM_FALLTHROUGH; case cmPolicies::OLD: break; case cmPolicies::REQUIRED_IF_USED: diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 77e9c7405..671cdab46 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -13,6 +13,7 @@ #include <stack> #include <string> #include <unordered_map> +#include <utility> #include <vector> #include <cm/optional> @@ -28,11 +29,10 @@ #include "cmMessageType.h" #include "cmNewLineStyle.h" #include "cmPolicies.h" -#include "cmProperty.h" #include "cmSourceFileLocationKind.h" #include "cmStateSnapshot.h" #include "cmStateTypes.h" -#include "cmStringAlgorithms.h" +#include "cmValue.h" // IWYU does not see that 'std::unordered_map<std::string, cmTarget>' // will not compile without the complete type. @@ -230,6 +230,10 @@ public: cmTarget* AddImportedTarget(const std::string& name, cmStateEnums::TargetType type, bool global); + std::pair<cmTarget&, bool> CreateNewTarget( + const std::string& name, cmStateEnums::TargetType type, + cmTarget::PerConfig perConfig = cmTarget::PerConfig::Yes); + cmTarget* AddNewTarget(cmStateEnums::TargetType type, const std::string& name); @@ -282,6 +286,10 @@ public: * can be used in CMake to refer to lists, directories, etc. */ void AddDefinition(const std::string& name, cm::string_view value); + void AddDefinition(const std::string& name, cmValue value) + { + this->AddDefinition(name, *value); + } /** * Add bool variable definition to the build. */ @@ -310,6 +318,8 @@ public: */ void SetProjectName(std::string const& name); + void InitCMAKE_CONFIGURATION_TYPES(std::string const& genDefault); + /* Get the default configuration */ std::string GetDefaultConfiguration() const; @@ -392,13 +402,13 @@ public: * Set a regular expression that include files must match * in order to be considered as part of the depend information. */ - void SetIncludeRegularExpression(const char* regex) + void SetIncludeRegularExpression(const std::string& regex) { - this->SetProperty("INCLUDE_REGULAR_EXPRESSION", regex); + this->SetProperty("INCLUDE_REGULAR_EXPRESSION", regex.c_str()); } - const char* GetIncludeRegularExpression() const + const std::string& GetIncludeRegularExpression() const { - return cmToCStr(this->GetProperty("INCLUDE_REGULAR_EXPRESSION")); + return this->GetProperty("INCLUDE_REGULAR_EXPRESSION"); } /** @@ -482,7 +492,7 @@ public: * If the variable is not found in this makefile instance, the * cache is then queried. */ - cmProp GetDefinition(const std::string&) const; + cmValue GetDefinition(const std::string&) const; const std::string& GetSafeDefinition(const std::string&) const; const std::string& GetRequiredDefinition(const std::string& name) const; bool IsDefinitionSet(const std::string&) const; @@ -762,10 +772,15 @@ public: //! Set/Get a property of this directory void SetProperty(const std::string& prop, const char* value); + void SetProperty(const std::string& prop, cmValue value); + void SetProperty(const std::string& prop, const std::string& value) + { + this->SetProperty(prop, cmValue(value)); + } void AppendProperty(const std::string& prop, const std::string& value, bool asString = false); - cmProp GetProperty(const std::string& prop) const; - cmProp GetProperty(const std::string& prop, bool chain) const; + cmValue GetProperty(const std::string& prop) const; + cmValue GetProperty(const std::string& prop, bool chain) const; bool GetPropertyAsBool(const std::string& prop) const; std::vector<std::string> GetPropertyKeys() const; @@ -867,16 +882,11 @@ public: bool CheckCMP0037(std::string const& targetName, cmStateEnums::TargetType targetType) const; - cmStringRange GetIncludeDirectoriesEntries() const; - cmBacktraceRange GetIncludeDirectoriesBacktraces() const; - cmStringRange GetCompileOptionsEntries() const; - cmBacktraceRange GetCompileOptionsBacktraces() const; - cmStringRange GetCompileDefinitionsEntries() const; - cmBacktraceRange GetCompileDefinitionsBacktraces() const; - cmStringRange GetLinkOptionsEntries() const; - cmBacktraceRange GetLinkOptionsBacktraces() const; - cmStringRange GetLinkDirectoriesEntries() const; - cmBacktraceRange GetLinkDirectoriesBacktraces() const; + cmBTStringRange GetIncludeDirectoriesEntries() const; + cmBTStringRange GetCompileOptionsEntries() const; + cmBTStringRange GetCompileDefinitionsEntries() const; + cmBTStringRange GetLinkOptionsEntries() const; + cmBTStringRange GetLinkDirectoriesEntries() const; std::set<std::string> const& GetSystemIncludeDirectories() const { diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index e7e4a2b6f..575fb0569 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -21,7 +21,6 @@ #include "cmMakefile.h" #include "cmOSXBundleGenerator.h" #include "cmOutputConverter.h" -#include "cmProperty.h" #include "cmRulePlaceholderExpander.h" #include "cmState.h" #include "cmStateDirectory.h" @@ -29,6 +28,7 @@ #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" cmMakefileExecutableTargetGenerator::cmMakefileExecutableTargetGenerator( cmGeneratorTarget* target) @@ -195,6 +195,8 @@ void cmMakefileExecutableTargetGenerator::WriteNvidiaDeviceExecutableRule( this->CreateObjectLists(useLinkScript, false, useResponseFileForObjects, buildObjs, depends, useWatcomQuote); + std::string const& aixExports = this->GetAIXExports(this->GetConfigName()); + cmRulePlaceholderExpander::RuleVariables vars; std::string objectDir = this->GeneratorTarget->GetSupportDirectory(); @@ -215,6 +217,7 @@ void cmMakefileExecutableTargetGenerator::WriteNvidiaDeviceExecutableRule( cmOutputConverter::SHELL); vars.Language = linkLanguage.c_str(); + vars.AIXExports = aixExports.c_str(); vars.Objects = buildObjs.c_str(); vars.ObjectDir = objectDir.c_str(); vars.Target = target.c_str(); @@ -225,8 +228,8 @@ void cmMakefileExecutableTargetGenerator::WriteNvidiaDeviceExecutableRule( std::string launcher; - cmProp val = this->LocalGenerator->GetRuleLauncher(this->GeneratorTarget, - "RULE_LAUNCH_LINK"); + cmValue val = this->LocalGenerator->GetRuleLauncher(this->GeneratorTarget, + "RULE_LAUNCH_LINK"); if (cmNonempty(val)) { launcher = cmStrCat(*val, ' '); } @@ -394,9 +397,8 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) this->LocalGenerator->GetLinkLibsCMP0065( linkLanguage, *this->GeneratorTarget)); - if (this->GeneratorTarget->GetPropertyAsBool("LINK_WHAT_YOU_USE")) { - this->LocalGenerator->AppendFlags(linkFlags, " -Wl,--no-as-needed"); - } + this->UseLWYU = this->LocalGenerator->AppendLWYUFlags( + linkFlags, this->GeneratorTarget, linkLanguage); // Add language feature flags. this->LocalGenerator->AddLanguageFlagsForLinking( @@ -525,14 +527,11 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) std::string manifests = this->GetManifests(this->GetConfigName()); - std::string const& aixExports = this->GetAIXExports(this->GetConfigName()); - cmRulePlaceholderExpander::RuleVariables vars; vars.CMTargetName = this->GeneratorTarget->GetName().c_str(); vars.CMTargetType = cmState::GetTargetTypeName(this->GeneratorTarget->GetType()).c_str(); vars.Language = linkLanguage.c_str(); - vars.AIXExports = aixExports.c_str(); vars.Objects = buildObjs.c_str(); std::string objectDir = this->GeneratorTarget->GetSupportDirectory(); @@ -577,18 +576,24 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) vars.Launcher = linkerLauncher.c_str(); } - if (this->GeneratorTarget->GetPropertyAsBool("LINK_WHAT_YOU_USE")) { - std::string cmakeCommand = - cmStrCat(this->LocalGenerator->ConvertToOutputFormat( - cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL), - " -E __run_co_compile --lwyu=", targetOutPathReal); - real_link_commands.push_back(std::move(cmakeCommand)); + if (this->UseLWYU) { + cmValue lwyuCheck = + this->Makefile->GetDefinition("CMAKE_LINK_WHAT_YOU_USE_CHECK"); + if (lwyuCheck) { + std::string cmakeCommand = cmStrCat( + this->LocalGenerator->ConvertToOutputFormat( + cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL), + " -E __run_co_compile --lwyu="); + cmakeCommand += this->LocalGenerator->EscapeForShell(*lwyuCheck); + cmakeCommand += cmStrCat(" --source=", targetOutPathReal); + real_link_commands.push_back(std::move(cmakeCommand)); + } } std::string launcher; - cmProp val = this->LocalGenerator->GetRuleLauncher(this->GeneratorTarget, - "RULE_LAUNCH_LINK"); + cmValue val = this->LocalGenerator->GetRuleLauncher(this->GeneratorTarget, + "RULE_LAUNCH_LINK"); if (cmNonempty(val)) { launcher = cmStrCat(*val, ' '); } diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index d0e3837dd..ace73a77e 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -21,7 +21,6 @@ #include "cmMakefile.h" #include "cmOSXBundleGenerator.h" #include "cmOutputConverter.h" -#include "cmProperty.h" #include "cmRulePlaceholderExpander.h" #include "cmState.h" #include "cmStateDirectory.h" @@ -29,6 +28,7 @@ #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" cmMakefileLibraryTargetGenerator::cmMakefileLibraryTargetGenerator( cmGeneratorTarget* target) @@ -178,9 +178,9 @@ void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink) this->AddModuleDefinitionFlag(linkLineComputer.get(), extraFlags, this->GetConfigName()); - if (this->GeneratorTarget->GetPropertyAsBool("LINK_WHAT_YOU_USE")) { - this->LocalGenerator->AppendFlags(extraFlags, " -Wl,--no-as-needed"); - } + this->UseLWYU = this->LocalGenerator->AppendLWYUFlags( + extraFlags, this->GeneratorTarget, linkLanguage); + this->WriteLibraryRules(linkRuleVar, extraFlags, relink); } @@ -362,8 +362,8 @@ void cmMakefileLibraryTargetGenerator::WriteNvidiaDeviceLibraryRules( vars.TargetCompilePDB = targetOutPathCompilePDB.c_str(); std::string launcher; - cmProp val = this->LocalGenerator->GetRuleLauncher(this->GeneratorTarget, - "RULE_LAUNCH_LINK"); + cmValue val = this->LocalGenerator->GetRuleLauncher(this->GeneratorTarget, + "RULE_LAUNCH_LINK"); if (cmNonempty(val)) { launcher = cmStrCat(*val, ' '); } @@ -811,8 +811,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules( } std::string launcher; - cmProp val = this->LocalGenerator->GetRuleLauncher(this->GeneratorTarget, - "RULE_LAUNCH_LINK"); + cmValue val = this->LocalGenerator->GetRuleLauncher(this->GeneratorTarget, + "RULE_LAUNCH_LINK"); if (cmNonempty(val)) { launcher = cmStrCat(*val, ' '); } @@ -871,13 +871,18 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules( // Get the set of commands. std::string linkRule = this->GetLinkRule(linkRuleVar); cmExpandList(linkRule, real_link_commands); - if (this->GeneratorTarget->GetPropertyAsBool("LINK_WHAT_YOU_USE") && - (this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY)) { - std::string cmakeCommand = cmStrCat( - this->LocalGenerator->ConvertToOutputFormat( - cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL), - " -E __run_co_compile --lwyu=", targetOutPathReal); - real_link_commands.push_back(std::move(cmakeCommand)); + if (this->UseLWYU) { + cmValue lwyuCheck = + this->Makefile->GetDefinition("CMAKE_LINK_WHAT_YOU_USE_CHECK"); + if (lwyuCheck) { + std::string cmakeCommand = cmStrCat( + this->LocalGenerator->ConvertToOutputFormat( + cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL), + " -E __run_co_compile --lwyu="); + cmakeCommand += this->LocalGenerator->EscapeForShell(*lwyuCheck); + cmakeCommand += cmStrCat(" --source=", targetOutPathReal); + real_link_commands.push_back(std::move(cmakeCommand)); + } } // Expand placeholders. diff --git a/Source/cmMakefileProfilingData.cxx b/Source/cmMakefileProfilingData.cxx index 86188db4c..337f78bf7 100644 --- a/Source/cmMakefileProfilingData.cxx +++ b/Source/cmMakefileProfilingData.cxx @@ -29,7 +29,7 @@ cmMakefileProfilingData::cmMakefileProfilingData( } this->ProfileStream << "["; -}; +} cmMakefileProfilingData::~cmMakefileProfilingData() noexcept { diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 945827701..8edadd31e 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -16,8 +16,6 @@ #include <cmext/algorithm> #include <cmext/string_view> -#include "cm_codecvt.hxx" - #include "cmComputeLinkInformation.h" #include "cmCustomCommand.h" #include "cmCustomCommandGenerator.h" @@ -36,7 +34,6 @@ #include "cmMessageType.h" #include "cmOutputConverter.h" #include "cmPolicies.h" -#include "cmProperty.h" #include "cmRange.h" #include "cmRulePlaceholderExpander.h" #include "cmSourceFile.h" @@ -47,6 +44,7 @@ #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" #include "cmake.h" cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmGeneratorTarget* target) @@ -59,11 +57,13 @@ cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmGeneratorTarget* target) this->LocalGenerator->GetGlobalGenerator()); cmake* cm = this->GlobalGenerator->GetCMakeInstance(); this->NoRuleMessages = false; - if (cmProp ruleStatus = cm->GetState()->GetGlobalProperty("RULE_MESSAGES")) { + if (cmValue ruleStatus = + cm->GetState()->GetGlobalProperty("RULE_MESSAGES")) { this->NoRuleMessages = cmIsOff(*ruleStatus); } switch (this->GeneratorTarget->GetPolicyStatusCMP0113()) { case cmPolicies::WARN: + CM_FALLTHROUGH; case cmPolicies::OLD: this->CMP0113New = false; break; @@ -202,14 +202,14 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules() }; // Look for additional files registered for cleaning in this directory. - if (cmProp prop_value = + if (cmValue prop_value = this->Makefile->GetProperty("ADDITIONAL_MAKE_CLEAN_FILES")) { std::vector<std::string> const files = evaluatedFiles(*prop_value); this->CleanFiles.insert(files.begin(), files.end()); } // Look for additional files registered for cleaning in this target. - if (cmProp prop_value = + if (cmValue prop_value = this->GeneratorTarget->GetProperty("ADDITIONAL_CLEAN_FILES")) { std::vector<std::string> const files = evaluatedFiles(*prop_value); // For relative path support @@ -289,14 +289,13 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules() this->GeneratorTarget->GetExtraSources(extraSources, this->GetConfigName()); this->OSXBundleGenerator->GenerateMacOSXContentStatements( extraSources, this->MacOSXContentGenerator.get(), this->GetConfigName()); - cmProp pchExtension = this->Makefile->GetDefinition("CMAKE_PCH_EXTENSION"); + cmValue pchExtension = this->Makefile->GetDefinition("CMAKE_PCH_EXTENSION"); std::vector<cmSourceFile const*> externalObjects; this->GeneratorTarget->GetExternalObjects(externalObjects, this->GetConfigName()); for (cmSourceFile const* sf : externalObjects) { auto const& objectFileName = sf->GetFullPath(); - if (!cmSystemTools::StringEndsWith(objectFileName, - cmToCStr(pchExtension))) { + if (!cmHasSuffix(objectFileName, pchExtension)) { this->ExternalObjects.push_back(objectFileName); } } @@ -671,12 +670,12 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles( cmSystemTools::GetFilenameWithoutLastExtension(objectName); ispcSource = cmSystemTools::GetFilenameWithoutLastExtension(ispcSource); - cmProp ispcSuffixProp = + cmValue ispcSuffixProp = this->GeneratorTarget->GetProperty("ISPC_HEADER_SUFFIX"); assert(ispcSuffixProp); std::string directory = this->GeneratorTarget->GetObjectDirectory(config); - if (cmProp prop = + if (cmValue prop = this->GeneratorTarget->GetProperty("ISPC_HEADER_DIRECTORY")) { directory = cmStrCat(this->LocalGenerator->GetBinaryDirectory(), '/', *prop); @@ -688,7 +687,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles( // Add flags from source file properties. const std::string COMPILE_FLAGS("COMPILE_FLAGS"); - if (cmProp cflags = source.GetProperty(COMPILE_FLAGS)) { + if (cmValue cflags = source.GetProperty(COMPILE_FLAGS)) { const std::string& evaluatedFlags = genexInterpreter.Evaluate(*cflags, COMPILE_FLAGS); this->LocalGenerator->AppendFlags(flags, evaluatedFlags); @@ -698,7 +697,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles( } const std::string COMPILE_OPTIONS("COMPILE_OPTIONS"); - if (cmProp coptions = source.GetProperty(COMPILE_OPTIONS)) { + if (cmValue coptions = source.GetProperty(COMPILE_OPTIONS)) { const std::string& evaluatedOptions = genexInterpreter.Evaluate(*coptions, COMPILE_OPTIONS); this->LocalGenerator->AppendCompileOptions(flags, evaluatedOptions); @@ -732,7 +731,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles( std::vector<std::string> includes; const std::string INCLUDE_DIRECTORIES("INCLUDE_DIRECTORIES"); - if (cmProp cincludes = source.GetProperty(INCLUDE_DIRECTORIES)) { + if (cmValue cincludes = source.GetProperty(INCLUDE_DIRECTORIES)) { const std::string& evaluatedIncludes = genexInterpreter.Evaluate(*cincludes, INCLUDE_DIRECTORIES); this->LocalGenerator->AppendIncludeDirectories(includes, evaluatedIncludes, @@ -748,7 +747,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles( // Add source-specific preprocessor definitions. const std::string COMPILE_DEFINITIONS("COMPILE_DEFINITIONS"); - if (cmProp compile_defs = source.GetProperty(COMPILE_DEFINITIONS)) { + if (cmValue compile_defs = source.GetProperty(COMPILE_DEFINITIONS)) { const std::string& evaluatedDefs = genexInterpreter.Evaluate(*compile_defs, COMPILE_DEFINITIONS); this->LocalGenerator->AppendDefines(defines, evaluatedDefs); @@ -757,7 +756,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles( << "\n"; } std::string defPropName = cmStrCat("COMPILE_DEFINITIONS_", configUpper); - if (cmProp config_compile_defs = source.GetProperty(defPropName)) { + if (cmValue config_compile_defs = source.GetProperty(defPropName)) { const std::string& evaluatedDefs = genexInterpreter.Evaluate(*config_compile_defs, COMPILE_DEFINITIONS); this->LocalGenerator->AppendDefines(defines, evaluatedDefs); @@ -947,11 +946,11 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles( this->GetIncludes(lang, this->GetConfigName())); } - cmProp eliminate[] = { + cmValue eliminate[] = { this->Makefile->GetDefinition("CMAKE_START_TEMP_FILE"), this->Makefile->GetDefinition("CMAKE_END_TEMP_FILE") }; - for (cmProp el : eliminate) { + for (cmValue el : eliminate) { if (el) { cmSystemTools::ReplaceString(compileCommand, *el, ""); } @@ -968,7 +967,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles( lang == "HIP" || lang == "ISPC" || lang == "OBJC" || lang == "OBJCXX")) { std::string const clauncher_prop = lang + "_COMPILER_LAUNCHER"; - cmProp clauncher = this->GeneratorTarget->GetProperty(clauncher_prop); + cmValue clauncher = this->GeneratorTarget->GetProperty(clauncher_prop); if (cmNonempty(clauncher)) { compilerLauncher = *clauncher; } @@ -978,10 +977,10 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles( if (!compileCommands.empty() && (lang == "C" || lang == "CXX" || lang == "OBJC" || lang == "OBJCXX")) { std::string const tidy_prop = lang + "_CLANG_TIDY"; - cmProp tidy = this->GeneratorTarget->GetProperty(tidy_prop); - cmProp iwyu = nullptr; - cmProp cpplint = nullptr; - cmProp cppcheck = nullptr; + cmValue tidy = this->GeneratorTarget->GetProperty(tidy_prop); + cmValue iwyu = nullptr; + cmValue cpplint = nullptr; + cmValue cppcheck = nullptr; if (lang == "C" || lang == "CXX") { std::string const iwyu_prop = lang + "_INCLUDE_WHAT_YOU_USE"; iwyu = this->GeneratorTarget->GetProperty(iwyu_prop); @@ -1002,12 +1001,30 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles( } if (cmNonempty(iwyu)) { run_iwyu += " --iwyu="; - run_iwyu += this->LocalGenerator->EscapeForShell(*iwyu); + + // Only add --driver-mode if it is not already specified, as adding + // it unconditionally might override a user-specified driver-mode + if (iwyu.Get()->find("--driver-mode=") == std::string::npos) { + cmValue p = this->Makefile->GetDefinition( + cmStrCat("CMAKE_", lang, "_INCLUDE_WHAT_YOU_USE_DRIVER_MODE")); + std::string driverMode; + + if (cmNonempty(p)) { + driverMode = *p; + } else { + driverMode = lang == "C" ? "gcc" : "g++"; + } + + run_iwyu += this->LocalGenerator->EscapeForShell( + cmStrCat(*iwyu, ";--driver-mode=", driverMode)); + } else { + run_iwyu += this->LocalGenerator->EscapeForShell(*iwyu); + } } if (cmNonempty(tidy)) { run_iwyu += " --tidy="; - cmProp p = this->Makefile->GetDefinition("CMAKE_" + lang + - "_CLANG_TIDY_DRIVER_MODE"); + cmValue p = this->Makefile->GetDefinition("CMAKE_" + lang + + "_CLANG_TIDY_DRIVER_MODE"); std::string driverMode; if (cmNonempty(p)) { driverMode = *p; @@ -1051,7 +1068,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles( std::string launcher; { - cmProp val = this->LocalGenerator->GetRuleLauncher( + cmValue val = this->LocalGenerator->GetRuleLauncher( this->GeneratorTarget, "RULE_LAUNCH_COMPILE"); if (cmNonempty(val)) { launcher = cmStrCat(*val, ' '); @@ -1121,7 +1138,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles( // Check for extra outputs created by the compilation. std::vector<std::string> outputs(1, relativeObj); - if (cmProp extra_outputs_str = source.GetProperty("OBJECT_OUTPUTS")) { + if (cmValue extra_outputs_str = source.GetProperty("OBJECT_OUTPUTS")) { std::string evaluated_outputs = cmGeneratorExpression::Evaluate( *extra_outputs_str, this->LocalGenerator, config); @@ -1176,7 +1193,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles( std::string preprocessRuleVar = cmStrCat("CMAKE_", lang, "_CREATE_PREPROCESSED_SOURCE"); - if (cmProp preprocessRule = + if (cmValue preprocessRule = this->Makefile->GetDefinition(preprocessRuleVar)) { std::vector<std::string> preprocessCommands = cmExpandedList(*preprocessRule); @@ -1221,7 +1238,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles( std::string assemblyRuleVar = cmStrCat("CMAKE_", lang, "_CREATE_ASSEMBLY_SOURCE"); - if (cmProp assemblyRule = + if (cmValue assemblyRule = this->Makefile->GetDefinition(assemblyRuleVar)) { std::vector<std::string> assemblyCommands = cmExpandedList(*assemblyRule); @@ -1400,6 +1417,13 @@ void cmMakefileTargetGenerator::WriteTargetDependRules() << "set(CMAKE_Fortran_TARGET_MODULE_DIR \"" << this->GeneratorTarget->GetFortranModuleDirectory(working_dir) << "\")\n"; + + if (this->GeneratorTarget->IsFortranBuildingInstrinsicModules()) { + *this->InfoFileStream + << "\n" + << "# Fortran compiler is building intrinsic modules.\n" + << "set(CMAKE_Fortran_TARGET_BUILDING_INSTRINSIC_MODULES ON) \n"; + } /* clang-format on */ // and now write the rule to use it @@ -1485,7 +1509,7 @@ void cmMakefileTargetGenerator::WriteObjectDependRules( // Create the list of dependencies known at cmake time. These are // shared between the object file and dependency scanning rule. depends.push_back(source.GetFullPath()); - if (cmProp objectDeps = source.GetProperty("OBJECT_DEPENDS")) { + if (cmValue objectDeps = source.GetProperty("OBJECT_DEPENDS")) { cmExpandList(*objectDeps, depends); } } @@ -1724,10 +1748,10 @@ void cmMakefileTargetGenerator::WriteObjectsVariable( std::string object; const auto& lineContinue = this->GlobalGenerator->LineContinueDirective; - cmProp pchExtension = this->Makefile->GetDefinition("CMAKE_PCH_EXTENSION"); + cmValue pchExtension = this->Makefile->GetDefinition("CMAKE_PCH_EXTENSION"); for (std::string const& obj : this->Objects) { - if (cmSystemTools::StringEndsWith(obj, cmToCStr(pchExtension))) { + if (cmHasSuffix(obj, pchExtension)) { continue; } *this->BuildFileStream << " " << lineContinue; @@ -1811,13 +1835,13 @@ private: void cmMakefileTargetGenerator::WriteObjectsStrings( std::vector<std::string>& objStrings, std::string::size_type limit) { - cmProp pchExtension = this->Makefile->GetDefinition("CMAKE_PCH_EXTENSION"); + cmValue pchExtension = this->Makefile->GetDefinition("CMAKE_PCH_EXTENSION"); cmMakefileTargetGeneratorObjectStrings helper( objStrings, this->LocalGenerator, this->LocalGenerator->GetStateSnapshot().GetDirectory(), limit); for (std::string const& obj : this->Objects) { - if (cmSystemTools::StringEndsWith(obj, cmToCStr(pchExtension))) { + if (cmHasSuffix(obj, pchExtension)) { continue; } helper.Feed(obj); @@ -1946,7 +1970,7 @@ std::string cmMakefileTargetGenerator::GetLinkRule( cmStrCat("CMAKE_", this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName()), "_GNUtoMS_RULE"); - if (cmProp rule = this->Makefile->GetDefinition(ruleVar)) { + if (cmValue rule = this->Makefile->GetDefinition(ruleVar)) { linkRule += *rule; } } @@ -1995,7 +2019,7 @@ bool cmMakefileTargetGenerator::CheckUseResponseFileForObjects( // Check for an explicit setting one way or the other. std::string const responseVar = "CMAKE_" + l + "_USE_RESPONSE_FILE_FOR_OBJECTS"; - if (cmProp val = this->Makefile->GetDefinition(responseVar)) { + if (cmValue val = this->Makefile->GetDefinition(responseVar)) { if (!val->empty()) { return cmIsOn(val); } @@ -2034,7 +2058,7 @@ bool cmMakefileTargetGenerator::CheckUseResponseFileForLibraries( // Check for an explicit setting one way or the other. std::string const responseVar = "CMAKE_" + l + "_USE_RESPONSE_FILE_FOR_LIBRARIES"; - if (cmProp val = this->Makefile->GetDefinition(responseVar)) { + if (cmValue val = this->Makefile->GetDefinition(responseVar)) { if (!val->empty()) { return cmIsOn(val); } @@ -2048,22 +2072,11 @@ std::string cmMakefileTargetGenerator::CreateResponseFile( const char* name, std::string const& options, std::vector<std::string>& makefile_depends) { - // FIXME: Find a better way to determine the response file encoding, - // perhaps using tool-specific platform information variables. - // For now, use the makefile encoding as a heuristic. - codecvt::Encoding responseEncoding = - this->GlobalGenerator->GetMakefileEncoding(); - // Non-MSVC tooling may not understand a BOM. - if (responseEncoding == codecvt::UTF8_WITH_BOM && - !this->Makefile->IsOn("MSVC")) { - responseEncoding = codecvt::UTF8; - } - // Create the response file. std::string responseFileNameFull = cmStrCat(this->TargetBuildDirectoryFull, '/', name); - cmGeneratedFileStream responseStream(responseFileNameFull, false, - responseEncoding); + cmGeneratedFileStream responseStream( + responseFileNameFull, false, this->GlobalGenerator->GetMakefileEncoding()); responseStream.SetCopyIfDifferent(true); responseStream << options << "\n"; @@ -2109,7 +2122,7 @@ void cmMakefileTargetGenerator::CreateLinkLibs( this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName()), "_RESPONSE_FILE_LINK_FLAG"); std::string responseFlag; - if (cmProp p = this->Makefile->GetDefinition(responseFlagVar)) { + if (cmValue p = this->Makefile->GetDefinition(responseFlagVar)) { responseFlag = *p; } else { responseFlag = "@"; @@ -2149,7 +2162,7 @@ void cmMakefileTargetGenerator::CreateObjectLists( this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName()), "_RESPONSE_FILE_LINK_FLAG"); std::string responseFlag; - if (cmProp p = this->Makefile->GetDefinition(responseFlagVar)) { + if (cmValue p = this->Makefile->GetDefinition(responseFlagVar)) { responseFlag = *p; } else { responseFlag = "@"; @@ -2244,7 +2257,7 @@ void cmMakefileTargetGenerator::GenDefFile( cmd += this->LocalGenerator->ConvertToOutputFormat( this->LocalGenerator->MaybeRelativeToCurBinDir(objlist_file), cmOutputConverter::SHELL); - cmProp nm_executable = this->Makefile->GetDefinition("CMAKE_NM"); + cmValue nm_executable = this->Makefile->GetDefinition("CMAKE_NM"); if (cmNonempty(nm_executable)) { cmd += " --nm="; cmd += this->LocalCommonGenerator->ConvertToOutputFormat( diff --git a/Source/cmMarkAsAdvancedCommand.cxx b/Source/cmMarkAsAdvancedCommand.cxx index 45043faa5..73e5f33b5 100644 --- a/Source/cmMarkAsAdvancedCommand.cxx +++ b/Source/cmMarkAsAdvancedCommand.cxx @@ -10,6 +10,7 @@ #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" #include "cmake.h" // cmMarkAsAdvancedCommand diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 5c21d1b7e..517d52955 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -32,7 +32,6 @@ #include "cmNinjaTypes.h" #include "cmOSXBundleGenerator.h" #include "cmOutputConverter.h" -#include "cmProperty.h" #include "cmRulePlaceholderExpander.h" #include "cmSourceFile.h" #include "cmState.h" @@ -41,6 +40,7 @@ #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" cmNinjaNormalTargetGenerator::cmNinjaNormalTargetGenerator( cmGeneratorTarget* target) @@ -267,7 +267,7 @@ void cmNinjaNormalTargetGenerator::WriteNvidiaDeviceLinkRule( vars.LanguageCompileFlags = "$LANGUAGE_COMPILE_FLAGS"; std::string launcher; - cmProp val = this->GetLocalGenerator()->GetRuleLauncher( + cmValue val = this->GetLocalGenerator()->GetRuleLauncher( this->GetGeneratorTarget(), "RULE_LAUNCH_LINK"); if (cmNonempty(val)) { launcher = cmStrCat(*val, ' '); @@ -390,7 +390,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile, // build response file name std::string cmakeLinkVar = cmakeVarLang + "_RESPONSE_FILE_LINK_FLAG"; - cmProp flag = this->GetMakefile()->GetDefinition(cmakeLinkVar); + cmValue flag = this->GetMakefile()->GetDefinition(cmakeLinkVar); if (flag) { responseFlag = *flag; @@ -462,7 +462,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile, } std::string launcher; - cmProp val = this->GetLocalGenerator()->GetRuleLauncher( + cmValue val = this->GetLocalGenerator()->GetRuleLauncher( this->GetGeneratorTarget(), "RULE_LAUNCH_LINK"); if (cmNonempty(val)) { launcher = cmStrCat(*val, ' '); @@ -569,29 +569,35 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd( // CMAKE_<lang>_CREATE_STATIC_LIBRARY_IPO define instead. std::string linkCmdVar = this->GetGeneratorTarget()->GetCreateRuleVariable( this->TargetLinkLanguage(config), config); - cmProp linkCmd = mf->GetDefinition(linkCmdVar); + cmValue linkCmd = mf->GetDefinition(linkCmdVar); if (linkCmd) { std::string linkCmdStr = *linkCmd; if (this->GetGeneratorTarget()->HasImplibGNUtoMS(config)) { std::string ruleVar = cmStrCat("CMAKE_", this->GeneratorTarget->GetLinkerLanguage(config), "_GNUtoMS_RULE"); - if (cmProp rule = this->Makefile->GetDefinition(ruleVar)) { + if (cmValue rule = this->Makefile->GetDefinition(ruleVar)) { linkCmdStr += *rule; } } cmExpandList(linkCmdStr, linkCmds); - if (this->GetGeneratorTarget()->GetPropertyAsBool("LINK_WHAT_YOU_USE")) { - std::string cmakeCommand = cmStrCat( - this->GetLocalGenerator()->ConvertToOutputFormat( - cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL), - " -E __run_co_compile --lwyu="); - cmGeneratorTarget& gt = *this->GetGeneratorTarget(); - std::string targetOutputReal = this->ConvertToNinjaPath( - gt.GetFullPath(config, cmStateEnums::RuntimeBinaryArtifact, - /*realname=*/true)); - cmakeCommand += targetOutputReal; - linkCmds.push_back(std::move(cmakeCommand)); + if (this->UseLWYU) { + cmValue lwyuCheck = mf->GetDefinition("CMAKE_LINK_WHAT_YOU_USE_CHECK"); + if (lwyuCheck) { + std::string cmakeCommand = cmStrCat( + this->GetLocalGenerator()->ConvertToOutputFormat( + cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL), + " -E __run_co_compile --lwyu="); + cmakeCommand += + this->GetLocalGenerator()->EscapeForShell(*lwyuCheck); + + std::string targetOutputReal = + this->ConvertToNinjaPath(this->GetGeneratorTarget()->GetFullPath( + config, cmStateEnums::RuntimeBinaryArtifact, + /*realname=*/true)); + cmakeCommand += cmStrCat(" --source=", targetOutputReal); + linkCmds.push_back(std::move(cmakeCommand)); + } } return linkCmds; } @@ -896,7 +902,7 @@ void cmNinjaNormalTargetGenerator::WriteNvidiaDeviceLinkStatement( const std::string impLibPath = localGen.ConvertToOutputFormat( targetOutputImplib, cmOutputConverter::SHELL); vars["TARGET_IMPLIB"] = impLibPath; - this->EnsureParentDirectoryExists(impLibPath); + this->EnsureParentDirectoryExists(targetOutputImplib); } const std::string objPath = @@ -1038,7 +1044,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement( }(); vars["SWIFT_MODULE_NAME"] = [gt]() -> std::string { - if (cmProp name = gt->GetProperty("Swift_MODULE_NAME")) { + if (cmValue name = gt->GetProperty("Swift_MODULE_NAME")) { return *name; } return gt->GetName(); @@ -1047,13 +1053,13 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement( vars["SWIFT_MODULE"] = [this](const std::string& module) -> std::string { std::string directory = this->GetLocalGenerator()->GetCurrentBinaryDirectory(); - if (cmProp prop = this->GetGeneratorTarget()->GetProperty( + if (cmValue prop = this->GetGeneratorTarget()->GetProperty( "Swift_MODULE_DIRECTORY")) { directory = *prop; } std::string name = module + ".swiftmodule"; - if (cmProp prop = + if (cmValue prop = this->GetGeneratorTarget()->GetProperty("Swift_MODULE")) { name = *prop; } @@ -1156,12 +1162,11 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement( this->AddModuleDefinitionFlag(linkLineComputer.get(), vars["LINK_FLAGS"], config); - if (gt->GetPropertyAsBool("LINK_WHAT_YOU_USE") && - (gt->GetType() == cmStateEnums::TargetType::EXECUTABLE || - gt->GetType() == cmStateEnums::TargetType::SHARED_LIBRARY || - gt->GetType() == cmStateEnums::TargetType::MODULE_LIBRARY)) { - vars["LINK_FLAGS"] += " -Wl,--no-as-needed"; - } + + this->UseLWYU = this->GetLocalGenerator()->AppendLWYUFlags( + vars["LINK_FLAGS"], this->GetGeneratorTarget(), + this->TargetLinkLanguage(config)); + vars["LINK_FLAGS"] = globalGen->EncodeLiteral(vars["LINK_FLAGS"]); vars["MANIFESTS"] = this->GetManifests(config); @@ -1206,7 +1211,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement( const std::string impLibPath = localGen.ConvertToOutputFormat( targetOutputImplib, cmOutputConverter::SHELL); vars["TARGET_IMPLIB"] = impLibPath; - this->EnsureParentDirectoryExists(impLibPath); + this->EnsureParentDirectoryExists(targetOutputImplib); if (gt->HasImportLibrary(config)) { // Some linkers may update a binary without touching its import lib. byproducts.ExplicitOuts.emplace_back(targetOutputImplib); @@ -1226,7 +1231,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement( gt->GetFullNameComponents(prefix, base, suffix, config); std::string dbg_suffix = ".dbg"; // TODO: Where to document? - if (cmProp d = mf->GetDefinition("CMAKE_DEBUG_SYMBOL_SUFFIX")) { + if (cmValue d = mf->GetDefinition("CMAKE_DEBUG_SYMBOL_SUFFIX")) { dbg_suffix = *d; } vars["TARGET_PDB"] = base + suffix + dbg_suffix; @@ -1292,7 +1297,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement( cmd += this->GetLocalGenerator()->ConvertToOutputFormat( obj_list_file, cmOutputConverter::SHELL); - cmProp nm_executable = this->GetMakefile()->GetDefinition("CMAKE_NM"); + cmValue nm_executable = this->GetMakefile()->GetDefinition("CMAKE_NM"); if (cmNonempty(nm_executable)) { cmd += " --nm="; cmd += this->LocalCommonGenerator->ConvertToOutputFormat( @@ -1346,7 +1351,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement( // build response file name std::string cmakeLinkVar = cmakeVarLang + "_RESPONSE_FILE_LINK_FLAG"; - cmProp flag = this->GetMakefile()->GetDefinition(cmakeLinkVar); + cmValue flag = this->GetMakefile()->GetDefinition(cmakeLinkVar); bool const lang_supports_response = !(this->TargetLinkLanguage(config) == "RC" || diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 609848b43..57657b1c7 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -31,7 +31,6 @@ #include "cmNinjaNormalTargetGenerator.h" #include "cmNinjaUtilityTargetGenerator.h" #include "cmOutputConverter.h" -#include "cmProperty.h" #include "cmRange.h" #include "cmRulePlaceholderExpander.h" #include "cmSourceFile.h" @@ -40,6 +39,7 @@ #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" #include "cmake.h" std::unique_ptr<cmNinjaTargetGenerator> cmNinjaTargetGenerator::New( @@ -224,13 +224,13 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject( this->LocalGenerator, config, this->GeneratorTarget, language); const std::string COMPILE_FLAGS("COMPILE_FLAGS"); - if (cmProp cflags = source->GetProperty(COMPILE_FLAGS)) { + if (cmValue cflags = source->GetProperty(COMPILE_FLAGS)) { this->LocalGenerator->AppendFlags( flags, genexInterpreter.Evaluate(*cflags, COMPILE_FLAGS)); } const std::string COMPILE_OPTIONS("COMPILE_OPTIONS"); - if (cmProp coptions = source->GetProperty(COMPILE_OPTIONS)) { + if (cmValue coptions = source->GetProperty(COMPILE_OPTIONS)) { this->LocalGenerator->AppendCompileOptions( flags, genexInterpreter.Evaluate(*coptions, COMPILE_OPTIONS)); } @@ -290,14 +290,14 @@ std::string cmNinjaTargetGenerator::ComputeDefines(cmSourceFile const* source, } const std::string COMPILE_DEFINITIONS("COMPILE_DEFINITIONS"); - if (cmProp compile_defs = source->GetProperty(COMPILE_DEFINITIONS)) { + if (cmValue compile_defs = source->GetProperty(COMPILE_DEFINITIONS)) { this->LocalGenerator->AppendDefines( defines, genexInterpreter.Evaluate(*compile_defs, COMPILE_DEFINITIONS)); } std::string defPropName = cmStrCat("COMPILE_DEFINITIONS_", cmSystemTools::UpperCase(config)); - if (cmProp config_compile_defs = source->GetProperty(defPropName)) { + if (cmValue config_compile_defs = source->GetProperty(defPropName)) { this->LocalGenerator->AppendDefines( defines, genexInterpreter.Evaluate(*config_compile_defs, COMPILE_DEFINITIONS)); @@ -318,7 +318,7 @@ std::string cmNinjaTargetGenerator::ComputeIncludes( this->LocalGenerator, config, this->GeneratorTarget, language); const std::string INCLUDE_DIRECTORIES("INCLUDE_DIRECTORIES"); - if (cmProp cincludes = source->GetProperty(INCLUDE_DIRECTORIES)) { + if (cmValue cincludes = source->GetProperty(INCLUDE_DIRECTORIES)) { this->LocalGenerator->AppendIncludeDirectories( includes, genexInterpreter.Evaluate(*cincludes, INCLUDE_DIRECTORIES), *source); @@ -638,7 +638,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang, cmLocalGenerator::SHELL); std::string launcher; - cmProp val = this->GetLocalGenerator()->GetRuleLauncher( + cmValue val = this->GetLocalGenerator()->GetRuleLauncher( this->GetGeneratorTarget(), "RULE_LAUNCH_COMPILE"); if (cmNonempty(val)) { launcher = cmStrCat(*val, ' '); @@ -771,11 +771,14 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang, if (!mf->GetIsSourceFileTryCompile()) { rule.DepType = "gcc"; rule.DepFile = "$DEP_FILE"; - cmProp d = mf->GetDefinition("CMAKE_C_COMPILER"); + cmValue d = mf->GetDefinition("CMAKE_C_COMPILER"); const std::string cl = d ? *d : mf->GetSafeDefinition("CMAKE_CXX_COMPILER"); - cldeps = cmStrCat('"', cmSystemTools::GetCMClDepsCommand(), "\" ", lang, - ' ', vars.Source, " $DEP_FILE $out \"", + std::string cmcldepsPath; + cmSystemTools::GetShortPath(cmSystemTools::GetCMClDepsCommand(), + cmcldepsPath); + cldeps = cmStrCat(cmcldepsPath, ' ', lang, ' ', vars.Source, + " $DEP_FILE $out \"", mf->GetSafeDefinition("CMAKE_CL_SHOWINCLUDES_PREFIX"), "\" \"", cl, "\" "); } @@ -840,7 +843,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang, lang == "HIP" || lang == "ISPC" || lang == "OBJC" || lang == "OBJCXX")) { std::string const clauncher_prop = cmStrCat(lang, "_COMPILER_LAUNCHER"); - cmProp clauncher = this->GeneratorTarget->GetProperty(clauncher_prop); + cmValue clauncher = this->GeneratorTarget->GetProperty(clauncher_prop); if (cmNonempty(clauncher)) { compilerLauncher = *clauncher; } @@ -850,10 +853,10 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang, if (!compileCmds.empty() && (lang == "C" || lang == "CXX" || lang == "OBJC" || lang == "OBJCXX")) { std::string const tidy_prop = cmStrCat(lang, "_CLANG_TIDY"); - cmProp tidy = this->GeneratorTarget->GetProperty(tidy_prop); - cmProp iwyu = nullptr; - cmProp cpplint = nullptr; - cmProp cppcheck = nullptr; + cmValue tidy = this->GeneratorTarget->GetProperty(tidy_prop); + cmValue iwyu = nullptr; + cmValue cpplint = nullptr; + cmValue cppcheck = nullptr; if (lang == "C" || lang == "CXX") { std::string const iwyu_prop = cmStrCat(lang, "_INCLUDE_WHAT_YOU_USE"); iwyu = this->GeneratorTarget->GetProperty(iwyu_prop); @@ -874,12 +877,30 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang, compilerLauncher.clear(); } if (cmNonempty(iwyu)) { - run_iwyu += cmStrCat(" --iwyu=", - this->GetLocalGenerator()->EscapeForShell(*iwyu)); + run_iwyu += " --iwyu="; + + // Only add --driver-mode if it is not already specified, as adding + // it unconditionally might override a user-specified driver-mode + if (iwyu.Get()->find("--driver-mode=") == std::string::npos) { + cmValue p = this->Makefile->GetDefinition( + cmStrCat("CMAKE_", lang, "_INCLUDE_WHAT_YOU_USE_DRIVER_MODE")); + std::string driverMode; + + if (cmNonempty(p)) { + driverMode = *p; + } else { + driverMode = lang == "C" ? "gcc" : "g++"; + } + + run_iwyu += this->LocalGenerator->EscapeForShell( + cmStrCat(*iwyu, ";--driver-mode=", driverMode)); + } else { + run_iwyu += this->LocalGenerator->EscapeForShell(*iwyu); + } } if (cmNonempty(tidy)) { run_iwyu += " --tidy="; - cmProp p = this->Makefile->GetDefinition( + cmValue p = this->Makefile->GetDefinition( cmStrCat("CMAKE_", lang, "_CLANG_TIDY_DRIVER_MODE")); std::string driverMode; if (cmNonempty(p)) { @@ -986,7 +1007,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements( config); } if (firstForConfig) { - cmProp pchExtension = + cmValue pchExtension = this->GetMakefile()->GetDefinition("CMAKE_PCH_EXTENSION"); std::vector<cmSourceFile const*> externalObjects; @@ -994,8 +1015,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements( for (cmSourceFile const* sf : externalObjects) { auto objectFileName = this->GetGlobalGenerator()->ExpandCFGIntDir( this->ConvertToNinjaPath(sf->GetFullPath()), config); - if (!cmSystemTools::StringEndsWith(objectFileName, - cmToCStr(pchExtension))) { + if (!cmHasSuffix(objectFileName, pchExtension)) { this->Configs[config].Objects.push_back(objectFileName); } } @@ -1092,7 +1112,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements( "output-file-map.json"); std::string const targetSwiftDepsPath = [this, config]() -> std::string { cmGeneratorTarget const* target = this->GeneratorTarget; - if (cmProp name = target->GetProperty("Swift_DEPENDENCIES_FILE")) { + if (cmValue name = target->GetProperty("Swift_DEPENDENCIES_FILE")) { return *name; } return this->ConvertToNinjaPath( @@ -1216,7 +1236,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( // build response file name std::string cmakeLinkVar = cmStrCat(cmakeVarLang, "_RESPONSE_FILE_FLAG"); - cmProp flag = this->GetMakefile()->GetDefinition(cmakeLinkVar); + cmValue flag = this->GetMakefile()->GetDefinition(cmakeLinkVar); bool const lang_supports_response = !(language == "RC" || (language == "CUDA" && !flag)); @@ -1258,10 +1278,9 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( objBuild.Outputs.push_back(objectFileName); if (firstForConfig) { - cmProp pchExtension = + cmValue pchExtension = this->GetMakefile()->GetDefinition("CMAKE_PCH_EXTENSION"); - if (!cmSystemTools::StringEndsWith(objectFileName, - cmToCStr(pchExtension))) { + if (!cmHasSuffix(objectFileName, pchExtension)) { // Add this object to the list of object files. this->Configs[config].Objects.push_back(objectFileName); } @@ -1299,7 +1318,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( } } - if (cmProp objectDeps = source->GetProperty("OBJECT_DEPENDS")) { + if (cmValue objectDeps = source->GetProperty("OBJECT_DEPENDS")) { std::vector<std::string> objDepList = cmExpandedList(*objectDeps); std::copy(objDepList.begin(), objDepList.end(), std::back_inserter(depList)); @@ -1445,13 +1464,13 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( cmSystemTools::GetFilenameWithoutLastExtension(objectName); ispcSource = cmSystemTools::GetFilenameWithoutLastExtension(ispcSource); - cmProp ispcSuffixProp = + cmValue ispcSuffixProp = this->GeneratorTarget->GetProperty("ISPC_HEADER_SUFFIX"); assert(ispcSuffixProp); std::string ispcHeaderDirectory = this->GeneratorTarget->GetObjectDirectory(config); - if (cmProp prop = + if (cmValue prop = this->GeneratorTarget->GetProperty("ISPC_HEADER_DIRECTORY")) { ispcHeaderDirectory = cmStrCat(this->LocalGenerator->GetBinaryDirectory(), '/', *prop); @@ -1502,7 +1521,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( objBuild, commandLineLengthLimit); } - if (cmProp objectOutputs = source->GetProperty("OBJECT_OUTPUTS")) { + if (cmValue objectOutputs = source->GetProperty("OBJECT_OUTPUTS")) { std::string evaluatedObjectOutputs = cmGeneratorExpression::Evaluate( *objectOutputs, this->LocalGenerator, config); @@ -1582,13 +1601,13 @@ void cmNinjaTargetGenerator::EmitSwiftDependencyInfo( std::string const objectFilePath = this->ConvertToNinjaPath(this->GetObjectFilePath(source, config)); std::string const swiftDepsPath = [source, objectFilePath]() -> std::string { - if (cmProp name = source->GetProperty("Swift_DEPENDENCIES_FILE")) { + if (cmValue name = source->GetProperty("Swift_DEPENDENCIES_FILE")) { return *name; } return cmStrCat(objectFilePath, ".swiftdeps"); }(); std::string const swiftDiaPath = [source, objectFilePath]() -> std::string { - if (cmProp name = source->GetProperty("Swift_DIAGNOSTICS_FILE")) { + if (cmValue name = source->GetProperty("Swift_DIAGNOSTICS_FILE")) { return *name; } return cmStrCat(objectFilePath, ".dia"); @@ -1696,7 +1715,7 @@ void cmNinjaTargetGenerator::ExportObjectCompileCommand( void cmNinjaTargetGenerator::AdditionalCleanFiles(const std::string& config) { - if (cmProp prop_value = + if (cmValue prop_value = this->GeneratorTarget->GetProperty("ADDITIONAL_CLEAN_FILES")) { cmLocalNinjaGenerator* lg = this->LocalGenerator; std::vector<std::string> cleanFiles; @@ -1730,7 +1749,7 @@ void cmNinjaTargetGenerator::EnsureDirectoryExists( } else { cmGlobalNinjaGenerator* gg = this->GetGlobalGenerator(); std::string fullPath = gg->GetCMakeInstance()->GetHomeOutputDirectory(); - // Also ensures their is a trailing slash. + // Also ensures there is a trailing slash. gg->StripNinjaOutputPathPrefixAsSuffix(fullPath); fullPath += path; cmSystemTools::MakeDirectory(fullPath); @@ -1786,7 +1805,7 @@ void cmNinjaTargetGenerator::addPoolNinjaVariable( const std::string& pool_property, cmGeneratorTarget* target, cmNinjaVars& vars) { - cmProp pool = target->GetProperty(pool_property); + cmValue pool = target->GetProperty(pool_property); if (pool) { vars["pool"] = *pool; } diff --git a/Source/cmNinjaUtilityTargetGenerator.cxx b/Source/cmNinjaUtilityTargetGenerator.cxx index 1f5a7ff4c..15197ba27 100644 --- a/Source/cmNinjaUtilityTargetGenerator.cxx +++ b/Source/cmNinjaUtilityTargetGenerator.cxx @@ -18,12 +18,12 @@ #include "cmLocalNinjaGenerator.h" #include "cmNinjaTypes.h" #include "cmOutputConverter.h" -#include "cmProperty.h" #include "cmSourceFile.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" +#include "cmValue.h" cmNinjaUtilityTargetGenerator::cmNinjaUtilityTargetGenerator( cmGeneratorTarget* target) @@ -141,7 +141,7 @@ void cmNinjaUtilityTargetGenerator::WriteUtilBuildStatements( std::string command = lg->BuildCommandLine( commands, config, fileConfig, "utility", this->GeneratorTarget); std::string desc; - cmProp echoStr = genTarget->GetProperty("EchoString"); + cmValue echoStr = genTarget->GetProperty("EchoString"); if (echoStr) { desc = *echoStr; } else { diff --git a/Source/cmOptionCommand.cxx b/Source/cmOptionCommand.cxx index bae67e04d..ec54fc590 100644 --- a/Source/cmOptionCommand.cxx +++ b/Source/cmOptionCommand.cxx @@ -6,11 +6,11 @@ #include "cmMakefile.h" #include "cmMessageType.h" #include "cmPolicies.h" -#include "cmProperty.h" #include "cmState.h" #include "cmStateSnapshot.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" +#include "cmValue.h" // cmOptionCommand bool cmOptionCommand(std::vector<std::string> const& args, @@ -29,12 +29,12 @@ bool cmOptionCommand(std::vector<std::string> const& args, { auto policyStatus = status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0077); - const auto* existsBeforeSet = + const auto& existsBeforeSet = status.GetMakefile().GetStateSnapshot().GetDefinition(args[0]); switch (policyStatus) { case cmPolicies::WARN: checkAndWarn = (existsBeforeSet != nullptr); - break; + CM_FALLTHROUGH; case cmPolicies::OLD: // OLD behavior does not warn. break; @@ -53,7 +53,7 @@ bool cmOptionCommand(std::vector<std::string> const& args, // See if a cache variable with this name already exists // If so just make sure the doc state is correct cmState* state = status.GetMakefile().GetState(); - cmProp existingValue = state->GetCacheEntryValue(args[0]); + cmValue existingValue = state->GetCacheEntryValue(args[0]); if (existingValue && (state->GetCacheEntryType(args[0]) != cmStateEnums::UNINITIALIZED)) { state->SetCacheEntryProperty(args[0], "HELPSTRING", args[1]); @@ -77,7 +77,7 @@ bool cmOptionCommand(std::vector<std::string> const& args, } if (checkAndWarn) { - const auto* existsAfterSet = + const auto& existsAfterSet = status.GetMakefile().GetStateSnapshot().GetDefinition(args[0]); if (!existsAfterSet) { status.GetMakefile().IssueMessage( diff --git a/Source/cmOutputConverter.cxx b/Source/cmOutputConverter.cxx index 840fdb9ec..2b785e1d3 100644 --- a/Source/cmOutputConverter.cxx +++ b/Source/cmOutputConverter.cxx @@ -12,13 +12,14 @@ #include "cmStateDirectory.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" namespace { bool PathEqOrSubDir(std::string const& a, std::string const& b) { return (cmSystemTools::ComparePath(a, b) || cmSystemTools::IsSubDirectory(a, b)); -}; +} } cmOutputConverter::cmOutputConverter(cmStateSnapshot const& snapshot) diff --git a/Source/cmOutputRequiredFilesCommand.cxx b/Source/cmOutputRequiredFilesCommand.cxx index d589614d7..ad276d2f7 100644 --- a/Source/cmOutputRequiredFilesCommand.cxx +++ b/Source/cmOutputRequiredFilesCommand.cxx @@ -15,11 +15,11 @@ #include "cmExecutionStatus.h" #include "cmGeneratorExpression.h" #include "cmMakefile.h" -#include "cmProperty.h" #include "cmSourceFile.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" +#include "cmValue.h" namespace { /** \class cmDependInformation @@ -118,7 +118,7 @@ public: std::set<std::string> uniqueIncludes; std::vector<std::string> orderedAndUniqueIncludes; for (auto const& target : this->Makefile->GetTargets()) { - cmProp incDirProp = target.second.GetProperty("INCLUDE_DIRECTORIES"); + cmValue incDirProp = target.second.GetProperty("INCLUDE_DIRECTORIES"); if (!incDirProp) { continue; } diff --git a/Source/cmParseArgumentsCommand.cxx b/Source/cmParseArgumentsCommand.cxx index 246506978..9f3fd00d3 100644 --- a/Source/cmParseArgumentsCommand.cxx +++ b/Source/cmParseArgumentsCommand.cxx @@ -13,10 +13,10 @@ #include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmMessageType.h" -#include "cmProperty.h" #include "cmRange.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" static std::string EscapeArg(const std::string& arg) { @@ -196,7 +196,7 @@ bool cmParseArgumentsCommand(std::vector<std::string> const& args, for (unsigned long i = argvStart; i < count; ++i) { std::ostringstream argName; argName << "ARGV" << i; - cmProp arg = status.GetMakefile().GetDefinition(argName.str()); + cmValue arg = status.GetMakefile().GetDefinition(argName.str()); if (!arg) { status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR, "PARSE_ARGV called with " + diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx index 01e8c047a..23000fae6 100644 --- a/Source/cmPolicies.cxx +++ b/Source/cmPolicies.cxx @@ -15,6 +15,7 @@ #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" #include "cmVersion.h" static bool stringToId(const char* input, cmPolicies::PolicyID& pid) diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index f7c0d2592..ce0411761 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -379,7 +379,13 @@ class cmMakefile; 3, 21, 0, cmPolicies::WARN) \ SELECT(POLICY, CMP0126, \ "set(CACHE) does not remove a normal variable of the same name.", 3, \ - 21, 0, cmPolicies::WARN) + 21, 0, cmPolicies::WARN) \ + SELECT(POLICY, CMP0127, \ + "cmake_dependent_option() supports full Condition Syntax.", 3, 22, \ + 0, cmPolicies::WARN) \ + SELECT(POLICY, CMP0128, \ + "Selection of language standard and extension flags improved.", 3, \ + 22, 0, cmPolicies::WARN) #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1) #define CM_FOR_EACH_POLICY_ID(POLICY) \ diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx index 6950c19ef..20fcdbed9 100644 --- a/Source/cmProjectCommand.cxx +++ b/Source/cmProjectCommand.cxx @@ -15,10 +15,10 @@ #include "cmMakefile.h" #include "cmMessageType.h" #include "cmPolicies.h" -#include "cmProperty.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" static bool IncludeByVariable(cmExecutionStatus& status, const std::string& variable); @@ -308,7 +308,7 @@ bool cmProjectCommand(std::vector<std::string> const& args, } std::string vw; for (std::string const& i : vv) { - cmProp v = mf.GetDefinition(i); + cmValue v = mf.GetDefinition(i); if (cmNonempty(v)) { if (cmp0048 == cmPolicies::WARN) { if (!injectedProjectCommand) { @@ -358,7 +358,7 @@ static bool IncludeByVariable(cmExecutionStatus& status, const std::string& variable) { cmMakefile& mf = status.GetMakefile(); - cmProp include = mf.GetDefinition(variable); + cmValue include = mf.GetDefinition(variable); if (!include) { return true; } diff --git a/Source/cmProperty.h b/Source/cmProperty.h index 1e03c3f0f..07811092e 100644 --- a/Source/cmProperty.h +++ b/Source/cmProperty.h @@ -4,8 +4,6 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include <string> - class cmProperty { public: @@ -22,15 +20,3 @@ public: INSTALL }; }; - -using cmProp = const std::string*; - -inline const char* cmToCStr(cmProp p) -{ - return p ? p->c_str() : nullptr; -} - -inline const char* cmToCStrSafe(cmProp p) -{ - return p ? p->c_str() : ""; -} diff --git a/Source/cmPropertyMap.cxx b/Source/cmPropertyMap.cxx index 06e151ab6..b15000f49 100644 --- a/Source/cmPropertyMap.cxx +++ b/Source/cmPropertyMap.cxx @@ -19,6 +19,15 @@ void cmPropertyMap::SetProperty(const std::string& name, const char* value) this->Map_[name] = value; } +void cmPropertyMap::SetProperty(const std::string& name, cmValue value) +{ + if (!value) { + this->Map_.erase(name); + return; + } + + this->Map_[name] = *value; +} void cmPropertyMap::AppendProperty(const std::string& name, const std::string& value, bool asString) @@ -42,11 +51,11 @@ void cmPropertyMap::RemoveProperty(const std::string& name) this->Map_.erase(name); } -cmProp cmPropertyMap::GetPropertyValue(const std::string& name) const +cmValue cmPropertyMap::GetPropertyValue(const std::string& name) const { auto it = this->Map_.find(name); if (it != this->Map_.end()) { - return &it->second; + return cmValue(it->second); } return nullptr; } diff --git a/Source/cmPropertyMap.h b/Source/cmPropertyMap.h index cda585a89..f50b65e21 100644 --- a/Source/cmPropertyMap.h +++ b/Source/cmPropertyMap.h @@ -9,7 +9,7 @@ #include <utility> #include <vector> -#include "cmProperty.h" +#include "cmValue.h" /** \class cmPropertyMap * \brief String property map. @@ -26,13 +26,18 @@ public: //! Set the property value void SetProperty(const std::string& name, const char* value); + void SetProperty(const std::string& name, cmValue value); + void SetProperty(const std::string& name, const std::string& value) + { + this->SetProperty(name, cmValue(value)); + } //! Append to the property value void AppendProperty(const std::string& name, const std::string& value, bool asString = false); //! Get the property value - cmProp GetPropertyValue(const std::string& name) const; + cmValue GetPropertyValue(const std::string& name) const; //! Remove the property @a name from the map void RemoveProperty(const std::string& name); diff --git a/Source/cmQTWrapCPPCommand.cxx b/Source/cmQTWrapCPPCommand.cxx index e9670f9c3..ca0b259dc 100644 --- a/Source/cmQTWrapCPPCommand.cxx +++ b/Source/cmQTWrapCPPCommand.cxx @@ -6,7 +6,6 @@ #include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmPolicies.h" -#include "cmProperty.h" #include "cmRange.h" #include "cmSourceFile.h" #include "cmStringAlgorithms.h" @@ -41,7 +40,7 @@ bool cmQTWrapCPPCommand(std::vector<std::string> const& args, cmStrCat(mf.GetCurrentBinaryDirectory(), "/moc_", srcName, ".cxx"); cmSourceFile* sf = mf.GetOrCreateSource(newName, true); if (curr) { - sf->SetProperty("ABSTRACT", cmToCStr(curr->GetProperty("ABSTRACT"))); + sf->SetProperty("ABSTRACT", curr->GetProperty("ABSTRACT")); } // Compute the name of the header from which to generate the file. diff --git a/Source/cmQtAutoGen.cxx b/Source/cmQtAutoGen.cxx index 57fcd2da7..9584e5c41 100644 --- a/Source/cmQtAutoGen.cxx +++ b/Source/cmQtAutoGen.cxx @@ -24,7 +24,8 @@ /// @arg valueOpts list of options that accept a value void MergeOptions(std::vector<std::string>& baseOpts, std::vector<std::string> const& newOpts, - std::initializer_list<cm::string_view> valueOpts, bool isQt5) + std::initializer_list<cm::string_view> valueOpts, + bool isQt5OrLater) { if (newOpts.empty()) { return; @@ -47,7 +48,7 @@ void MergeOptions(std::vector<std::string>& baseOpts, auto oit = newOpt.begin(); if (*oit == '-') { ++oit; - if (isQt5 && (*oit == '-')) { + if (isQt5OrLater && (*oit == '-')) { ++oit; } optName.assign(oit, newOpt.end()); @@ -204,24 +205,24 @@ std::string cmQtAutoGen::AppendFilenameSuffix(cm::string_view filename, void cmQtAutoGen::UicMergeOptions(std::vector<std::string>& baseOpts, std::vector<std::string> const& newOpts, - bool isQt5) + bool isQt5OrLater) { static std::initializer_list<cm::string_view> const valueOpts = { "tr", "translate", "postfix", "generator", "include", // Since Qt 5.3 "g" }; - MergeOptions(baseOpts, newOpts, valueOpts, isQt5); + MergeOptions(baseOpts, newOpts, valueOpts, isQt5OrLater); } void cmQtAutoGen::RccMergeOptions(std::vector<std::string>& baseOpts, std::vector<std::string> const& newOpts, - bool isQt5) + bool isQt5OrLater) { static std::initializer_list<cm::string_view> const valueOpts = { "name", "root", "compress", "threshold" }; - MergeOptions(baseOpts, newOpts, valueOpts, isQt5); + MergeOptions(baseOpts, newOpts, valueOpts, isQt5OrLater); } static void RccListParseContent(std::string const& content, diff --git a/Source/cmQtAutoGen.h b/Source/cmQtAutoGen.h index 466a954a9..5a23ae924 100644 --- a/Source/cmQtAutoGen.h +++ b/Source/cmQtAutoGen.h @@ -93,12 +93,12 @@ public: /// @brief Merges newOpts into baseOpts static void UicMergeOptions(std::vector<std::string>& baseOpts, std::vector<std::string> const& newOpts, - bool isQt5); + bool isQt5OrLater); /// @brief Merges newOpts into baseOpts static void RccMergeOptions(std::vector<std::string>& baseOpts, std::vector<std::string> const& newOpts, - bool isQt5); + bool isQt5OrLater); /** @class RccLister * @brief Lists files in qrc resource files diff --git a/Source/cmQtAutoGenGlobalInitializer.cxx b/Source/cmQtAutoGenGlobalInitializer.cxx index 77fe87e4c..f9e889a66 100644 --- a/Source/cmQtAutoGenGlobalInitializer.cxx +++ b/Source/cmQtAutoGenGlobalInitializer.cxx @@ -15,7 +15,6 @@ #include "cmMessageType.h" #include "cmPolicies.h" #include "cmProcessOutput.h" -#include "cmProperty.h" #include "cmQtAutoGen.h" #include "cmQtAutoGenInitializer.h" #include "cmState.h" @@ -23,6 +22,7 @@ #include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" +#include "cmValue.h" cmQtAutoGenGlobalInitializer::Keywords::Keywords() : AUTOMOC("AUTOMOC") @@ -183,10 +183,10 @@ void cmQtAutoGenGlobalInitializer::GetOrCreateGlobalTarget( // Set FOLDER property in the target { - cmProp folder = + cmValue folder = makefile->GetState()->GetGlobalProperty("AUTOGEN_TARGETS_FOLDER"); if (folder) { - target->SetProperty("FOLDER", *folder); + target->SetProperty("FOLDER", folder); } } } diff --git a/Source/cmQtAutoGenGlobalInitializer.h b/Source/cmQtAutoGenGlobalInitializer.h index afcb4a2a9..3de5c1a85 100644 --- a/Source/cmQtAutoGenGlobalInitializer.h +++ b/Source/cmQtAutoGenGlobalInitializer.h @@ -49,7 +49,7 @@ public: std::vector<std::unique_ptr<cmLocalGenerator>> const& localGenerators); ~cmQtAutoGenGlobalInitializer(); - Keywords const& kw() const { return this->Keywords_; }; + Keywords const& kw() const { return this->Keywords_; } bool generate(); diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx index 4e3c58421..c49cafee5 100644 --- a/Source/cmQtAutoGenInitializer.cxx +++ b/Source/cmQtAutoGenInitializer.cxx @@ -24,6 +24,7 @@ #include "cmsys/SystemInformation.hxx" +#include "cmAlgorithms.h" #include "cmCustomCommand.h" #include "cmCustomCommandLines.h" #include "cmGeneratedFileStream.h" @@ -36,7 +37,6 @@ #include "cmMakefile.h" #include "cmMessageType.h" #include "cmPolicies.h" -#include "cmProperty.h" #include "cmQtAutoGen.h" #include "cmQtAutoGenGlobalInitializer.h" #include "cmSourceFile.h" @@ -47,6 +47,7 @@ #include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" +#include "cmValue.h" #include "cmake.h" namespace { @@ -355,7 +356,7 @@ bool cmQtAutoGenInitializer::InitCustomTargets() // Targets FOLDER { - cmProp folder = + cmValue folder = this->Makefile->GetState()->GetGlobalProperty("AUTOMOC_TARGETS_FOLDER"); if (!folder) { folder = this->Makefile->GetState()->GetGlobalProperty( @@ -522,6 +523,8 @@ bool cmQtAutoGenInitializer::InitCustomTargets() // Filters cmExpandList(this->GenTarget->GetSafeProperty("AUTOMOC_MACRO_NAMES"), this->Moc.MacroNames); + this->Moc.MacroNames.erase(cmRemoveDuplicates(this->Moc.MacroNames), + this->Moc.MacroNames.end()); { auto filterList = cmExpandedList( this->GenTarget->GetSafeProperty("AUTOMOC_DEPEND_FILTERS")); @@ -1796,7 +1799,7 @@ void cmQtAutoGenInitializer::AddToSourceGroup(std::string const& fileName, cmStrCat(genNameUpper, "_SOURCE_GROUP"), "AUTOGEN_SOURCE_GROUP" }; for (std::string const& prop : props) { - cmProp propName = this->Makefile->GetState()->GetGlobalProperty(prop); + cmValue propName = this->Makefile->GetState()->GetGlobalProperty(prop); if (cmNonempty(propName)) { groupName = *propName; property = prop; @@ -1926,7 +1929,7 @@ cmQtAutoGenInitializer::GetQtVersion(cmGeneratorTarget const* target, } return 0u; }; - auto toUInt2 = [](cmProp input) -> unsigned int { + auto toUInt2 = [](cmValue input) -> unsigned int { unsigned long tmp = 0; if (input && cmStrToULong(*input, &tmp)) { return static_cast<unsigned int>(tmp); @@ -1954,8 +1957,8 @@ cmQtAutoGenInitializer::GetQtVersion(cmGeneratorTarget const* target, knownQtVersions.reserve(keys.size() * 2); // Adds a version to the result (nullptr safe) - auto addVersion = [&knownQtVersions, &toUInt2](cmProp major, - cmProp minor) { + auto addVersion = [&knownQtVersions, &toUInt2](cmValue major, + cmValue minor) { cmQtAutoGen::IntegerVersion ver(toUInt2(major), toUInt2(minor)); if (ver.Major != 0) { knownQtVersions.emplace_back(ver); diff --git a/Source/cmQtAutoGenInitializer.h b/Source/cmQtAutoGenInitializer.h index e76817b9c..603c53777 100644 --- a/Source/cmQtAutoGenInitializer.h +++ b/Source/cmQtAutoGenInitializer.h @@ -95,7 +95,9 @@ public: GenVarsT(GenT gen) : Gen(gen) - , GenNameUpper(cmQtAutoGen::GeneratorNameUpper(gen)){}; + , GenNameUpper(cmQtAutoGen::GeneratorNameUpper(gen)) + { + } }; /** @param mocExecutable The file path to the moc executable. Will be used as @@ -209,7 +211,9 @@ private: struct MocT : public GenVarsT { MocT() - : GenVarsT(GenT::MOC){}; + : GenVarsT(GenT::MOC) + { + } bool RelaxedMode = false; bool PathPrefix = false; @@ -237,7 +241,9 @@ private: using UiFileT = std::pair<std::string, std::vector<std::string>>; UicT() - : GenVarsT(GenT::UIC){}; + : GenVarsT(GenT::UIC) + { + } std::set<std::string> SkipUi; std::vector<std::string> UiFilesNoOptions; @@ -252,7 +258,9 @@ private: struct RccT : public GenVarsT { RccT() - : GenVarsT(GenT::RCC){}; + : GenVarsT(GenT::RCC) + { + } bool GlobalTarget = false; std::vector<Qrc> Qrcs; diff --git a/Source/cmQtAutoGenerator.cxx b/Source/cmQtAutoGenerator.cxx index 568926e3c..e5c7bda66 100644 --- a/Source/cmQtAutoGenerator.cxx +++ b/Source/cmQtAutoGenerator.cxx @@ -9,6 +9,7 @@ #include "cmQtAutoGen.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" cmQtAutoGenerator::Logger::Logger() { diff --git a/Source/cmQtAutoMocUic.cxx b/Source/cmQtAutoMocUic.cxx index 2753fd57c..4ed728ea9 100644 --- a/Source/cmQtAutoMocUic.cxx +++ b/Source/cmQtAutoMocUic.cxx @@ -310,7 +310,7 @@ public: cmQtAutoMocUicT* Gen() const { return static_cast<cmQtAutoMocUicT*>(this->UserData()); - }; + } // -- Accessors. Only valid during Process() call! Logger const& Log() const { return this->Gen()->Log(); } @@ -346,7 +346,7 @@ public: : JobT(true) { } - void Process() override{}; + void Process() override {} }; /** Generate moc_predefs.h. */ @@ -2083,7 +2083,7 @@ void cmQtAutoMocUicT::JobCompileUicT::Process() auto optionIt = this->UicConst().UiFiles.find(sourceFile); if (optionIt != this->UicConst().UiFiles.end()) { UicMergeOptions(allOpts, optionIt->second.Options, - (this->BaseConst().QtVersion.Major == 5)); + (this->BaseConst().QtVersion.Major >= 5)); } cm::append(cmd, allOpts); } diff --git a/Source/cmRST.cxx b/Source/cmRST.cxx index fce6e80bf..1e4dedde3 100644 --- a/Source/cmRST.cxx +++ b/Source/cmRST.cxx @@ -35,6 +35,7 @@ cmRST::cmRST(std::ostream& os, std::string docroot) , TocTreeDirective("^.. toctree::[ \t]*(.*)$") , ProductionListDirective("^.. productionlist::[ \t]*(.*)$") , NoteDirective("^.. note::[ \t]*(.*)$") + , VersionDirective("^.. version(added|changed)::[ \t]*(.*)$") , ModuleRST(R"(^#\[(=*)\[\.rst:$)") , CMakeRole("(:cmake)?:(" "command|cpack_gen|generator|genex|" @@ -209,6 +210,10 @@ void cmRST::ProcessLine(std::string const& line) } else if (this->NoteDirective.find(line)) { // Output note directives and their content normally. this->NormalLine(line); + } else if (this->VersionDirective.find(line)) { + // Output versionadded and versionchanged directives and their content + // normally. + this->NormalLine(line); } } // An explicit markup start followed nothing but whitespace and a diff --git a/Source/cmRST.h b/Source/cmRST.h index 17cdfe896..156b20a1b 100644 --- a/Source/cmRST.h +++ b/Source/cmRST.h @@ -83,6 +83,7 @@ private: cmsys::RegularExpression TocTreeDirective; cmsys::RegularExpression ProductionListDirective; cmsys::RegularExpression NoteDirective; + cmsys::RegularExpression VersionDirective; cmsys::RegularExpression ModuleRST; cmsys::RegularExpression CMakeRole; cmsys::RegularExpression InlineLink; diff --git a/Source/cmRemoveCommand.cxx b/Source/cmRemoveCommand.cxx index 13455886b..8af13ae2b 100644 --- a/Source/cmRemoveCommand.cxx +++ b/Source/cmRemoveCommand.cxx @@ -4,8 +4,8 @@ #include "cmExecutionStatus.h" #include "cmMakefile.h" -#include "cmProperty.h" #include "cmStringAlgorithms.h" +#include "cmValue.h" // cmRemoveCommand bool cmRemoveCommand(std::vector<std::string> const& args, @@ -17,7 +17,7 @@ bool cmRemoveCommand(std::vector<std::string> const& args, std::string const& variable = args[0]; // VAR is always first // get the old value - cmProp cacheValue = status.GetMakefile().GetDefinition(variable); + cmValue cacheValue = status.GetMakefile().GetDefinition(variable); // if there is no old value then return if (!cacheValue) { diff --git a/Source/cmRuntimeDependencyArchive.cxx b/Source/cmRuntimeDependencyArchive.cxx index 4dfdfae4f..26f255da0 100644 --- a/Source/cmRuntimeDependencyArchive.cxx +++ b/Source/cmRuntimeDependencyArchive.cxx @@ -236,7 +236,6 @@ bool cmRuntimeDependencyArchive::GetGetRuntimeDependenciesCommand( cmGlobalGenerator* gg = this->GetMakefile()->GetGlobalGenerator(); // Add newer Visual Studio paths - AddVisualStudioPath(paths, "Visual Studio 17 ", 17, gg); AddVisualStudioPath(paths, "Visual Studio 16 ", 16, gg); AddVisualStudioPath(paths, "Visual Studio 15 ", 15, gg); diff --git a/Source/cmSearchPath.cxx b/Source/cmSearchPath.cxx index a58be621c..1bb459c4b 100644 --- a/Source/cmSearchPath.cxx +++ b/Source/cmSearchPath.cxx @@ -8,9 +8,9 @@ #include "cmFindCommon.h" #include "cmMakefile.h" -#include "cmProperty.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" cmSearchPath::cmSearchPath(cmFindCommon* findCmd) : FC(findCmd) @@ -78,7 +78,7 @@ void cmSearchPath::AddCMakePath(const std::string& variable) assert(this->FC != nullptr); // Get a path from a CMake variable. - if (cmProp value = this->FC->Makefile->GetDefinition(variable)) { + if (cmValue value = this->FC->Makefile->GetDefinition(variable)) { std::vector<std::string> expanded = cmExpandedList(*value); for (std::string const& p : expanded) { @@ -102,7 +102,7 @@ void cmSearchPath::AddCMakePrefixPath(const std::string& variable) assert(this->FC != nullptr); // Get a path from a CMake variable. - if (cmProp value = this->FC->Makefile->GetDefinition(variable)) { + if (cmValue value = this->FC->Makefile->GetDefinition(variable)) { std::vector<std::string> expanded = cmExpandedList(*value); this->AddPrefixPaths( @@ -179,7 +179,7 @@ void cmSearchPath::AddPrefixPaths(const std::vector<std::string>& paths, dir += "/"; } if (subdir == "include" || subdir == "lib") { - cmProp arch = + cmValue arch = this->FC->Makefile->GetDefinition("CMAKE_LIBRARY_ARCHITECTURE"); if (cmNonempty(arch)) { if (this->FC->Makefile->IsDefinitionSet("CMAKE_SYSROOT") && diff --git a/Source/cmSeparateArgumentsCommand.cxx b/Source/cmSeparateArgumentsCommand.cxx index 52b1a4431..17285e723 100644 --- a/Source/cmSeparateArgumentsCommand.cxx +++ b/Source/cmSeparateArgumentsCommand.cxx @@ -4,15 +4,16 @@ #include <algorithm> +#include <cm/string_view> #include <cmext/string_view> #include "cmArgumentParser.h" #include "cmExecutionStatus.h" #include "cmMakefile.h" -#include "cmProperty.h" #include "cmRange.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" // cmSeparateArgumentsCommand bool cmSeparateArgumentsCommand(std::vector<std::string> const& args, @@ -27,7 +28,7 @@ bool cmSeparateArgumentsCommand(std::vector<std::string> const& args, if (args.size() == 1) { // Original space-replacement version of command. - if (cmProp def = status.GetMakefile().GetDefinition(var)) { + if (cmValue def = status.GetMakefile().GetDefinition(var)) { std::string value = *def; std::replace(value.begin(), value.end(), ' ', ';'); status.GetMakefile().AddDefinition(var, value); @@ -81,7 +82,7 @@ bool cmSeparateArgumentsCommand(std::vector<std::string> const& args, } if (unparsedArguments.empty()) { - status.GetMakefile().AddDefinition(var, {}); + status.GetMakefile().AddDefinition(var, cm::string_view{}); return true; } diff --git a/Source/cmSetCommand.cxx b/Source/cmSetCommand.cxx index 354b4c327..ce0cb258c 100644 --- a/Source/cmSetCommand.cxx +++ b/Source/cmSetCommand.cxx @@ -5,12 +5,12 @@ #include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmMessageType.h" -#include "cmProperty.h" #include "cmRange.h" #include "cmState.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" // cmSetCommand bool cmSetCommand(std::vector<std::string> const& args, @@ -136,7 +136,7 @@ bool cmSetCommand(std::vector<std::string> const& args, // see if this is already in the cache cmState* state = status.GetMakefile().GetState(); - cmProp existingValue = state->GetCacheEntryValue(variable); + cmValue existingValue = state->GetCacheEntryValue(variable); if (existingValue && (state->GetCacheEntryType(variable) != cmStateEnums::UNINITIALIZED)) { // if the set is trying to CACHE the value but the value diff --git a/Source/cmSetDirectoryPropertiesCommand.cxx b/Source/cmSetDirectoryPropertiesCommand.cxx index 07ad24602..9adf5373b 100644 --- a/Source/cmSetDirectoryPropertiesCommand.cxx +++ b/Source/cmSetDirectoryPropertiesCommand.cxx @@ -32,7 +32,7 @@ bool cmSetDirectoryPropertiesCommand(std::vector<std::string> const& args, "Commands and macros cannot be set using SET_CMAKE_PROPERTIES"); return false; } - status.GetMakefile().SetProperty(prop, (iter + 1)->c_str()); + status.GetMakefile().SetProperty(prop, *(iter + 1)); } return true; diff --git a/Source/cmSetPropertyCommand.cxx b/Source/cmSetPropertyCommand.cxx index c8990537b..db10cd47a 100644 --- a/Source/cmSetPropertyCommand.cxx +++ b/Source/cmSetPropertyCommand.cxx @@ -21,6 +21,7 @@ #include "cmSystemTools.h" #include "cmTarget.h" #include "cmTest.h" +#include "cmValue.h" #include "cmake.h" namespace { @@ -116,7 +117,7 @@ bool HandleSourceFileDirectoryScopes( "given non-existent target for TARGET_DIRECTORY ", target_name)); return false; } - cmProp target_source_dir = target->GetProperty("BINARY_DIR"); + cmValue target_source_dir = target->GetProperty("BINARY_DIR"); cmMakefile* target_dir_mf = status.GetMakefile().GetGlobalGenerator()->FindMakefile( *target_source_dir); @@ -294,7 +295,7 @@ bool HandleAndValidateSourceFilePropertyGENERATED( sf->SetProperty("GENERATED", nullptr); break; case PropertyOp::Set: - sf->SetProperty("GENERATED", propertyValue.c_str()); + sf->SetProperty("GENERATED", propertyValue); break; } } else { @@ -474,7 +475,7 @@ bool HandleGlobalMode(cmExecutionStatus& status, if (remove) { cm->SetProperty(propertyName, nullptr); } else { - cm->SetProperty(propertyName, propertyValue.c_str()); + cm->SetProperty(propertyName, propertyValue); } } @@ -520,7 +521,7 @@ bool HandleDirectoryMode(cmExecutionStatus& status, if (remove) { mf->SetProperty(propertyName, nullptr); } else { - mf->SetProperty(propertyName, propertyValue.c_str()); + mf->SetProperty(propertyName, propertyValue); } } @@ -631,7 +632,7 @@ bool HandleSource(cmSourceFile* sf, const std::string& propertyName, if (remove) { sf->SetProperty(propertyName, nullptr); } else { - sf->SetProperty(propertyName, propertyValue.c_str()); + sf->SetProperty(propertyName, propertyValue); } } return true; @@ -681,7 +682,7 @@ bool HandleTest(cmTest* test, const std::string& propertyName, if (remove) { test->SetProperty(propertyName, nullptr); } else { - test->SetProperty(propertyName, propertyValue.c_str()); + test->SetProperty(propertyName, propertyValue); } } @@ -719,7 +720,7 @@ bool HandleCacheMode(cmExecutionStatus& status, for (std::string const& name : names) { // Get the source file. cmake* cm = status.GetMakefile().GetCMakeInstance(); - cmProp existingValue = cm->GetState()->GetCacheEntryValue(name); + cmValue existingValue = cm->GetState()->GetCacheEntryValue(name); if (existingValue) { if (!HandleCacheEntry(name, status.GetMakefile(), propertyName, propertyValue, appendAsString, appendMode, diff --git a/Source/cmSetSourceFilesPropertiesCommand.cxx b/Source/cmSetSourceFilesPropertiesCommand.cxx index 237b67fed..ab93ddb54 100644 --- a/Source/cmSetSourceFilesPropertiesCommand.cxx +++ b/Source/cmSetSourceFilesPropertiesCommand.cxx @@ -173,7 +173,7 @@ static bool RunCommandForScope( SetPropertyCommand::HandleAndValidateSourceFilePropertyGENERATED( sf, *(k + 1)); } else { - sf->SetProperty(*k, (k + 1)->c_str()); + sf->SetProperty(*k, *(k + 1)); } } } diff --git a/Source/cmSetTestsPropertiesCommand.cxx b/Source/cmSetTestsPropertiesCommand.cxx index c4bff76f6..a17c96451 100644 --- a/Source/cmSetTestsPropertiesCommand.cxx +++ b/Source/cmSetTestsPropertiesCommand.cxx @@ -37,7 +37,7 @@ bool cmSetTestsPropertiesCommand(std::vector<std::string> const& args, // loop through all the props and set them for (auto k = propsIter + 1; k != args.end(); k += 2) { if (!k->empty()) { - test->SetProperty(*k, (k + 1)->c_str()); + test->SetProperty(*k, *(k + 1)); } } } else { diff --git a/Source/cmSiteNameCommand.cxx b/Source/cmSiteNameCommand.cxx index 58af8f0b0..61d1c3002 100644 --- a/Source/cmSiteNameCommand.cxx +++ b/Source/cmSiteNameCommand.cxx @@ -6,10 +6,9 @@ #include "cmExecutionStatus.h" #include "cmMakefile.h" -#include "cmProperty.h" #include "cmStateTypes.h" -#include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" // cmSiteNameCommand bool cmSiteNameCommand(std::vector<std::string> const& args, @@ -27,12 +26,12 @@ bool cmSiteNameCommand(std::vector<std::string> const& args, paths.emplace_back("/sbin"); paths.emplace_back("/usr/local/bin"); - cmProp cacheValue = status.GetMakefile().GetDefinition(args[0]); + cmValue cacheValue = status.GetMakefile().GetDefinition(args[0]); if (cacheValue) { return true; } - cmProp temp = status.GetMakefile().GetDefinition("HOSTNAME"); + cmValue temp = status.GetMakefile().GetDefinition("HOSTNAME"); std::string hostname_cmd; if (temp) { hostname_cmd = *temp; diff --git a/Source/cmSourceFile.cxx b/Source/cmSourceFile.cxx index 3f3c8d501..3fa0051e2 100644 --- a/Source/cmSourceFile.cxx +++ b/Source/cmSourceFile.cxx @@ -13,6 +13,7 @@ #include "cmState.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" #include "cmake.h" cmSourceFile::cmSourceFile(cmMakefile* mf, const std::string& name, @@ -53,7 +54,7 @@ std::string cmSourceFile::GetObjectLibrary() const std::string const& cmSourceFile::GetOrDetermineLanguage() { // If the language was set explicitly by the user then use it. - if (cmProp lang = this->GetProperty(propLANGUAGE)) { + if (cmValue lang = this->GetProperty(propLANGUAGE)) { // Assign to member in order to return a reference. this->Language = *lang; return this->Language; @@ -84,7 +85,7 @@ std::string const& cmSourceFile::GetOrDetermineLanguage() std::string cmSourceFile::GetLanguage() const { // If the language was set explicitly by the user then use it. - if (cmProp lang = this->GetProperty(propLANGUAGE)) { + if (cmValue lang = this->GetProperty(propLANGUAGE)) { return *lang; } @@ -269,7 +270,8 @@ bool cmSourceFile::Matches(cmSourceFileLocation const& loc) return this->Location.Matches(loc); } -void cmSourceFile::SetProperty(const std::string& prop, const char* value) +template <typename ValueType> +void cmSourceFile::StoreProperty(const std::string& prop, ValueType value) { if (prop == propINCLUDE_DIRECTORIES) { this->IncludeDirectories.clear(); @@ -294,6 +296,15 @@ void cmSourceFile::SetProperty(const std::string& prop, const char* value) } } +void cmSourceFile::SetProperty(const std::string& prop, const char* value) +{ + this->StoreProperty(prop, value); +} +void cmSourceFile::SetProperty(const std::string& prop, cmValue value) +{ + this->StoreProperty(prop, value); +} + void cmSourceFile::AppendProperty(const std::string& prop, const std::string& value, bool asString) { @@ -317,7 +328,7 @@ void cmSourceFile::AppendProperty(const std::string& prop, } } -cmProp cmSourceFile::GetPropertyForUser(const std::string& prop) +cmValue cmSourceFile::GetPropertyForUser(const std::string& prop) { // This method is a consequence of design history and backwards // compatibility. GetProperty is (and should be) a const method. @@ -342,7 +353,7 @@ cmProp cmSourceFile::GetPropertyForUser(const std::string& prop) // if it is requested by the user. if (prop == propLANGUAGE) { // The pointer is valid until `this->Language` is modified. - return &this->GetOrDetermineLanguage(); + return cmValue(this->GetOrDetermineLanguage()); } // Special handling for GENERATED property. @@ -355,23 +366,23 @@ cmProp cmSourceFile::GetPropertyForUser(const std::string& prop) (policyStatus == cmPolicies::WARN || policyStatus == cmPolicies::OLD) ? CheckScope::GlobalAndLocal : CheckScope::Global)) { - return &propTRUE; + return cmValue(propTRUE); } - return &propFALSE; + return cmValue(propFALSE); } // Perform the normal property lookup. return this->GetProperty(prop); } -cmProp cmSourceFile::GetProperty(const std::string& prop) const +cmValue cmSourceFile::GetProperty(const std::string& prop) const { // Check for computed properties. if (prop == propLOCATION) { if (this->FullPath.empty()) { return nullptr; } - return &this->FullPath; + return cmValue(this->FullPath); } // Check for the properties with backtraces. @@ -382,7 +393,7 @@ cmProp cmSourceFile::GetProperty(const std::string& prop) const static std::string output; output = cmJoin(this->IncludeDirectories, ";"); - return &output; + return cmValue(output); } if (prop == propCOMPILE_OPTIONS) { @@ -392,7 +403,7 @@ cmProp cmSourceFile::GetProperty(const std::string& prop) const static std::string output; output = cmJoin(this->CompileOptions, ";"); - return &output; + return cmValue(output); } if (prop == propCOMPILE_DEFINITIONS) { @@ -402,10 +413,10 @@ cmProp cmSourceFile::GetProperty(const std::string& prop) const static std::string output; output = cmJoin(this->CompileDefinitions, ";"); - return &output; + return cmValue(output); } - cmProp retVal = this->Properties.GetPropertyValue(prop); + cmValue retVal = this->Properties.GetPropertyValue(prop); if (!retVal) { cmMakefile const* mf = this->Location.GetMakefile(); const bool chain = @@ -421,7 +432,7 @@ cmProp cmSourceFile::GetProperty(const std::string& prop) const const std::string& cmSourceFile::GetSafeProperty(const std::string& prop) const { - cmProp ret = this->GetProperty(prop); + cmValue ret = this->GetProperty(prop); if (ret) { return *ret; } diff --git a/Source/cmSourceFile.h b/Source/cmSourceFile.h index 32ed68715..c1c52010c 100644 --- a/Source/cmSourceFile.h +++ b/Source/cmSourceFile.h @@ -10,10 +10,10 @@ #include "cmCustomCommand.h" #include "cmListFileCache.h" -#include "cmProperty.h" #include "cmPropertyMap.h" #include "cmSourceFileLocation.h" #include "cmSourceFileLocationKind.h" +#include "cmValue.h" class cmMakefile; @@ -42,17 +42,22 @@ public: //! Set/Get a property of this source file void SetProperty(const std::string& prop, const char* value); + void SetProperty(const std::string& prop, cmValue value); + void SetProperty(const std::string& prop, const std::string& value) + { + this->SetProperty(prop, cmValue(value)); + } void AppendProperty(const std::string& prop, const std::string& value, bool asString = false); //! Might return a nullptr if the property is not set or invalid - cmProp GetProperty(const std::string& prop) const; + cmValue GetProperty(const std::string& prop) const; //! Always returns a valid pointer const std::string& GetSafeProperty(const std::string& prop) const; bool GetPropertyAsBool(const std::string& prop) const; /** Implement getting a property when called from a CMake language command like get_property or get_source_file_property. */ - cmProp GetPropertyForUser(const std::string& prop); + cmValue GetPropertyForUser(const std::string& prop); /// Marks this file as generated /** @@ -145,6 +150,9 @@ public: std::string GetObjectLibrary() const; private: + template <typename ValueType> + void StoreProperty(const std::string& prop, ValueType value); + cmSourceFileLocation Location; cmPropertyMap Properties; std::unique_ptr<cmCustomCommand> CustomCommand; diff --git a/Source/cmStandardLevelResolver.cxx b/Source/cmStandardLevelResolver.cxx index 37ed4c130..61416e063 100644 --- a/Source/cmStandardLevelResolver.cxx +++ b/Source/cmStandardLevelResolver.cxx @@ -20,9 +20,10 @@ #include "cmGlobalGenerator.h" #include "cmMakefile.h" #include "cmMessageType.h" -#include "cmProperty.h" +#include "cmPolicies.h" #include "cmStringAlgorithms.h" #include "cmTarget.h" +#include "cmValue.h" #include "cmake.h" namespace { @@ -57,10 +58,10 @@ int ParseStd(std::string const& level) return -1; } -struct StanardLevelComputer +struct StandardLevelComputer { - explicit StanardLevelComputer(std::string lang, std::vector<int> levels, - std::vector<std::string> levelsStr) + explicit StandardLevelComputer(std::string lang, std::vector<int> levels, + std::vector<std::string> levelsStr) : Language(std::move(lang)) , Levels(std::move(levels)) , LevelsAsStrings(std::move(levelsStr)) @@ -76,37 +77,74 @@ struct StanardLevelComputer const auto& stds = this->Levels; const auto& stdsStrings = this->LevelsAsStrings; - cmProp defaultStd = makefile->GetDefinition( + cmValue defaultStd = makefile->GetDefinition( cmStrCat("CMAKE_", this->Language, "_STANDARD_DEFAULT")); if (!cmNonempty(defaultStd)) { // this compiler has no notion of language standard levels return std::string{}; } + cmPolicies::PolicyStatus const cmp0128{ makefile->GetPolicyStatus( + cmPolicies::CMP0128) }; + bool const defaultExt{ cmIsOn(*makefile->GetDefinition( + cmStrCat("CMAKE_", this->Language, "_EXTENSIONS_DEFAULT"))) }; bool ext = true; - if (cmProp extPropValue = target->GetLanguageExtensions(this->Language)) { - if (cmIsOff(*extPropValue)) { - ext = false; - } + + if (cmp0128 == cmPolicies::NEW) { + ext = defaultExt; } - cmProp standardProp = target->GetLanguageStandard(this->Language, config); + if (cmValue extPropValue = target->GetLanguageExtensions(this->Language)) { + ext = cmIsOn(*extPropValue); + } + + std::string const type{ ext ? "EXTENSION" : "STANDARD" }; + + cmValue standardProp = target->GetLanguageStandard(this->Language, config); if (!standardProp) { - if (ext) { - // No language standard is specified and extensions are not disabled. - // Check if this compiler needs a flag to enable extensions. - return cmStrCat("CMAKE_", this->Language, "_EXTENSION_COMPILE_OPTION"); + if (cmp0128 == cmPolicies::NEW) { + // Add extension flag if compiler's default doesn't match. + if (ext != defaultExt) { + return cmStrCat("CMAKE_", this->Language, *defaultStd, "_", type, + "_COMPILE_OPTION"); + } + } else { + if (cmp0128 == cmPolicies::WARN && + makefile->PolicyOptionalWarningEnabled( + "CMAKE_POLICY_WARNING_CMP0128") && + ext != defaultExt) { + const char* state{}; + if (ext) { + if (!makefile->GetDefinition(cmStrCat( + "CMAKE_", this->Language, "_EXTENSION_COMPILE_OPTION"))) { + state = "enabled"; + } + } else { + state = "disabled"; + } + if (state) { + makefile->IssueMessage( + MessageType::AUTHOR_WARNING, + cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0128), + "\nFor compatibility with older versions of CMake, " + "compiler extensions won't be ", + state, ".")); + } + } + + if (ext) { + return cmStrCat("CMAKE_", this->Language, + "_EXTENSION_COMPILE_OPTION"); + } } return std::string{}; } - std::string const type = ext ? "EXTENSION" : "STANDARD"; - if (target->GetLanguageStandardRequired(this->Language)) { std::string option_flag = cmStrCat( "CMAKE_", this->Language, *standardProp, "_", type, "_COMPILE_OPTION"); - cmProp opt = target->Target->GetMakefile()->GetDefinition(option_flag); + cmValue opt = target->Target->GetMakefile()->GetDefinition(option_flag); if (!opt) { std::ostringstream e; e << "Target \"" << target->GetName() @@ -121,6 +159,25 @@ struct StanardLevelComputer return option_flag; } + // If the request matches the compiler's defaults we don't need to add + // anything. + if (*standardProp == *defaultStd && ext == defaultExt) { + if (cmp0128 == cmPolicies::NEW) { + return std::string{}; + } + + if (cmp0128 == cmPolicies::WARN && + makefile->PolicyOptionalWarningEnabled( + "CMAKE_POLICY_WARNING_CMP0128")) { + makefile->IssueMessage( + MessageType::AUTHOR_WARNING, + cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0128), + "\nFor compatibility with older versions of CMake, " + "unnecessary flags for language standard or compiler " + "extensions may be added.")); + } + } + std::string standardStr(*standardProp); if (this->Language == "CUDA" && standardStr == "98") { standardStr = "03"; @@ -147,17 +204,18 @@ struct StanardLevelComputer return std::string{}; } - // If the standard requested is older than the compiler's default - // then we need to use a flag to change it. - if (stdIt <= defaultStdIt) { + // If the standard requested is older than the compiler's default or the + // extension mode doesn't match then we need to use a flag. + if (stdIt < defaultStdIt || + (cmp0128 == cmPolicies::NEW && ext != defaultExt)) { auto offset = std::distance(cm::cbegin(stds), stdIt); return cmStrCat("CMAKE_", this->Language, stdsStrings[offset], "_", type, "_COMPILE_OPTION"); } - // The standard requested is at least as new as the compiler's default, - // and the standard request is not required. Decay to the newest standard - // for which a flag is defined. + // The compiler's default is at least as new as the requested standard, + // and the requested standard is not required. Decay to the newest + // standard for which a flag is defined. for (; defaultStdIt < stdIt; --stdIt) { auto offset = std::distance(cm::cbegin(stds), stdIt); std::string option_flag = @@ -174,7 +232,7 @@ struct StanardLevelComputer bool GetNewRequiredStandard(cmMakefile* makefile, std::string const& targetName, const std::string& feature, - cmProp currentLangStandardValue, + cmValue currentLangStandardValue, std::string& newRequiredStandard, std::string* error) const { @@ -186,9 +244,9 @@ struct StanardLevelComputer auto needed = this->HighestStandardNeeded(makefile, feature); - cmProp existingStandard = currentLangStandardValue; + cmValue existingStandard = currentLangStandardValue; if (!existingStandard) { - cmProp defaultStandard = makefile->GetDefinition( + cmValue defaultStandard = makefile->GetDefinition( cmStrCat("CMAKE_", this->Language, "_STANDARD_DEFAULT")); if (cmNonempty(defaultStandard)) { existingStandard = defaultStandard; @@ -231,7 +289,7 @@ struct StanardLevelComputer std::string const& config, std::string const& feature) const { - cmProp defaultStandard = makefile->GetDefinition( + cmValue defaultStandard = makefile->GetDefinition( cmStrCat("CMAKE_", this->Language, "_STANDARD_DEFAULT")); if (!defaultStandard) { makefile->IssueMessage( @@ -253,7 +311,7 @@ struct StanardLevelComputer return false; } - cmProp existingStandard = + cmValue existingStandard = target->GetLanguageStandard(this->Language, config); if (!existingStandard) { existingStandard = defaultStandard; @@ -283,7 +341,7 @@ struct StanardLevelComputer std::string prefix = cmStrCat("CMAKE_", this->Language); StandardNeeded maxLevel = { -1, -1 }; for (size_t i = 0; i < this->Levels.size(); ++i) { - if (cmProp prop = makefile->GetDefinition( + if (cmValue prop = makefile->GetDefinition( cmStrCat(prefix, this->LevelsAsStrings[i], "_COMPILE_FEATURES"))) { std::vector<std::string> props = cmExpandedList(*prop); if (cm::contains(props, feature)) { @@ -308,31 +366,33 @@ struct StanardLevelComputer std::vector<std::string> LevelsAsStrings; }; -std::unordered_map<std::string, StanardLevelComputer> StandardComputerMapping = - { { "C", - StanardLevelComputer{ +std::unordered_map<std::string, StandardLevelComputer> + StandardComputerMapping = { + { "C", + StandardLevelComputer{ "C", std::vector<int>{ 90, 99, 11, 17, 23 }, std::vector<std::string>{ "90", "99", "11", "17", "23" } } }, { "CXX", - StanardLevelComputer{ + StandardLevelComputer{ "CXX", std::vector<int>{ 98, 11, 14, 17, 20, 23 }, std::vector<std::string>{ "98", "11", "14", "17", "20", "23" } } }, { "CUDA", - StanardLevelComputer{ + StandardLevelComputer{ "CUDA", std::vector<int>{ 03, 11, 14, 17, 20, 23 }, std::vector<std::string>{ "03", "11", "14", "17", "20", "23" } } }, { "OBJC", - StanardLevelComputer{ + StandardLevelComputer{ "OBJC", std::vector<int>{ 90, 99, 11, 17, 23 }, std::vector<std::string>{ "90", "99", "11", "17", "23" } } }, { "OBJCXX", - StanardLevelComputer{ + StandardLevelComputer{ "OBJCXX", std::vector<int>{ 98, 11, 14, 17, 20, 23 }, std::vector<std::string>{ "98", "11", "14", "17", "20", "23" } } }, { "HIP", - StanardLevelComputer{ + StandardLevelComputer{ "HIP", std::vector<int>{ 98, 11, 14, 17, 20, 23 }, - std::vector<std::string>{ "98", "11", "14", "17", "20", "23" } } } }; + std::vector<std::string>{ "98", "11", "14", "17", "20", "23" } } } + }; } std::string cmStandardLevelResolver::GetCompileOptionDef( @@ -387,7 +447,11 @@ bool cmStandardLevelResolver::CheckCompileFeaturesAvailable( return false; } - const char* features = this->CompileFeaturesAvailable(lang, error); + if (!this->Makefile->GetGlobalGenerator()->GetLanguageEnabled(lang)) { + return true; + } + + cmValue features = this->CompileFeaturesAvailable(lang, error); if (!features) { return false; } @@ -465,7 +529,7 @@ bool cmStandardLevelResolver::CompileFeatureKnown( return false; } -const char* cmStandardLevelResolver::CompileFeaturesAvailable( +cmValue cmStandardLevelResolver::CompileFeaturesAvailable( const std::string& lang, std::string* error) const { if (!this->Makefile->GetGlobalGenerator()->GetLanguageEnabled(lang)) { @@ -484,7 +548,7 @@ const char* cmStandardLevelResolver::CompileFeaturesAvailable( return nullptr; } - cmProp featuresKnown = + cmValue featuresKnown = this->Makefile->GetDefinition("CMAKE_" + lang + "_COMPILE_FEATURES"); if (!cmNonempty(featuresKnown)) { @@ -507,12 +571,12 @@ const char* cmStandardLevelResolver::CompileFeaturesAvailable( } return nullptr; } - return cmToCStr(featuresKnown); + return featuresKnown; } bool cmStandardLevelResolver::GetNewRequiredStandard( const std::string& targetName, const std::string& feature, - cmProp currentLangStandardValue, std::string& newRequiredStandard, + cmValue currentLangStandardValue, std::string& newRequiredStandard, std::string* error) const { std::string lang; diff --git a/Source/cmStandardLevelResolver.h b/Source/cmStandardLevelResolver.h index d84fbcbe1..422645604 100644 --- a/Source/cmStandardLevelResolver.h +++ b/Source/cmStandardLevelResolver.h @@ -4,7 +4,7 @@ #include <string> -#include "cmProperty.h" +#include "cmValue.h" class cmMakefile; class cmGeneratorTarget; @@ -30,12 +30,12 @@ public: const std::string& feature, std::string& lang, std::string* error) const; - const char* CompileFeaturesAvailable(const std::string& lang, - std::string* error) const; + cmValue CompileFeaturesAvailable(const std::string& lang, + std::string* error) const; bool GetNewRequiredStandard(const std::string& targetName, const std::string& feature, - cmProp currentLangStandardValue, + cmValue currentLangStandardValue, std::string& newRequiredStandard, std::string* error = nullptr) const; diff --git a/Source/cmState.cxx b/Source/cmState.cxx index ce6eb311e..e79949d97 100644 --- a/Source/cmState.cxx +++ b/Source/cmState.cxx @@ -26,7 +26,9 @@ #include "cmSystemTools.h" #include "cmake.h" -cmState::cmState() +cmState::cmState(Mode mode, ProjectKind projectKind) + : StateMode(mode) + , StateProjectKind(projectKind) { this->CacheManager = cm::make_unique<cmCacheManager>(); this->GlobVerificationManager = cm::make_unique<cmGlobVerificationManager>(); @@ -142,20 +144,20 @@ std::vector<std::string> cmState::GetCacheEntryKeys() const return this->CacheManager->GetCacheEntryKeys(); } -cmProp cmState::GetCacheEntryValue(std::string const& key) const +cmValue cmState::GetCacheEntryValue(std::string const& key) const { return this->CacheManager->GetCacheEntryValue(key); } std::string cmState::GetSafeCacheEntryValue(std::string const& key) const { - if (cmProp val = this->GetCacheEntryValue(key)) { + if (cmValue val = this->GetCacheEntryValue(key)) { return *val; } return std::string(); } -cmProp cmState::GetInitializedCacheValue(std::string const& key) const +cmValue cmState::GetInitializedCacheValue(std::string const& key) const { return this->CacheManager->GetInitializedCacheValue(key); } @@ -192,8 +194,8 @@ std::vector<std::string> cmState::GetCacheEntryPropertyList( return this->CacheManager->GetCacheEntryPropertyList(key); } -cmProp cmState::GetCacheEntryProperty(std::string const& key, - std::string const& propertyName) +cmValue cmState::GetCacheEntryProperty(std::string const& key, + std::string const& propertyName) { return this->CacheManager->GetCacheEntryProperty(key, propertyName); } @@ -204,7 +206,7 @@ bool cmState::GetCacheEntryPropertyAsBool(std::string const& key, return this->CacheManager->GetCacheEntryPropertyAsBool(key, propertyName); } -void cmState::AddCacheEntry(const std::string& key, const char* value, +void cmState::AddCacheEntry(const std::string& key, cmValue value, const char* helpString, cmStateEnums::CacheEntryType type) { @@ -275,15 +277,10 @@ cmStateSnapshot cmState::Reset() cmLinkedTree<cmStateDetail::BuildsystemDirectoryStateType>::iterator it = this->BuildsystemDirectory.Truncate(); it->IncludeDirectories.clear(); - it->IncludeDirectoryBacktraces.clear(); it->CompileDefinitions.clear(); - it->CompileDefinitionsBacktraces.clear(); it->CompileOptions.clear(); - it->CompileOptionsBacktraces.clear(); it->LinkOptions.clear(); - it->LinkOptionsBacktraces.clear(); it->LinkDirectories.clear(); - it->LinkDirectoriesBacktraces.clear(); it->DirectoryEnd = pos; it->NormalTargetNames.clear(); it->ImportedTargetNames.clear(); @@ -381,16 +378,6 @@ void cmState::ClearEnabledLanguages() this->EnabledLanguages.clear(); } -bool cmState::GetIsInTryCompile() const -{ - return this->IsInTryCompile; -} - -void cmState::SetIsInTryCompile(bool b) -{ - this->IsInTryCompile = b; -} - bool cmState::GetIsGeneratorMultiConfig() const { return this->IsGeneratorMultiConfig; @@ -466,7 +453,7 @@ void cmState::AddDisallowedCommand(std::string const& name, case cmPolicies::WARN: mf.IssueMessage(MessageType::AUTHOR_WARNING, cmPolicies::GetPolicyWarning(policy)); - break; + CM_FALLTHROUGH; case cmPolicies::OLD: break; case cmPolicies::REQUIRED_IF_USED: @@ -485,7 +472,7 @@ void cmState::AddUnexpectedCommand(std::string const& name, const char* error) name, [name, error](std::vector<cmListFileArgument> const&, cmExecutionStatus& status) -> bool { - cmProp versionValue = + cmValue versionValue = status.GetMakefile().GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION"); if (name == "endif" && (!versionValue || atof(versionValue->c_str()) <= 1.4)) { @@ -577,6 +564,10 @@ void cmState::SetGlobalProperty(const std::string& prop, const char* value) { this->GlobalProperties.SetProperty(prop, value); } +void cmState::SetGlobalProperty(const std::string& prop, cmValue value) +{ + this->GlobalProperties.SetProperty(prop, value); +} void cmState::AppendGlobalProperty(const std::string& prop, const std::string& value, bool asString) @@ -584,7 +575,7 @@ void cmState::AppendGlobalProperty(const std::string& prop, this->GlobalProperties.AppendProperty(prop, value, asString); } -cmProp cmState::GetGlobalProperty(const std::string& prop) +cmValue cmState::GetGlobalProperty(const std::string& prop) { if (prop == "CACHE_VARIABLES") { std::vector<std::string> cacheKeys = this->GetCacheEntryKeys(); @@ -593,8 +584,9 @@ cmProp cmState::GetGlobalProperty(const std::string& prop) std::vector<std::string> commands = this->GetCommandNames(); this->SetGlobalProperty("COMMANDS", cmJoin(commands, ";").c_str()); } else if (prop == "IN_TRY_COMPILE") { - this->SetGlobalProperty("IN_TRY_COMPILE", - this->IsInTryCompile ? "1" : "0"); + this->SetGlobalProperty( + "IN_TRY_COMPILE", + this->StateProjectKind == ProjectKind::TryCompile ? "1" : "0"); } else if (prop == "GENERATOR_IS_MULTI_CONFIG") { this->SetGlobalProperty("GENERATOR_IS_MULTI_CONFIG", this->IsGeneratorMultiConfig ? "1" : "0"); @@ -610,47 +602,47 @@ cmProp cmState::GetGlobalProperty(const std::string& prop) if (prop == "CMAKE_C_KNOWN_FEATURES") { static const std::string s_out( &FOR_EACH_C_FEATURE(STRING_LIST_ELEMENT)[1]); - return &s_out; + return cmValue(s_out); } if (prop == "CMAKE_C90_KNOWN_FEATURES") { static const std::string s_out( &FOR_EACH_C90_FEATURE(STRING_LIST_ELEMENT)[1]); - return &s_out; + return cmValue(s_out); } if (prop == "CMAKE_C99_KNOWN_FEATURES") { static const std::string s_out( &FOR_EACH_C99_FEATURE(STRING_LIST_ELEMENT)[1]); - return &s_out; + return cmValue(s_out); } if (prop == "CMAKE_C11_KNOWN_FEATURES") { static const std::string s_out( &FOR_EACH_C11_FEATURE(STRING_LIST_ELEMENT)[1]); - return &s_out; + return cmValue(s_out); } if (prop == "CMAKE_CXX_KNOWN_FEATURES") { static const std::string s_out( &FOR_EACH_CXX_FEATURE(STRING_LIST_ELEMENT)[1]); - return &s_out; + return cmValue(s_out); } if (prop == "CMAKE_CXX98_KNOWN_FEATURES") { static const std::string s_out( &FOR_EACH_CXX98_FEATURE(STRING_LIST_ELEMENT)[1]); - return &s_out; + return cmValue(s_out); } if (prop == "CMAKE_CXX11_KNOWN_FEATURES") { static const std::string s_out( &FOR_EACH_CXX11_FEATURE(STRING_LIST_ELEMENT)[1]); - return &s_out; + return cmValue(s_out); } if (prop == "CMAKE_CXX14_KNOWN_FEATURES") { static const std::string s_out( &FOR_EACH_CXX14_FEATURE(STRING_LIST_ELEMENT)[1]); - return &s_out; + return cmValue(s_out); } if (prop == "CMAKE_CUDA_KNOWN_FEATURES") { static const std::string s_out( &FOR_EACH_CUDA_FEATURE(STRING_LIST_ELEMENT)[1]); - return &s_out; + return cmValue(s_out); } #undef STRING_LIST_ELEMENT @@ -771,17 +763,12 @@ unsigned int cmState::GetCacheMinorVersion() const cmState::Mode cmState::GetMode() const { - return this->CurrentMode; + return this->StateMode; } std::string cmState::GetModeString() const { - return ModeToString(this->CurrentMode); -} - -void cmState::SetMode(cmState::Mode mode) -{ - this->CurrentMode = mode; + return ModeToString(this->StateMode); } std::string cmState::ModeToString(cmState::Mode mode) @@ -803,6 +790,11 @@ std::string cmState::ModeToString(cmState::Mode mode) return "UNKNOWN"; } +cmState::ProjectKind cmState::GetProjectKind() const +{ + return this->StateProjectKind; +} + std::string const& cmState::GetBinaryDirectory() const { return this->BinaryDirectory; diff --git a/Source/cmState.h b/Source/cmState.h index 9951b9acf..a1666ca1f 100644 --- a/Source/cmState.h +++ b/Source/cmState.h @@ -21,6 +21,7 @@ #include "cmPropertyMap.h" #include "cmStatePrivate.h" #include "cmStateTypes.h" +#include "cmValue.h" class cmCacheManager; class cmCommand; @@ -35,12 +36,6 @@ class cmState friend class cmStateSnapshot; public: - cmState(); - ~cmState(); - - cmState(const cmState&) = delete; - cmState& operator=(const cmState&) = delete; - enum Mode { Unknown, @@ -51,6 +46,18 @@ public: CPack, }; + enum class ProjectKind + { + Normal, + TryCompile, + }; + + cmState(Mode mode, ProjectKind projectKind = ProjectKind::Normal); + ~cmState(); + + cmState(const cmState&) = delete; + cmState& operator=(const cmState&) = delete; + static const std::string& GetTargetTypeName( cmStateEnums::TargetType targetType); @@ -92,9 +99,9 @@ public: bool IsCacheLoaded() const; std::vector<std::string> GetCacheEntryKeys() const; - cmProp GetCacheEntryValue(std::string const& key) const; + cmValue GetCacheEntryValue(std::string const& key) const; std::string GetSafeCacheEntryValue(std::string const& key) const; - cmProp GetInitializedCacheValue(std::string const& key) const; + cmValue GetInitializedCacheValue(std::string const& key) const; cmStateEnums::CacheEntryType GetCacheEntryType(std::string const& key) const; void SetCacheEntryValue(std::string const& key, std::string const& value); @@ -106,8 +113,8 @@ public: void SetCacheEntryBoolProperty(std::string const& key, std::string const& propertyName, bool value); std::vector<std::string> GetCacheEntryPropertyList(std::string const& key); - cmProp GetCacheEntryProperty(std::string const& key, - std::string const& propertyName); + cmValue GetCacheEntryProperty(std::string const& key, + std::string const& propertyName); bool GetCacheEntryPropertyAsBool(std::string const& key, std::string const& propertyName); void AppendCacheEntryProperty(std::string const& key, @@ -141,9 +148,6 @@ public: void SetEnabledLanguages(std::vector<std::string> const& langs); void ClearEnabledLanguages(); - bool GetIsInTryCompile() const; - void SetIsInTryCompile(bool b); - bool GetIsGeneratorMultiConfig() const; void SetIsGeneratorMultiConfig(bool b); @@ -175,9 +179,10 @@ public: std::vector<std::string> GetCommandNames() const; void SetGlobalProperty(const std::string& prop, const char* value); + void SetGlobalProperty(const std::string& prop, cmValue value); void AppendGlobalProperty(const std::string& prop, const std::string& value, bool asString = false); - cmProp GetGlobalProperty(const std::string& prop); + cmValue GetGlobalProperty(const std::string& prop); bool GetGlobalPropertyAsBool(const std::string& prop); std::string const& GetSourceDirectory() const; @@ -207,13 +212,26 @@ public: Mode GetMode() const; std::string GetModeString() const; - void SetMode(Mode mode); static std::string ModeToString(Mode mode); + ProjectKind GetProjectKind() const; + private: friend class cmake; void AddCacheEntry(const std::string& key, const char* value, + const char* helpString, cmStateEnums::CacheEntryType type) + { + this->AddCacheEntry(key, + value ? cmValue(std::string(value)) : cmValue(nullptr), + helpString, type); + } + void AddCacheEntry(const std::string& key, const std::string& value, + const char* helpString, cmStateEnums::CacheEntryType type) + { + this->AddCacheEntry(key, cmValue(value), helpString, type); + } + void AddCacheEntry(const std::string& key, cmValue value, const char* helpString, cmStateEnums::CacheEntryType type); @@ -248,7 +266,6 @@ private: std::string SourceDirectory; std::string BinaryDirectory; - bool IsInTryCompile = false; bool IsGeneratorMultiConfig = false; bool WindowsShell = false; bool WindowsVSIDE = false; @@ -258,5 +275,6 @@ private: bool NMake = false; bool MSYSShell = false; bool NinjaMulti = false; - Mode CurrentMode = Unknown; + Mode StateMode = Unknown; + ProjectKind StateProjectKind = ProjectKind::Normal; }; diff --git a/Source/cmStateDirectory.cxx b/Source/cmStateDirectory.cxx index c898dd475..b42e5c338 100644 --- a/Source/cmStateDirectory.cxx +++ b/Source/cmStateDirectory.cxx @@ -19,7 +19,9 @@ #include "cmState.h" #include "cmStatePrivate.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" static std::string const kBINARY_DIR = "BINARY_DIR"; static std::string const kBUILDSYSTEM_TARGETS = "BUILDSYSTEM_TARGETS"; @@ -63,7 +65,7 @@ cmStateDirectory::cmStateDirectory( } template <typename T, typename U> -cmStringRange GetPropertyContent(T const& content, U contentEndPosition) +cmBTStringRange GetPropertyContent(T const& content, U contentEndPosition) { auto end = content.begin() + contentEndPosition; @@ -73,88 +75,59 @@ cmStringRange GetPropertyContent(T const& content, U contentEndPosition) return cmMakeRange(rbegin.base(), end); } -template <typename T, typename U, typename V> -cmBacktraceRange GetPropertyBacktraces(T const& content, U const& backtraces, - V contentEndPosition) -{ - auto entryEnd = content.begin() + contentEndPosition; - - auto rbegin = cm::make_reverse_iterator(entryEnd); - rbegin = std::find(rbegin, content.rend(), cmPropertySentinal); - - auto it = backtraces.begin() + std::distance(content.begin(), rbegin.base()); - - auto end = backtraces.end(); - return cmMakeRange(it, end); -} - -template <typename T, typename U, typename V> -void AppendEntry(T& content, U& backtraces, V& endContentPosition, - const std::string& value, const cmListFileBacktrace& lfbt) +template <typename T, typename U> +void AppendEntry(T& content, U& endContentPosition, + const BT<std::string>& value) { - if (value.empty()) { + if (value.Value.empty()) { return; } assert(endContentPosition == content.size()); content.push_back(value); - backtraces.push_back(lfbt); endContentPosition = content.size(); } -template <typename T, typename U, typename V> -void SetContent(T& content, U& backtraces, V& endContentPosition, - const std::string& vec, const cmListFileBacktrace& lfbt) +template <typename T, typename U> +void SetContent(T& content, U& endContentPosition, const BT<std::string>& vec) { assert(endContentPosition == content.size()); content.resize(content.size() + 2); - backtraces.resize(backtraces.size() + 2); content.back() = vec; - backtraces.back() = lfbt; endContentPosition = content.size(); } -template <typename T, typename U, typename V> -void ClearContent(T& content, U& backtraces, V& endContentPosition) +template <typename T, typename U> +void ClearContent(T& content, U& endContentPosition) { assert(endContentPosition == content.size()); content.resize(content.size() + 1); - backtraces.resize(backtraces.size() + 1); endContentPosition = content.size(); } -cmStringRange cmStateDirectory::GetIncludeDirectoriesEntries() const +cmBTStringRange cmStateDirectory::GetIncludeDirectoriesEntries() const { return GetPropertyContent( this->DirectoryState->IncludeDirectories, this->Snapshot_.Position->IncludeDirectoryPosition); } -cmBacktraceRange cmStateDirectory::GetIncludeDirectoriesEntryBacktraces() const -{ - return GetPropertyBacktraces( - this->DirectoryState->IncludeDirectories, - this->DirectoryState->IncludeDirectoryBacktraces, - this->Snapshot_.Position->IncludeDirectoryPosition); -} - void cmStateDirectory::AppendIncludeDirectoriesEntry( - const std::string& vec, const cmListFileBacktrace& lfbt) + const BT<std::string>& vec) { AppendEntry(this->DirectoryState->IncludeDirectories, - this->DirectoryState->IncludeDirectoryBacktraces, - this->Snapshot_.Position->IncludeDirectoryPosition, vec, lfbt); + this->Snapshot_.Position->IncludeDirectoryPosition, vec); } void cmStateDirectory::PrependIncludeDirectoriesEntry( - const std::string& vec, const cmListFileBacktrace& lfbt) + const BT<std::string>& vec) { auto entryEnd = this->DirectoryState->IncludeDirectories.begin() + this->Snapshot_.Position->IncludeDirectoryPosition; @@ -164,167 +137,111 @@ void cmStateDirectory::PrependIncludeDirectoriesEntry( rbegin = std::find(rbegin, rend, cmPropertySentinal); auto entryIt = rbegin.base(); - auto entryBegin = this->DirectoryState->IncludeDirectories.begin(); - - auto btIt = this->DirectoryState->IncludeDirectoryBacktraces.begin() + - std::distance(entryBegin, entryIt); this->DirectoryState->IncludeDirectories.insert(entryIt, vec); - this->DirectoryState->IncludeDirectoryBacktraces.insert(btIt, lfbt); this->Snapshot_.Position->IncludeDirectoryPosition = this->DirectoryState->IncludeDirectories.size(); } -void cmStateDirectory::SetIncludeDirectories(const std::string& vec, - const cmListFileBacktrace& lfbt) +void cmStateDirectory::SetIncludeDirectories(const BT<std::string>& vec) { SetContent(this->DirectoryState->IncludeDirectories, - this->DirectoryState->IncludeDirectoryBacktraces, - this->Snapshot_.Position->IncludeDirectoryPosition, vec, lfbt); + this->Snapshot_.Position->IncludeDirectoryPosition, vec); } void cmStateDirectory::ClearIncludeDirectories() { ClearContent(this->DirectoryState->IncludeDirectories, - this->DirectoryState->IncludeDirectoryBacktraces, this->Snapshot_.Position->IncludeDirectoryPosition); } -cmStringRange cmStateDirectory::GetCompileDefinitionsEntries() const +cmBTStringRange cmStateDirectory::GetCompileDefinitionsEntries() const { return GetPropertyContent( this->DirectoryState->CompileDefinitions, this->Snapshot_.Position->CompileDefinitionsPosition); } -cmBacktraceRange cmStateDirectory::GetCompileDefinitionsEntryBacktraces() const -{ - return GetPropertyBacktraces( - this->DirectoryState->CompileDefinitions, - this->DirectoryState->CompileDefinitionsBacktraces, - this->Snapshot_.Position->CompileDefinitionsPosition); -} - void cmStateDirectory::AppendCompileDefinitionsEntry( - const std::string& vec, const cmListFileBacktrace& lfbt) + const BT<std::string>& vec) { AppendEntry(this->DirectoryState->CompileDefinitions, - this->DirectoryState->CompileDefinitionsBacktraces, - this->Snapshot_.Position->CompileDefinitionsPosition, vec, lfbt); + this->Snapshot_.Position->CompileDefinitionsPosition, vec); } -void cmStateDirectory::SetCompileDefinitions(const std::string& vec, - const cmListFileBacktrace& lfbt) +void cmStateDirectory::SetCompileDefinitions(const BT<std::string>& vec) { SetContent(this->DirectoryState->CompileDefinitions, - this->DirectoryState->CompileDefinitionsBacktraces, - this->Snapshot_.Position->CompileDefinitionsPosition, vec, lfbt); + this->Snapshot_.Position->CompileDefinitionsPosition, vec); } void cmStateDirectory::ClearCompileDefinitions() { ClearContent(this->DirectoryState->CompileDefinitions, - this->DirectoryState->CompileDefinitionsBacktraces, this->Snapshot_.Position->CompileDefinitionsPosition); } -cmStringRange cmStateDirectory::GetCompileOptionsEntries() const +cmBTStringRange cmStateDirectory::GetCompileOptionsEntries() const { return GetPropertyContent(this->DirectoryState->CompileOptions, this->Snapshot_.Position->CompileOptionsPosition); } -cmBacktraceRange cmStateDirectory::GetCompileOptionsEntryBacktraces() const -{ - return GetPropertyBacktraces( - this->DirectoryState->CompileOptions, - this->DirectoryState->CompileOptionsBacktraces, - this->Snapshot_.Position->CompileOptionsPosition); -} - -void cmStateDirectory::AppendCompileOptionsEntry( - const std::string& vec, const cmListFileBacktrace& lfbt) +void cmStateDirectory::AppendCompileOptionsEntry(const BT<std::string>& vec) { AppendEntry(this->DirectoryState->CompileOptions, - this->DirectoryState->CompileOptionsBacktraces, - this->Snapshot_.Position->CompileOptionsPosition, vec, lfbt); + this->Snapshot_.Position->CompileOptionsPosition, vec); } -void cmStateDirectory::SetCompileOptions(const std::string& vec, - const cmListFileBacktrace& lfbt) +void cmStateDirectory::SetCompileOptions(const BT<std::string>& vec) { SetContent(this->DirectoryState->CompileOptions, - this->DirectoryState->CompileOptionsBacktraces, - this->Snapshot_.Position->CompileOptionsPosition, vec, lfbt); + this->Snapshot_.Position->CompileOptionsPosition, vec); } void cmStateDirectory::ClearCompileOptions() { ClearContent(this->DirectoryState->CompileOptions, - this->DirectoryState->CompileOptionsBacktraces, this->Snapshot_.Position->CompileOptionsPosition); } -cmStringRange cmStateDirectory::GetLinkOptionsEntries() const +cmBTStringRange cmStateDirectory::GetLinkOptionsEntries() const { return GetPropertyContent(this->DirectoryState->LinkOptions, this->Snapshot_.Position->LinkOptionsPosition); } -cmBacktraceRange cmStateDirectory::GetLinkOptionsEntryBacktraces() const -{ - return GetPropertyBacktraces(this->DirectoryState->LinkOptions, - this->DirectoryState->LinkOptionsBacktraces, - this->Snapshot_.Position->LinkOptionsPosition); -} - -void cmStateDirectory::AppendLinkOptionsEntry(const std::string& vec, - const cmListFileBacktrace& lfbt) +void cmStateDirectory::AppendLinkOptionsEntry(const BT<std::string>& vec) { AppendEntry(this->DirectoryState->LinkOptions, - this->DirectoryState->LinkOptionsBacktraces, - this->Snapshot_.Position->LinkOptionsPosition, vec, lfbt); + this->Snapshot_.Position->LinkOptionsPosition, vec); } -void cmStateDirectory::SetLinkOptions(const std::string& vec, - const cmListFileBacktrace& lfbt) +void cmStateDirectory::SetLinkOptions(const BT<std::string>& vec) { SetContent(this->DirectoryState->LinkOptions, - this->DirectoryState->LinkOptionsBacktraces, - this->Snapshot_.Position->LinkOptionsPosition, vec, lfbt); + this->Snapshot_.Position->LinkOptionsPosition, vec); } void cmStateDirectory::ClearLinkOptions() { ClearContent(this->DirectoryState->LinkOptions, - this->DirectoryState->LinkOptionsBacktraces, this->Snapshot_.Position->LinkOptionsPosition); } -cmStringRange cmStateDirectory::GetLinkDirectoriesEntries() const +cmBTStringRange cmStateDirectory::GetLinkDirectoriesEntries() const { return GetPropertyContent(this->DirectoryState->LinkDirectories, this->Snapshot_.Position->LinkDirectoriesPosition); } -cmBacktraceRange cmStateDirectory::GetLinkDirectoriesEntryBacktraces() const -{ - return GetPropertyBacktraces( - this->DirectoryState->LinkDirectories, - this->DirectoryState->LinkDirectoriesBacktraces, - this->Snapshot_.Position->LinkDirectoriesPosition); -} - -void cmStateDirectory::AppendLinkDirectoriesEntry( - const std::string& vec, const cmListFileBacktrace& lfbt) +void cmStateDirectory::AppendLinkDirectoriesEntry(const BT<std::string>& vec) { AppendEntry(this->DirectoryState->LinkDirectories, - this->DirectoryState->LinkDirectoriesBacktraces, - this->Snapshot_.Position->LinkDirectoriesPosition, vec, lfbt); + this->Snapshot_.Position->LinkDirectoriesPosition, vec); } -void cmStateDirectory::PrependLinkDirectoriesEntry( - const std::string& vec, const cmListFileBacktrace& lfbt) +void cmStateDirectory::PrependLinkDirectoriesEntry(const BT<std::string>& vec) { auto entryEnd = this->DirectoryState->LinkDirectories.begin() + this->Snapshot_.Position->LinkDirectoriesPosition; @@ -334,42 +251,35 @@ void cmStateDirectory::PrependLinkDirectoriesEntry( rbegin = std::find(rbegin, rend, cmPropertySentinal); auto entryIt = rbegin.base(); - auto entryBegin = this->DirectoryState->LinkDirectories.begin(); - - auto btIt = this->DirectoryState->LinkDirectoriesBacktraces.begin() + - std::distance(entryBegin, entryIt); this->DirectoryState->LinkDirectories.insert(entryIt, vec); - this->DirectoryState->LinkDirectoriesBacktraces.insert(btIt, lfbt); this->Snapshot_.Position->LinkDirectoriesPosition = this->DirectoryState->LinkDirectories.size(); } -void cmStateDirectory::SetLinkDirectories(const std::string& vec, - const cmListFileBacktrace& lfbt) +void cmStateDirectory::SetLinkDirectories(const BT<std::string>& vec) { SetContent(this->DirectoryState->LinkDirectories, - this->DirectoryState->LinkDirectoriesBacktraces, - this->Snapshot_.Position->LinkDirectoriesPosition, vec, lfbt); + this->Snapshot_.Position->LinkDirectoriesPosition, vec); } void cmStateDirectory::ClearLinkDirectories() { ClearContent(this->DirectoryState->LinkDirectories, - this->DirectoryState->LinkDirectoriesBacktraces, this->Snapshot_.Position->LinkDirectoriesPosition); } -void cmStateDirectory::SetProperty(const std::string& prop, const char* value, - cmListFileBacktrace const& lfbt) +template <typename ValueType> +void cmStateDirectory::StoreProperty(const std::string& prop, ValueType value, + cmListFileBacktrace const& lfbt) { if (prop == "INCLUDE_DIRECTORIES") { if (!value) { this->ClearIncludeDirectories(); return; } - this->SetIncludeDirectories(value, lfbt); + this->SetIncludeDirectories(BT<std::string>(value, lfbt)); return; } if (prop == "COMPILE_OPTIONS") { @@ -377,7 +287,7 @@ void cmStateDirectory::SetProperty(const std::string& prop, const char* value, this->ClearCompileOptions(); return; } - this->SetCompileOptions(value, lfbt); + this->SetCompileOptions(BT<std::string>(value, lfbt)); return; } if (prop == "COMPILE_DEFINITIONS") { @@ -385,7 +295,7 @@ void cmStateDirectory::SetProperty(const std::string& prop, const char* value, this->ClearCompileDefinitions(); return; } - this->SetCompileDefinitions(value, lfbt); + this->SetCompileDefinitions(BT<std::string>(value, lfbt)); return; } if (prop == "LINK_OPTIONS") { @@ -393,7 +303,7 @@ void cmStateDirectory::SetProperty(const std::string& prop, const char* value, this->ClearLinkOptions(); return; } - this->SetLinkOptions(value, lfbt); + this->SetLinkOptions(BT<std::string>(value, lfbt)); return; } if (prop == "LINK_DIRECTORIES") { @@ -401,66 +311,78 @@ void cmStateDirectory::SetProperty(const std::string& prop, const char* value, this->ClearLinkDirectories(); return; } - this->SetLinkDirectories(value, lfbt); + this->SetLinkDirectories(BT<std::string>(value, lfbt)); return; } this->DirectoryState->Properties.SetProperty(prop, value); } +void cmStateDirectory::SetProperty(const std::string& prop, const char* value, + cmListFileBacktrace const& lfbt) +{ + this->StoreProperty(prop, value, lfbt); +} +void cmStateDirectory::SetProperty(const std::string& prop, cmValue value, + cmListFileBacktrace const& lfbt) +{ + this->StoreProperty(prop, value, lfbt); +} + void cmStateDirectory::AppendProperty(const std::string& prop, const std::string& value, bool asString, cmListFileBacktrace const& lfbt) { if (prop == "INCLUDE_DIRECTORIES") { - this->AppendIncludeDirectoriesEntry(value, lfbt); + this->AppendIncludeDirectoriesEntry(BT<std::string>(value, lfbt)); return; } if (prop == "COMPILE_OPTIONS") { - this->AppendCompileOptionsEntry(value, lfbt); + this->AppendCompileOptionsEntry(BT<std::string>(value, lfbt)); return; } if (prop == "COMPILE_DEFINITIONS") { - this->AppendCompileDefinitionsEntry(value, lfbt); + this->AppendCompileDefinitionsEntry(BT<std::string>(value, lfbt)); return; } if (prop == "LINK_OPTIONS") { - this->AppendLinkOptionsEntry(value, lfbt); + this->AppendLinkOptionsEntry(BT<std::string>(value, lfbt)); return; } if (prop == "LINK_DIRECTORIES") { - this->AppendLinkDirectoriesEntry(value, lfbt); + this->AppendLinkDirectoriesEntry(BT<std::string>(value, lfbt)); return; } this->DirectoryState->Properties.AppendProperty(prop, value, asString); } -cmProp cmStateDirectory::GetProperty(const std::string& prop) const +cmValue cmStateDirectory::GetProperty(const std::string& prop) const { const bool chain = this->Snapshot_.State->IsPropertyChained(prop, cmProperty::DIRECTORY); return this->GetProperty(prop, chain); } -cmProp cmStateDirectory::GetProperty(const std::string& prop, bool chain) const +cmValue cmStateDirectory::GetProperty(const std::string& prop, + bool chain) const { static std::string output; output.clear(); if (prop == "PARENT_DIRECTORY") { cmStateSnapshot parent = this->Snapshot_.GetBuildsystemDirectoryParent(); if (parent.IsValid()) { - return &parent.GetDirectory().GetCurrentSource(); + return cmValue(parent.GetDirectory().GetCurrentSource()); } - return &output; + return cmValue(output); } if (prop == kBINARY_DIR) { output = this->GetCurrentBinary(); - return &output; + return cmValue(output); } if (prop == kSOURCE_DIR) { output = this->GetCurrentSource(); - return &output; + return cmValue(output); } if (prop == kSUBDIRECTORIES) { std::vector<std::string> child_dirs; @@ -471,15 +393,15 @@ cmProp cmStateDirectory::GetProperty(const std::string& prop, bool chain) const child_dirs.push_back(ci.GetDirectory().GetCurrentSource()); } output = cmJoin(child_dirs, ";"); - return &output; + return cmValue(output); } if (prop == kBUILDSYSTEM_TARGETS) { output = cmJoin(this->DirectoryState->NormalTargetNames, ";"); - return &output; + return cmValue(output); } if (prop == "IMPORTED_TARGETS"_s) { output = cmJoin(this->DirectoryState->ImportedTargetNames, ";"); - return &output; + return cmValue(output); } if (prop == "LISTFILE_STACK") { @@ -491,41 +413,41 @@ cmProp cmStateDirectory::GetProperty(const std::string& prop, bool chain) const } std::reverse(listFiles.begin(), listFiles.end()); output = cmJoin(listFiles, ";"); - return &output; + return cmValue(output); } if (prop == "CACHE_VARIABLES") { output = cmJoin(this->Snapshot_.State->GetCacheEntryKeys(), ";"); - return &output; + return cmValue(output); } if (prop == "VARIABLES") { std::vector<std::string> res = this->Snapshot_.ClosureKeys(); cm::append(res, this->Snapshot_.State->GetCacheEntryKeys()); std::sort(res.begin(), res.end()); output = cmJoin(res, ";"); - return &output; + return cmValue(output); } if (prop == "INCLUDE_DIRECTORIES") { output = cmJoin(this->GetIncludeDirectoriesEntries(), ";"); - return &output; + return cmValue(output); } if (prop == "COMPILE_OPTIONS") { output = cmJoin(this->GetCompileOptionsEntries(), ";"); - return &output; + return cmValue(output); } if (prop == "COMPILE_DEFINITIONS") { output = cmJoin(this->GetCompileDefinitionsEntries(), ";"); - return &output; + return cmValue(output); } if (prop == "LINK_OPTIONS") { output = cmJoin(this->GetLinkOptionsEntries(), ";"); - return &output; + return cmValue(output); } if (prop == "LINK_DIRECTORIES") { output = cmJoin(this->GetLinkDirectoriesEntries(), ";"); - return &output; + return cmValue(output); } - cmProp retVal = this->DirectoryState->Properties.GetPropertyValue(prop); + cmValue retVal = this->DirectoryState->Properties.GetPropertyValue(prop); if (!retVal && chain) { cmStateSnapshot parentSnapshot = this->Snapshot_.GetBuildsystemDirectoryParent(); diff --git a/Source/cmStateDirectory.h b/Source/cmStateDirectory.h index b8abccb81..6429f3293 100644 --- a/Source/cmStateDirectory.h +++ b/Source/cmStateDirectory.h @@ -11,10 +11,9 @@ #include "cmAlgorithms.h" #include "cmLinkedTree.h" #include "cmListFileCache.h" -#include "cmProperty.h" #include "cmStatePrivate.h" #include "cmStateSnapshot.h" -#include "cmStringAlgorithms.h" +#include "cmValue.h" class cmStateDirectory { @@ -28,55 +27,41 @@ public: std::string const& GetCurrentBinary() const; void SetCurrentBinary(std::string const& dir); - cmStringRange GetIncludeDirectoriesEntries() const; - cmBacktraceRange GetIncludeDirectoriesEntryBacktraces() const; - void AppendIncludeDirectoriesEntry(std::string const& vec, - cmListFileBacktrace const& lfbt); - void PrependIncludeDirectoriesEntry(std::string const& vec, - cmListFileBacktrace const& lfbt); - void SetIncludeDirectories(std::string const& vec, - cmListFileBacktrace const& lfbt); + cmBTStringRange GetIncludeDirectoriesEntries() const; + void AppendIncludeDirectoriesEntry(BT<std::string> const& vec); + void PrependIncludeDirectoriesEntry(BT<std::string> const& vec); + void SetIncludeDirectories(BT<std::string> const& vec); void ClearIncludeDirectories(); - cmStringRange GetCompileDefinitionsEntries() const; - cmBacktraceRange GetCompileDefinitionsEntryBacktraces() const; - void AppendCompileDefinitionsEntry(std::string const& vec, - cmListFileBacktrace const& lfbt); - void SetCompileDefinitions(std::string const& vec, - cmListFileBacktrace const& lfbt); + cmBTStringRange GetCompileDefinitionsEntries() const; + void AppendCompileDefinitionsEntry(BT<std::string> const& vec); + void SetCompileDefinitions(BT<std::string> const& vec); void ClearCompileDefinitions(); - cmStringRange GetCompileOptionsEntries() const; - cmBacktraceRange GetCompileOptionsEntryBacktraces() const; - void AppendCompileOptionsEntry(std::string const& vec, - cmListFileBacktrace const& lfbt); - void SetCompileOptions(std::string const& vec, - cmListFileBacktrace const& lfbt); + cmBTStringRange GetCompileOptionsEntries() const; + void AppendCompileOptionsEntry(BT<std::string> const& vec); + void SetCompileOptions(BT<std::string> const& vec); void ClearCompileOptions(); - cmStringRange GetLinkOptionsEntries() const; - cmBacktraceRange GetLinkOptionsEntryBacktraces() const; - void AppendLinkOptionsEntry(std::string const& vec, - cmListFileBacktrace const& lfbt); - void PrependLinkDirectoriesEntry(std::string const& vec, - cmListFileBacktrace const& lfbt); - void SetLinkOptions(std::string const& vec, cmListFileBacktrace const& lfbt); + cmBTStringRange GetLinkOptionsEntries() const; + void AppendLinkOptionsEntry(BT<std::string> const& vec); + void PrependLinkDirectoriesEntry(BT<std::string> const& vec); + void SetLinkOptions(BT<std::string> const& vec); void ClearLinkOptions(); - cmStringRange GetLinkDirectoriesEntries() const; - cmBacktraceRange GetLinkDirectoriesEntryBacktraces() const; - void AppendLinkDirectoriesEntry(std::string const& vec, - cmListFileBacktrace const& lfbt); - void SetLinkDirectories(std::string const& vec, - cmListFileBacktrace const& lfbt); + cmBTStringRange GetLinkDirectoriesEntries() const; + void AppendLinkDirectoriesEntry(BT<std::string> const& vec); + void SetLinkDirectories(BT<std::string> const& vecs); void ClearLinkDirectories(); void SetProperty(const std::string& prop, const char* value, cmListFileBacktrace const& lfbt); + void SetProperty(const std::string& prop, cmValue value, + cmListFileBacktrace const& lfbt); void AppendProperty(const std::string& prop, const std::string& value, bool asString, cmListFileBacktrace const& lfbt); - cmProp GetProperty(const std::string& prop) const; - cmProp GetProperty(const std::string& prop, bool chain) const; + cmValue GetProperty(const std::string& prop) const; + cmValue GetProperty(const std::string& prop, bool chain) const; bool GetPropertyAsBool(const std::string& prop) const; std::vector<std::string> GetPropertyKeys() const; @@ -84,6 +69,10 @@ public: void AddImportedTargetName(std::string const& name); private: + template <typename ValueType> + void StoreProperty(const std::string& prop, ValueType value, + cmListFileBacktrace const& lfbt); + cmLinkedTree<cmStateDetail::BuildsystemDirectoryStateType>::iterator DirectoryState; cmStateSnapshot Snapshot_; diff --git a/Source/cmStatePrivate.h b/Source/cmStatePrivate.h index 6f475f2ee..fd46eedfa 100644 --- a/Source/cmStatePrivate.h +++ b/Source/cmStatePrivate.h @@ -67,20 +67,15 @@ struct cmStateDetail::BuildsystemDirectoryStateType std::string Location; std::string OutputLocation; - std::vector<std::string> IncludeDirectories; - std::vector<cmListFileBacktrace> IncludeDirectoryBacktraces; + std::vector<BT<std::string>> IncludeDirectories; - std::vector<std::string> CompileDefinitions; - std::vector<cmListFileBacktrace> CompileDefinitionsBacktraces; + std::vector<BT<std::string>> CompileDefinitions; - std::vector<std::string> CompileOptions; - std::vector<cmListFileBacktrace> CompileOptionsBacktraces; + std::vector<BT<std::string>> CompileOptions; - std::vector<std::string> LinkOptions; - std::vector<cmListFileBacktrace> LinkOptionsBacktraces; + std::vector<BT<std::string>> LinkOptions; - std::vector<std::string> LinkDirectories; - std::vector<cmListFileBacktrace> LinkDirectoriesBacktraces; + std::vector<BT<std::string>> LinkDirectories; std::vector<std::string> NormalTargetNames; std::vector<std::string> ImportedTargetNames; diff --git a/Source/cmStateSnapshot.cxx b/Source/cmStateSnapshot.cxx index fbf47ef68..f73df8f08 100644 --- a/Source/cmStateSnapshot.cxx +++ b/Source/cmStateSnapshot.cxx @@ -11,14 +11,18 @@ #include "cmDefinitions.h" #include "cmListFileCache.h" -#include "cmProperty.h" #include "cmPropertyMap.h" #include "cmState.h" #include "cmStateDirectory.h" #include "cmStatePrivate.h" #include "cmSystemTools.h" +#include "cmValue.h" #include "cmVersion.h" +#if defined(__CYGWIN__) +# include "cmStringAlgorithms.h" +#endif + cmStateSnapshot::cmStateSnapshot(cmState* state) : State(state) { @@ -201,8 +205,7 @@ bool cmStateSnapshot::HasDefinedPolicyCMP0011() return !this->Position->Policies->IsEmpty(); } -std::string const* cmStateSnapshot::GetDefinition( - std::string const& name) const +cmValue cmStateSnapshot::GetDefinition(std::string const& name) const { assert(this->Position->Vars.IsValid()); return cmDefinitions::Get(name, this->Position->Vars, this->Position->Root); @@ -260,12 +263,10 @@ bool cmStateSnapshot::RaiseScope(std::string const& var, const char* varDef) return true; } -template <typename T, typename U, typename V> +template <typename T, typename U> void InitializeContentFromParent(T& parentContent, T& thisContent, - U& parentBacktraces, U& thisBacktraces, - V& contentEndPosition) + U& contentEndPosition) { - auto parentBegin = parentContent.begin(); auto parentEnd = parentContent.end(); auto parentRbegin = cm::make_reverse_iterator(parentEnd); @@ -273,12 +274,7 @@ void InitializeContentFromParent(T& parentContent, T& thisContent, parentRbegin = std::find(parentRbegin, parentRend, cmPropertySentinal); auto parentIt = parentRbegin.base(); - thisContent = std::vector<std::string>(parentIt, parentEnd); - - auto btIt = parentBacktraces.begin() + std::distance(parentBegin, parentIt); - auto btEnd = parentBacktraces.end(); - - thisBacktraces = std::vector<cmListFileBacktrace>(btIt, btEnd); + thisContent = std::vector<BT<std::string>>(parentIt, parentEnd); contentEndPosition = thisContent.size(); } @@ -360,43 +356,33 @@ void cmStateSnapshot::InitializeFromParent() InitializeContentFromParent( parent->BuildSystemDirectory->IncludeDirectories, this->Position->BuildSystemDirectory->IncludeDirectories, - parent->BuildSystemDirectory->IncludeDirectoryBacktraces, - this->Position->BuildSystemDirectory->IncludeDirectoryBacktraces, this->Position->IncludeDirectoryPosition); InitializeContentFromParent( parent->BuildSystemDirectory->CompileDefinitions, this->Position->BuildSystemDirectory->CompileDefinitions, - parent->BuildSystemDirectory->CompileDefinitionsBacktraces, - this->Position->BuildSystemDirectory->CompileDefinitionsBacktraces, this->Position->CompileDefinitionsPosition); InitializeContentFromParent( parent->BuildSystemDirectory->CompileOptions, this->Position->BuildSystemDirectory->CompileOptions, - parent->BuildSystemDirectory->CompileOptionsBacktraces, - this->Position->BuildSystemDirectory->CompileOptionsBacktraces, this->Position->CompileOptionsPosition); InitializeContentFromParent( parent->BuildSystemDirectory->LinkOptions, this->Position->BuildSystemDirectory->LinkOptions, - parent->BuildSystemDirectory->LinkOptionsBacktraces, - this->Position->BuildSystemDirectory->LinkOptionsBacktraces, this->Position->LinkOptionsPosition); InitializeContentFromParent( parent->BuildSystemDirectory->LinkDirectories, this->Position->BuildSystemDirectory->LinkDirectories, - parent->BuildSystemDirectory->LinkDirectoriesBacktraces, - this->Position->BuildSystemDirectory->LinkDirectoriesBacktraces, this->Position->LinkDirectoriesPosition); - cmProp include_regex = + cmValue include_regex = parent->BuildSystemDirectory->Properties.GetPropertyValue( "INCLUDE_REGULAR_EXPRESSION"); this->Position->BuildSystemDirectory->Properties.SetProperty( - "INCLUDE_REGULAR_EXPRESSION", cmToCStr(include_regex)); + "INCLUDE_REGULAR_EXPRESSION", include_regex); } cmState* cmStateSnapshot::GetState() const diff --git a/Source/cmStateSnapshot.h b/Source/cmStateSnapshot.h index d06cba37a..a61ec8337 100644 --- a/Source/cmStateSnapshot.h +++ b/Source/cmStateSnapshot.h @@ -13,6 +13,7 @@ #include "cmLinkedTree.h" #include "cmPolicies.h" #include "cmStateTypes.h" +#include "cmValue.h" class cmState; class cmStateDirectory; @@ -23,7 +24,7 @@ public: cmStateSnapshot(cmState* state = nullptr); cmStateSnapshot(cmState* state, cmStateDetail::PositionType position); - std::string const* GetDefinition(std::string const& name) const; + cmValue GetDefinition(std::string const& name) const; bool IsInitialized(std::string const& name) const; void SetDefinition(std::string const& name, cm::string_view value); void RemoveDefinition(std::string const& name); diff --git a/Source/cmStringAlgorithms.cxx b/Source/cmStringAlgorithms.cxx index 5bb6e7bc5..1bb680819 100644 --- a/Source/cmStringAlgorithms.cxx +++ b/Source/cmStringAlgorithms.cxx @@ -218,85 +218,6 @@ std::string cmCatViews(std::initializer_list<cm::string_view> views) return result; } -bool cmIsInternallyOn(cm::string_view val) -{ - return (val.size() == 4) && // - (val[0] == 'I' || val[0] == 'i') && // - (val[1] == '_') && // - (val[2] == 'O' || val[2] == 'o') && // - (val[3] == 'N' || val[3] == 'n'); -} - -bool cmIsNOTFOUND(cm::string_view val) -{ - return (val == "NOTFOUND") || cmHasLiteralSuffix(val, "-NOTFOUND"); -} - -bool cmIsOn(cm::string_view val) -{ - switch (val.size()) { - case 1: - return val[0] == '1' || val[0] == 'Y' || val[0] == 'y'; - case 2: - return // - (val[0] == 'O' || val[0] == 'o') && // - (val[1] == 'N' || val[1] == 'n'); - case 3: - return // - (val[0] == 'Y' || val[0] == 'y') && // - (val[1] == 'E' || val[1] == 'e') && // - (val[2] == 'S' || val[2] == 's'); - case 4: - return // - (val[0] == 'T' || val[0] == 't') && // - (val[1] == 'R' || val[1] == 'r') && // - (val[2] == 'U' || val[2] == 'u') && // - (val[3] == 'E' || val[3] == 'e'); - default: - break; - } - - return false; -} - -bool cmIsOff(cm::string_view val) -{ - switch (val.size()) { - case 0: - return true; - case 1: - return val[0] == '0' || val[0] == 'N' || val[0] == 'n'; - case 2: - return // - (val[0] == 'N' || val[0] == 'n') && // - (val[1] == 'O' || val[1] == 'o'); - case 3: - return // - (val[0] == 'O' || val[0] == 'o') && // - (val[1] == 'F' || val[1] == 'f') && // - (val[2] == 'F' || val[2] == 'f'); - case 5: - return // - (val[0] == 'F' || val[0] == 'f') && // - (val[1] == 'A' || val[1] == 'a') && // - (val[2] == 'L' || val[2] == 'l') && // - (val[3] == 'S' || val[3] == 's') && // - (val[4] == 'E' || val[4] == 'e'); - case 6: - return // - (val[0] == 'I' || val[0] == 'i') && // - (val[1] == 'G' || val[1] == 'g') && // - (val[2] == 'N' || val[2] == 'n') && // - (val[3] == 'O' || val[3] == 'o') && // - (val[4] == 'R' || val[4] == 'r') && // - (val[5] == 'E' || val[5] == 'e'); - default: - break; - } - - return cmIsNOTFOUND(val); -} - bool cmStrToLong(const char* str, long* value) { errno = 0; diff --git a/Source/cmStringAlgorithms.h b/Source/cmStringAlgorithms.h index 6b458ec52..492e588bb 100644 --- a/Source/cmStringAlgorithms.h +++ b/Source/cmStringAlgorithms.h @@ -15,24 +15,11 @@ #include <cm/string_view> #include "cmRange.h" +#include "cmValue.h" /** String range type. */ using cmStringRange = cmRange<std::vector<std::string>::const_iterator>; -/** Check for non-empty string. */ -inline bool cmNonempty(const char* str) -{ - return str && *str; -} -inline bool cmNonempty(cm::string_view str) -{ - return !str.empty(); -} -inline bool cmNonempty(std::string const* str) -{ - return str && !str->empty(); -} - /** Returns length of a literal string. */ template <size_t N> constexpr size_t cmStrLen(const char (&/*str*/)[N]) @@ -107,6 +94,13 @@ std::vector<std::string> cmTokenize(cm::string_view str, cm::string_view sep); */ void cmExpandList(cm::string_view arg, std::vector<std::string>& argsOut, bool emptyArgs = false); +inline void cmExpandList(cmValue arg, std::vector<std::string>& argsOut, + bool emptyArgs = false) +{ + if (arg) { + cmExpandList(*arg, argsOut, emptyArgs); + } +} /** * Expand out any arguments in the string range [@a first, @a last) that have @@ -128,6 +122,14 @@ void cmExpandLists(InputIt first, InputIt last, */ std::vector<std::string> cmExpandedList(cm::string_view arg, bool emptyArgs = false); +inline std::vector<std::string> cmExpandedList(cmValue arg, + bool emptyArgs = false) +{ + if (!arg) { + return {}; + } + return cmExpandedList(*arg, emptyArgs); +} /** * Same as cmExpandList but a new vector is created containing the expanded @@ -175,6 +177,10 @@ public: cmAlphaNum(unsigned long long int val); cmAlphaNum(float val); cmAlphaNum(double val); + cmAlphaNum(cmValue value) + : View_(*value) + { + } cm::string_view View() const { return this->View_; } @@ -213,53 +219,6 @@ std::string cmWrap(char prefix, Range const& rng, char suffix, sep); } -/** - * Does a string indicates that CMake/CPack/CTest internally - * forced this value. This is not the same as On, but this - * may be considered as "internally switched on". - */ -bool cmIsInternallyOn(cm::string_view val); -inline bool cmIsInternallyOn(const char* val) -{ - if (!val) { - return false; - } - return cmIsInternallyOn(cm::string_view(val)); -} - -/** Return true if value is NOTFOUND or ends in -NOTFOUND. */ -bool cmIsNOTFOUND(cm::string_view val); - -/** - * Does a string indicate a true or ON value? This is not the same as ifdef. - */ -bool cmIsOn(cm::string_view val); -inline bool cmIsOn(const char* val) -{ - return val && cmIsOn(cm::string_view(val)); -} -inline bool cmIsOn(std::string const* val) -{ - return val && cmIsOn(*val); -} - -/** - * Does a string indicate a false or off value ? Note that this is - * not the same as !IsOn(...) because there are a number of - * ambiguous values such as "/usr/local/bin" a path will result in - * IsON and IsOff both returning false. Note that the special path - * NOTFOUND, *-NOTFOUND or IGNORE will cause IsOff to return true. - */ -bool cmIsOff(cm::string_view val); -inline bool cmIsOff(const char* val) -{ - return !val || cmIsOff(cm::string_view(val)); -} -inline bool cmIsOff(std::string const* val) -{ - return !val || cmIsOff(*val); -} - /** Returns true if string @a str starts with the character @a prefix. */ inline bool cmHasPrefix(cm::string_view str, char prefix) { @@ -273,6 +232,16 @@ inline bool cmHasPrefix(cm::string_view str, cm::string_view prefix) } /** Returns true if string @a str starts with string @a prefix. */ +inline bool cmHasPrefix(cm::string_view str, cmValue prefix) +{ + if (!prefix) { + return false; + } + + return str.compare(0, prefix->size(), *prefix) == 0; +} + +/** Returns true if string @a str starts with string @a prefix. */ template <size_t N> inline bool cmHasLiteralPrefix(cm::string_view str, const char (&prefix)[N]) { @@ -293,6 +262,17 @@ inline bool cmHasSuffix(cm::string_view str, cm::string_view suffix) } /** Returns true if string @a str ends with string @a suffix. */ +inline bool cmHasSuffix(cm::string_view str, cmValue suffix) +{ + if (!suffix) { + return false; + } + + return str.size() >= suffix->size() && + str.compare(str.size() - suffix->size(), suffix->size(), *suffix) == 0; +} + +/** Returns true if string @a str ends with string @a suffix. */ template <size_t N> inline bool cmHasLiteralSuffix(cm::string_view str, const char (&suffix)[N]) { diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx index 5fa309df3..f44fcf7c6 100644 --- a/Source/cmStringCommand.cxx +++ b/Source/cmStringCommand.cxx @@ -31,7 +31,6 @@ #include "cmGeneratorExpression.h" #include "cmMakefile.h" #include "cmMessageType.h" -#include "cmProperty.h" #include "cmRange.h" #include "cmStringAlgorithms.h" #include "cmStringReplaceHelper.h" @@ -39,6 +38,7 @@ #include "cmSystemTools.h" #include "cmTimestamp.h" #include "cmUuid.h" +#include "cmValue.h" namespace { @@ -572,7 +572,7 @@ bool HandlePrependCommand(std::vector<std::string> const& args, const std::string& variable = args[1]; std::string value = cmJoin(cmMakeRange(args).advance(2), std::string()); - cmProp oldValue = status.GetMakefile().GetDefinition(variable); + cmValue oldValue = status.GetMakefile().GetDefinition(variable); if (oldValue) { value += *oldValue; } @@ -1054,7 +1054,7 @@ Json::Value& ResolvePath(Json::Value& json, Args path) } } return *search; -}; +} Json::Value ReadJson(const std::string& jsonstr) { diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 10d2e50a4..75a5a8d87 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -20,10 +20,12 @@ #include <cm3p/uv.h> #include "cmDuration.h" +#include "cmELF.h" #include "cmMessageMetadata.h" #include "cmProcessOutput.h" #include "cmRange.h" #include "cmStringAlgorithms.h" +#include "cmValue.h" #if !defined(CMAKE_BOOTSTRAP) # include <cm3p/archive.h> @@ -46,10 +48,6 @@ # include "cmCryptoHash.h" #endif -#if defined(CMake_USE_ELF_PARSER) -# include "cmELF.h" -#endif - #if defined(CMake_USE_MACH_PARSER) # include "cmMachO.h" #endif @@ -1595,6 +1593,12 @@ bool cmSystemTools::IsPathToFramework(const std::string& path) cmHasLiteralSuffix(path, ".framework")); } +bool cmSystemTools::IsPathToMacOSSharedLibrary(const std::string& path) +{ + return (cmSystemTools::FileIsFullPath(path) && + cmHasLiteralSuffix(path, ".dylib")); +} + bool cmSystemTools::CreateTar(const std::string& outFileName, const std::vector<std::string>& files, cmTarCompression compressType, bool verbose, @@ -1632,7 +1636,10 @@ bool cmSystemTools::CreateTar(const std::string& outFileName, cmArchiveWrite a(fout, compress, format.empty() ? "paxr" : format, compressionLevel); - a.Open(); + if (!a.Open()) { + cmSystemTools::Error(a.GetError()); + return false; + } a.SetMTime(mtime); a.SetVerbose(verbose); bool tarCreatedSuccessfully = true; @@ -2446,14 +2453,12 @@ void cmSystemTools::MakefileColorEcho(int color, const char* message, bool cmSystemTools::GuessLibrarySOName(std::string const& fullPath, std::string& soname) { -// For ELF shared libraries use a real parser to get the correct -// soname. -#if defined(CMake_USE_ELF_PARSER) + // For ELF shared libraries use a real parser to get the correct + // soname. cmELF elf(fullPath.c_str()); if (elf) { return elf.GetSOName(soname); } -#endif // If the file is not a symlink we have no guess for its soname. if (!cmSystemTools::FileIsSymlink(fullPath)) { @@ -2491,7 +2496,6 @@ bool cmSystemTools::GuessLibraryInstallName(std::string const& fullPath, return false; } -#if defined(CMake_USE_ELF_PARSER) || defined(CMake_USE_XCOFF_PARSER) std::string::size_type cmSystemToolsFindRPath(cm::string_view const& have, cm::string_view const& want) { @@ -2523,9 +2527,7 @@ std::string::size_type cmSystemToolsFindRPath(cm::string_view const& have, // The desired rpath was not found. return std::string::npos; } -#endif -#if defined(CMake_USE_ELF_PARSER) namespace { struct cmSystemToolsRPathInfo { @@ -2539,10 +2541,10 @@ using EmptyCallback = std::function<bool(std::string*, const cmELF&)>; using AdjustCallback = std::function<bool( cm::optional<std::string>&, const std::string&, const char*, std::string*)>; -// FIXME: Dispatch if multiple formats are supported. -bool AdjustRPath(std::string const& file, const EmptyCallback& emptyCallback, - const AdjustCallback& adjustCallback, std::string* emsg, - bool* changed) +cm::optional<bool> AdjustRPathELF(std::string const& file, + const EmptyCallback& emptyCallback, + const AdjustCallback& adjustCallback, + std::string* emsg, bool* changed) { if (changed) { *changed = false; @@ -2553,6 +2555,9 @@ bool AdjustRPath(std::string const& file, const EmptyCallback& emptyCallback, { // Parse the ELF binary. cmELF elf(file.c_str()); + if (!elf) { + return cm::nullopt; // Not a valid ELF file. + } // Get the RPATH and RUNPATH entries from it. int se_count = 0; @@ -2686,14 +2691,14 @@ std::function<bool(std::string*, const cmELF&)> MakeEmptyCallback( } return false; }; -}; +} } -bool cmSystemTools::ChangeRPath(std::string const& file, - std::string const& oldRPath, - std::string const& newRPath, - bool removeEnvironmentRPath, std::string* emsg, - bool* changed) +cm::optional<bool> ChangeRPathELF(std::string const& file, + std::string const& oldRPath, + std::string const& newRPath, + bool removeEnvironmentRPath, + std::string* emsg, bool* changed) { auto adjustCallback = [oldRPath, newRPath, removeEnvironmentRPath]( cm::optional<std::string>& outRPath, @@ -2741,13 +2746,13 @@ bool cmSystemTools::ChangeRPath(std::string const& file, return true; }; - return AdjustRPath(file, MakeEmptyCallback(newRPath), adjustCallback, emsg, - changed); + return AdjustRPathELF(file, MakeEmptyCallback(newRPath), adjustCallback, + emsg, changed); } -bool cmSystemTools::SetRPath(std::string const& file, - std::string const& newRPath, std::string* emsg, - bool* changed) +static cm::optional<bool> SetRPathELF(std::string const& file, + std::string const& newRPath, + std::string* emsg, bool* changed) { auto adjustCallback = [newRPath](cm::optional<std::string>& outRPath, const std::string& inRPath, @@ -2759,22 +2764,31 @@ bool cmSystemTools::SetRPath(std::string const& file, return true; }; - return AdjustRPath(file, MakeEmptyCallback(newRPath), adjustCallback, emsg, - changed); + return AdjustRPathELF(file, MakeEmptyCallback(newRPath), adjustCallback, + emsg, changed); } -#elif defined(CMake_USE_XCOFF_PARSER) -bool cmSystemTools::ChangeRPath(std::string const& file, - std::string const& oldRPath, - std::string const& newRPath, - bool removeEnvironmentRPath, std::string* emsg, - bool* changed) +static cm::optional<bool> ChangeRPathXCOFF(std::string const& file, + std::string const& oldRPath, + std::string const& newRPath, + bool removeEnvironmentRPath, + std::string* emsg, bool* changed) { if (changed) { *changed = false; } - +#if !defined(CMake_USE_XCOFF_PARSER) + (void)file; + (void)oldRPath; + (void)newRPath; + (void)removeEnvironmentRPath; + (void)emsg; + return cm::nullopt; +#else bool chg = false; cmXCOFF xcoff(file.c_str(), cmXCOFF::Mode::ReadWrite); + if (!xcoff) { + return cm::nullopt; // Not a valid XCOFF file + } if (cm::optional<cm::string_view> maybeLibPath = xcoff.GetLibPath()) { cm::string_view libPath = *maybeLibPath; // Make sure the current rpath contains the old rpath. @@ -2830,34 +2844,51 @@ bool cmSystemTools::ChangeRPath(std::string const& file, *changed = chg; } return true; +#endif } -bool cmSystemTools::SetRPath(std::string const& /*file*/, - std::string const& /*newRPath*/, - std::string* /*emsg*/, bool* /*changed*/) +static cm::optional<bool> SetRPathXCOFF(std::string const& /*file*/, + std::string const& /*newRPath*/, + std::string* /*emsg*/, + bool* /*changed*/) { - return false; + return cm::nullopt; // Not implemented. } -#else -bool cmSystemTools::ChangeRPath(std::string const& /*file*/, - std::string const& /*oldRPath*/, - std::string const& /*newRPath*/, - bool /*removeEnvironmentRPath*/, - std::string* /*emsg*/, bool* /*changed*/) + +bool cmSystemTools::ChangeRPath(std::string const& file, + std::string const& oldRPath, + std::string const& newRPath, + bool removeEnvironmentRPath, std::string* emsg, + bool* changed) { + if (cm::optional<bool> result = ChangeRPathELF( + file, oldRPath, newRPath, removeEnvironmentRPath, emsg, changed)) { + return result.value(); + } + if (cm::optional<bool> result = ChangeRPathXCOFF( + file, oldRPath, newRPath, removeEnvironmentRPath, emsg, changed)) { + return result.value(); + } return false; } -bool cmSystemTools::SetRPath(std::string const& /*file*/, - std::string const& /*newRPath*/, - std::string* /*emsg*/, bool* /*changed*/) +bool cmSystemTools::SetRPath(std::string const& file, + std::string const& newRPath, std::string* emsg, + bool* changed) { + if (cm::optional<bool> result = SetRPathELF(file, newRPath, emsg, changed)) { + return result.value(); + } + if (cm::optional<bool> result = + SetRPathXCOFF(file, newRPath, emsg, changed)) { + return result.value(); + } return false; } -#endif -bool cmSystemTools::VersionCompare(cmSystemTools::CompareOp op, - const char* lhss, const char* rhss) +namespace { +bool VersionCompare(cmSystemTools::CompareOp op, const char* lhss, + const char* rhss) { const char* endl = lhss; const char* endr = rhss; @@ -2890,26 +2921,37 @@ bool cmSystemTools::VersionCompare(cmSystemTools::CompareOp op, // lhs == rhs, so true if operation is EQUAL return (op & cmSystemTools::OP_EQUAL) != 0; } +} + +bool cmSystemTools::VersionCompare(cmSystemTools::CompareOp op, + const std::string& lhs, + const std::string& rhs) +{ + return ::VersionCompare(op, lhs.c_str(), rhs.c_str()); +} +bool cmSystemTools::VersionCompare(cmSystemTools::CompareOp op, + const std::string& lhs, const char rhs[]) +{ + return ::VersionCompare(op, lhs.c_str(), rhs); +} bool cmSystemTools::VersionCompareEqual(std::string const& lhs, std::string const& rhs) { - return cmSystemTools::VersionCompare(cmSystemTools::OP_EQUAL, lhs.c_str(), - rhs.c_str()); + return cmSystemTools::VersionCompare(cmSystemTools::OP_EQUAL, lhs, rhs); } bool cmSystemTools::VersionCompareGreater(std::string const& lhs, std::string const& rhs) { - return cmSystemTools::VersionCompare(cmSystemTools::OP_GREATER, lhs.c_str(), - rhs.c_str()); + return cmSystemTools::VersionCompare(cmSystemTools::OP_GREATER, lhs, rhs); } bool cmSystemTools::VersionCompareGreaterEq(std::string const& lhs, std::string const& rhs) { - return cmSystemTools::VersionCompare(cmSystemTools::OP_GREATER_EQUAL, - lhs.c_str(), rhs.c_str()); + return cmSystemTools::VersionCompare(cmSystemTools::OP_GREATER_EQUAL, lhs, + rhs); } static size_t cm_strverscmp_find_first_difference_or_end(const char* lhs, @@ -2989,10 +3031,8 @@ int cmSystemTools::strverscmp(std::string const& lhs, std::string const& rhs) return cm_strverscmp(lhs.c_str(), rhs.c_str()); } -// FIXME: Dispatch if multiple formats are supported. -#if defined(CMake_USE_ELF_PARSER) -bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg, - bool* removed) +static cm::optional<bool> RemoveRPathELF(std::string const& file, + std::string* emsg, bool* removed) { if (removed) { *removed = false; @@ -3005,6 +3045,9 @@ bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg, { // Parse the ELF binary. cmELF elf(file.c_str()); + if (!elf) { + return cm::nullopt; // Not a valid ELF file. + } // Get the RPATH and RUNPATH entries from it and sort them by index // in the dynamic section header. @@ -3054,8 +3097,7 @@ bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg, entriesErased++; continue; } - if (cmELF::TagMipsRldMapRel != 0 && - it->first == cmELF::TagMipsRldMapRel) { + if (it->first == cmELF::TagMipsRldMapRel && elf.IsMIPS()) { // Background: debuggers need to know the "linker map" which contains // the addresses each dynamic object is loaded at. Most arches use // the DT_DEBUG tag which the dynamic linker writes to (directly) and @@ -3131,15 +3173,22 @@ bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg, } return true; } -#elif defined(CMake_USE_XCOFF_PARSER) -bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg, - bool* removed) + +static cm::optional<bool> RemoveRPathXCOFF(std::string const& file, + std::string* emsg, bool* removed) { if (removed) { *removed = false; } - +#if !defined(CMake_USE_XCOFF_PARSER) + (void)file; + (void)emsg; + return cm::nullopt; // Cannot handle XCOFF files. +#else cmXCOFF xcoff(file.c_str(), cmXCOFF::Mode::ReadWrite); + if (!xcoff) { + return cm::nullopt; // Not a valid XCOFF file. + } bool rm = xcoff.RemoveLibPath(); if (!xcoff) { if (emsg) { @@ -3152,55 +3201,60 @@ bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg, *removed = rm; } return true; +#endif } -#else -bool cmSystemTools::RemoveRPath(std::string const& /*file*/, - std::string* /*emsg*/, bool* /*removed*/) +bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg, + bool* removed) { + if (cm::optional<bool> result = RemoveRPathELF(file, emsg, removed)) { + return result.value(); + } + if (cm::optional<bool> result = RemoveRPathXCOFF(file, emsg, removed)) { + return result.value(); + } return false; } -#endif -// FIXME: Dispatch if multiple formats are supported. bool cmSystemTools::CheckRPath(std::string const& file, std::string const& newRPath) { -#if defined(CMake_USE_ELF_PARSER) // Parse the ELF binary. cmELF elf(file.c_str()); - - // Get the RPATH or RUNPATH entry from it. - cmELF::StringEntry const* se = elf.GetRPath(); - if (!se) { - se = elf.GetRunPath(); - } - - // Make sure the current rpath contains the new rpath. - if (newRPath.empty()) { + if (elf) { + // Get the RPATH or RUNPATH entry from it. + cmELF::StringEntry const* se = elf.GetRPath(); if (!se) { - return true; + se = elf.GetRunPath(); } - } else { - if (se && - cmSystemToolsFindRPath(se->Value, newRPath) != std::string::npos) { - return true; + + // Make sure the current rpath contains the new rpath. + if (newRPath.empty()) { + if (!se) { + return true; + } + } else { + if (se && + cmSystemToolsFindRPath(se->Value, newRPath) != std::string::npos) { + return true; + } } + return false; } - return false; -#elif defined(CMake_USE_XCOFF_PARSER) +#if defined(CMake_USE_XCOFF_PARSER) // Parse the XCOFF binary. cmXCOFF xcoff(file.c_str()); - if (cm::optional<cm::string_view> libPath = xcoff.GetLibPath()) { - if (cmSystemToolsFindRPath(*libPath, newRPath) != std::string::npos) { - return true; + if (xcoff) { + if (cm::optional<cm::string_view> libPath = xcoff.GetLibPath()) { + if (cmSystemToolsFindRPath(*libPath, newRPath) != std::string::npos) { + return true; + } } + return false; } - return false; -#else +#endif (void)file; (void)newRPath; return false; -#endif } bool cmSystemTools::RepeatedRemoveDirectory(const std::string& dir) diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index 44ccbf7a3..715724c3c 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -102,7 +102,11 @@ public: } //! Return true if the path is a framework - static bool IsPathToFramework(const std::string& value); + static bool IsPathToFramework(const std::string& path); + + //! Return true if the path is a macOS non-framework shared library (aka + //! .dylib) + static bool IsPathToMacOSSharedLibrary(const std::string& path); static bool DoesFileExistWithExtensions( const std::string& name, const std::vector<std::string>& sourceExts); @@ -280,7 +284,10 @@ public: /** * Compare versions */ - static bool VersionCompare(CompareOp op, const char* lhs, const char* rhs); + static bool VersionCompare(CompareOp op, const std::string& lhs, + const std::string& rhs); + static bool VersionCompare(CompareOp op, const std::string& lhs, + const char rhs[]); static bool VersionCompareEqual(std::string const& lhs, std::string const& rhs); static bool VersionCompareGreater(std::string const& lhs, diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 762270051..97d60cf03 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -37,6 +37,7 @@ #include "cmStateSnapshot.h" #include "cmSystemTools.h" #include "cmTargetPropertyComputer.h" +#include "cmValue.h" #include "cmake.h" template <> @@ -79,19 +80,19 @@ const std::string& cmTargetPropertyComputer::ComputeLocation<cmTarget>( } template <> -cmProp cmTargetPropertyComputer::GetSources<cmTarget>( +cmValue cmTargetPropertyComputer::GetSources<cmTarget>( cmTarget const* tgt, cmMessenger* messenger, cmListFileBacktrace const& context) { - cmStringRange entries = tgt->GetSourceEntries(); + cmBTStringRange entries = tgt->GetSourceEntries(); if (entries.empty()) { return nullptr; } std::ostringstream ss; const char* sep = ""; - for (std::string const& entry : entries) { - std::vector<std::string> files = cmExpandedList(entry); + for (auto const& entry : entries) { + std::vector<std::string> files = cmExpandedList(entry.Value); for (std::string const& file : files) { if (cmHasLiteralPrefix(file, "$<TARGET_OBJECTS:") && file.back() == '>') { @@ -112,12 +113,14 @@ cmProp cmTargetPropertyComputer::GetSources<cmTarget>( case cmPolicies::WARN: e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0051) << "\n"; noMessage = false; + CM_FALLTHROUGH; case cmPolicies::OLD: break; case cmPolicies::REQUIRED_ALWAYS: case cmPolicies::REQUIRED_IF_USED: case cmPolicies::NEW: addContent = true; + break; } if (!noMessage) { e << "Target \"" << tgt->GetName() @@ -157,7 +160,7 @@ cmProp cmTargetPropertyComputer::GetSources<cmTarget>( } static std::string srcs; srcs = ss.str(); - return &srcs; + return cmValue(srcs); } class cmTargetInternals @@ -187,24 +190,16 @@ public: std::set<std::string> SystemIncludeDirectories; cmTarget::LinkLibraryVectorType OriginalLinkLibraries; std::map<std::string, BTs<std::string>> LanguageStandardProperties; - std::vector<std::string> IncludeDirectoriesEntries; - std::vector<cmListFileBacktrace> IncludeDirectoriesBacktraces; - std::vector<std::string> CompileOptionsEntries; - std::vector<cmListFileBacktrace> CompileOptionsBacktraces; - std::vector<std::string> CompileFeaturesEntries; - std::vector<cmListFileBacktrace> CompileFeaturesBacktraces; - std::vector<std::string> CompileDefinitionsEntries; - std::vector<cmListFileBacktrace> CompileDefinitionsBacktraces; - std::vector<std::string> PrecompileHeadersEntries; - std::vector<cmListFileBacktrace> PrecompileHeadersBacktraces; - std::vector<std::string> SourceEntries; - std::vector<cmListFileBacktrace> SourceBacktraces; - std::vector<std::string> LinkOptionsEntries; - std::vector<cmListFileBacktrace> LinkOptionsBacktraces; - std::vector<std::string> LinkDirectoriesEntries; - std::vector<cmListFileBacktrace> LinkDirectoriesBacktraces; - std::vector<std::string> LinkImplementationPropertyEntries; - std::vector<cmListFileBacktrace> LinkImplementationPropertyBacktraces; + std::vector<BT<std::string>> IncludeDirectoriesEntries; + std::vector<std::string> InstallIncludeDirectoriesEntries; + std::vector<BT<std::string>> CompileOptionsEntries; + std::vector<BT<std::string>> CompileFeaturesEntries; + std::vector<BT<std::string>> CompileDefinitionsEntries; + std::vector<BT<std::string>> PrecompileHeadersEntries; + std::vector<BT<std::string>> SourceEntries; + std::vector<BT<std::string>> LinkOptionsEntries; + std::vector<BT<std::string>> LinkDirectoriesEntries; + std::vector<BT<std::string>> LinkImplementationPropertyEntries; std::vector<std::pair<cmTarget::TLLSignature, cmListFileContext>> TLLCommands; cmListFileBacktrace Backtrace; @@ -265,16 +260,16 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, auto initProp = [this, mf, &defKey](const std::string& property) { // Replace everything after "CMAKE_" defKey.replace(defKey.begin() + 6, defKey.end(), property); - if (cmProp value = mf->GetDefinition(defKey)) { - this->SetProperty(property, *value); + if (cmValue value = mf->GetDefinition(defKey)) { + this->SetProperty(property, value); } }; auto initPropValue = [this, mf, &defKey](const std::string& property, const char* default_value) { // Replace everything after "CMAKE_" defKey.replace(defKey.begin() + 6, defKey.end(), property); - if (cmProp value = mf->GetDefinition(defKey)) { - this->SetProperty(property, *value); + if (cmValue value = mf->GetDefinition(defKey)) { + this->SetProperty(property, value); } else if (default_value) { this->SetProperty(property, default_value); } @@ -481,8 +476,6 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, // of the same directory property: cm::append(this->impl->IncludeDirectoriesEntries, this->impl->Makefile->GetIncludeDirectoriesEntries()); - cm::append(this->impl->IncludeDirectoriesBacktraces, - this->impl->Makefile->GetIncludeDirectoriesBacktraces()); { auto const& sysInc = this->impl->Makefile->GetSystemIncludeDirectories(); @@ -492,18 +485,12 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, cm::append(this->impl->CompileOptionsEntries, this->impl->Makefile->GetCompileOptionsEntries()); - cm::append(this->impl->CompileOptionsBacktraces, - this->impl->Makefile->GetCompileOptionsBacktraces()); cm::append(this->impl->LinkOptionsEntries, this->impl->Makefile->GetLinkOptionsEntries()); - cm::append(this->impl->LinkOptionsBacktraces, - this->impl->Makefile->GetLinkOptionsBacktraces()); cm::append(this->impl->LinkDirectoriesEntries, this->impl->Makefile->GetLinkDirectoriesEntries()); - cm::append(this->impl->LinkDirectoriesBacktraces, - this->impl->Makefile->GetLinkDirectoriesBacktraces()); } if (this->impl->TargetType == cmStateEnums::EXECUTABLE) { @@ -541,7 +528,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, // check for "CMAKE_VS_GLOBALS" variable and set up target properties // if any - cmProp globals = mf->GetDefinition("CMAKE_VS_GLOBALS"); + cmValue globals = mf->GetDefinition("CMAKE_VS_GLOBALS"); if (globals) { const std::string genName = mf->GetGlobalGenerator()->GetName(); if (cmHasLiteralPrefix(genName, "Visual Studio")) { @@ -612,11 +599,9 @@ void cmTarget::SetLanguageStandardProperty(std::string const& lang, const std::string& feature) { cmListFileBacktrace featureBacktrace; - for (size_t i = 0; i < this->impl->CompileFeaturesEntries.size(); i++) { - if (this->impl->CompileFeaturesEntries[i] == feature) { - if (i < this->impl->CompileFeaturesBacktraces.size()) { - featureBacktrace = this->impl->CompileFeaturesBacktraces[i]; - } + for (auto const& entry : this->impl->CompileFeaturesEntries) { + if (entry.Value == feature) { + featureBacktrace = entry.Backtrace; break; } } @@ -728,8 +713,7 @@ void cmTarget::AddTracedSources(std::vector<std::string> const& srcs) { if (!srcs.empty()) { cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); - this->impl->SourceEntries.push_back(cmJoin(srcs, ";")); - this->impl->SourceBacktraces.push_back(lfbt); + this->impl->SourceEntries.emplace_back(cmJoin(srcs, ";"), lfbt); } } @@ -753,8 +737,7 @@ void cmTarget::AddSources(std::vector<std::string> const& srcs) } if (!srcFiles.empty()) { cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); - this->impl->SourceEntries.push_back(std::move(srcFiles)); - this->impl->SourceBacktraces.push_back(lfbt); + this->impl->SourceEntries.emplace_back(std::move(srcFiles), lfbt); } } @@ -842,9 +825,9 @@ public: { } - bool operator()(std::string const& entry) + bool operator()(BT<std::string> const& entry) { - std::vector<std::string> files = cmExpandedList(entry); + std::vector<std::string> files = cmExpandedList(entry.Value); std::vector<cmSourceFileLocation> locations; locations.reserve(files.size()); std::transform(files.begin(), files.end(), std::back_inserter(locations), @@ -865,11 +848,7 @@ cmSourceFile* cmTarget::AddSource(const std::string& src, bool before) cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); this->impl->SourceEntries.insert(before ? this->impl->SourceEntries.begin() : this->impl->SourceEntries.end(), - src); - this->impl->SourceBacktraces.insert( - before ? this->impl->SourceBacktraces.begin() - : this->impl->SourceBacktraces.end(), - lfbt); + BT<std::string>(src, lfbt)); } if (cmGeneratorExpression::Find(src) != std::string::npos) { return nullptr; @@ -1042,7 +1021,7 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf, std::string const& lib, this->GetPolicyStatusCMP0073() == cmPolicies::WARN)) { std::string targetEntry = cmStrCat(this->impl->Name, "_LIB_DEPENDS"); std::string dependencies; - cmProp old_val = mf.GetDefinition(targetEntry); + cmValue old_val = mf.GetDefinition(targetEntry); if (old_val) { dependencies += *old_val; } @@ -1075,122 +1054,115 @@ std::set<std::string> const& cmTarget::GetSystemIncludeDirectories() const return this->impl->SystemIncludeDirectories; } -cmStringRange cmTarget::GetIncludeDirectoriesEntries() const +void cmTarget::AddInstallIncludeDirectories(cmStringRange const& incs) { - return cmMakeRange(this->impl->IncludeDirectoriesEntries); + std::copy(incs.begin(), incs.end(), + std::back_inserter(this->impl->InstallIncludeDirectoriesEntries)); } -cmBacktraceRange cmTarget::GetIncludeDirectoriesBacktraces() const +cmStringRange cmTarget::GetInstallIncludeDirectoriesEntries() const { - return cmMakeRange(this->impl->IncludeDirectoriesBacktraces); + return cmMakeRange(this->impl->InstallIncludeDirectoriesEntries); } -cmStringRange cmTarget::GetCompileOptionsEntries() const +cmBTStringRange cmTarget::GetIncludeDirectoriesEntries() const { - return cmMakeRange(this->impl->CompileOptionsEntries); + return cmMakeRange(this->impl->IncludeDirectoriesEntries); } -cmBacktraceRange cmTarget::GetCompileOptionsBacktraces() const +cmBTStringRange cmTarget::GetCompileOptionsEntries() const { - return cmMakeRange(this->impl->CompileOptionsBacktraces); + return cmMakeRange(this->impl->CompileOptionsEntries); } -cmStringRange cmTarget::GetCompileFeaturesEntries() const +cmBTStringRange cmTarget::GetCompileFeaturesEntries() const { return cmMakeRange(this->impl->CompileFeaturesEntries); } -cmBacktraceRange cmTarget::GetCompileFeaturesBacktraces() const -{ - return cmMakeRange(this->impl->CompileFeaturesBacktraces); -} - -cmStringRange cmTarget::GetCompileDefinitionsEntries() const +cmBTStringRange cmTarget::GetCompileDefinitionsEntries() const { return cmMakeRange(this->impl->CompileDefinitionsEntries); } -cmBacktraceRange cmTarget::GetCompileDefinitionsBacktraces() const -{ - return cmMakeRange(this->impl->CompileDefinitionsBacktraces); -} - -cmStringRange cmTarget::GetPrecompileHeadersEntries() const +cmBTStringRange cmTarget::GetPrecompileHeadersEntries() const { return cmMakeRange(this->impl->PrecompileHeadersEntries); } -cmBacktraceRange cmTarget::GetPrecompileHeadersBacktraces() const -{ - return cmMakeRange(this->impl->PrecompileHeadersBacktraces); -} - -cmStringRange cmTarget::GetSourceEntries() const +cmBTStringRange cmTarget::GetSourceEntries() const { return cmMakeRange(this->impl->SourceEntries); } -cmBacktraceRange cmTarget::GetSourceBacktraces() const -{ - return cmMakeRange(this->impl->SourceBacktraces); -} - -cmStringRange cmTarget::GetLinkOptionsEntries() const +cmBTStringRange cmTarget::GetLinkOptionsEntries() const { return cmMakeRange(this->impl->LinkOptionsEntries); } -cmBacktraceRange cmTarget::GetLinkOptionsBacktraces() const +cmBTStringRange cmTarget::GetLinkDirectoriesEntries() const { - return cmMakeRange(this->impl->LinkOptionsBacktraces); + return cmMakeRange(this->impl->LinkDirectoriesEntries); } -cmStringRange cmTarget::GetLinkDirectoriesEntries() const +cmBTStringRange cmTarget::GetLinkImplementationEntries() const { - return cmMakeRange(this->impl->LinkDirectoriesEntries); + return cmMakeRange(this->impl->LinkImplementationPropertyEntries); } -cmBacktraceRange cmTarget::GetLinkDirectoriesBacktraces() const -{ - return cmMakeRange(this->impl->LinkDirectoriesBacktraces); +namespace { +#define MAKE_PROP(PROP) const std::string prop##PROP = #PROP +MAKE_PROP(C_STANDARD); +MAKE_PROP(CXX_STANDARD); +MAKE_PROP(CUDA_STANDARD); +MAKE_PROP(HIP_STANDARD); +MAKE_PROP(OBJC_STANDARD); +MAKE_PROP(OBJCXX_STANDARD); +MAKE_PROP(COMPILE_DEFINITIONS); +MAKE_PROP(COMPILE_FEATURES); +MAKE_PROP(COMPILE_OPTIONS); +MAKE_PROP(PRECOMPILE_HEADERS); +MAKE_PROP(PRECOMPILE_HEADERS_REUSE_FROM); +MAKE_PROP(CUDA_PTX_COMPILATION); +MAKE_PROP(EXPORT_NAME); +MAKE_PROP(IMPORTED); +MAKE_PROP(IMPORTED_GLOBAL); +MAKE_PROP(INCLUDE_DIRECTORIES); +MAKE_PROP(LINK_OPTIONS); +MAKE_PROP(LINK_DIRECTORIES); +MAKE_PROP(LINK_LIBRARIES); +MAKE_PROP(MANUALLY_ADDED_DEPENDENCIES); +MAKE_PROP(NAME); +MAKE_PROP(SOURCES); +MAKE_PROP(TYPE); +MAKE_PROP(BINARY_DIR); +MAKE_PROP(SOURCE_DIR); +MAKE_PROP(FALSE); +MAKE_PROP(TRUE); +#undef MAKE_PROP } -cmStringRange cmTarget::GetLinkImplementationEntries() const +namespace { +// to workaround bug on GCC/AIX +// Define a template to force conversion to std::string +template <typename ValueType> +std::string ConvertToString(ValueType value); + +template <> +std::string ConvertToString<const char*>(const char* value) { - return cmMakeRange(this->impl->LinkImplementationPropertyEntries); + return std::string(value); } - -cmBacktraceRange cmTarget::GetLinkImplementationBacktraces() const +template <> +std::string ConvertToString<cmValue>(cmValue value) { - return cmMakeRange(this->impl->LinkImplementationPropertyBacktraces); + return std::string(*value); +} } -void cmTarget::SetProperty(const std::string& prop, const char* value) +template <typename ValueType> +void cmTarget::StoreProperty(const std::string& prop, ValueType value) { -#define MAKE_STATIC_PROP(PROP) static const std::string prop##PROP = #PROP - MAKE_STATIC_PROP(C_STANDARD); - MAKE_STATIC_PROP(CXX_STANDARD); - MAKE_STATIC_PROP(CUDA_STANDARD); - MAKE_STATIC_PROP(HIP_STANDARD); - MAKE_STATIC_PROP(OBJC_STANDARD); - MAKE_STATIC_PROP(OBJCXX_STANDARD); - MAKE_STATIC_PROP(COMPILE_DEFINITIONS); - MAKE_STATIC_PROP(COMPILE_FEATURES); - MAKE_STATIC_PROP(COMPILE_OPTIONS); - MAKE_STATIC_PROP(PRECOMPILE_HEADERS); - MAKE_STATIC_PROP(PRECOMPILE_HEADERS_REUSE_FROM); - MAKE_STATIC_PROP(CUDA_PTX_COMPILATION); - MAKE_STATIC_PROP(EXPORT_NAME); - MAKE_STATIC_PROP(IMPORTED_GLOBAL); - MAKE_STATIC_PROP(INCLUDE_DIRECTORIES); - MAKE_STATIC_PROP(LINK_OPTIONS); - MAKE_STATIC_PROP(LINK_DIRECTORIES); - MAKE_STATIC_PROP(LINK_LIBRARIES); - MAKE_STATIC_PROP(MANUALLY_ADDED_DEPENDENCIES); - MAKE_STATIC_PROP(NAME); - MAKE_STATIC_PROP(SOURCES); - MAKE_STATIC_PROP(TYPE); -#undef MAKE_STATIC_PROP if (prop == propMANUALLY_ADDED_DEPENDENCIES) { this->impl->Makefile->IssueMessage( MessageType::FATAL_ERROR, @@ -1231,75 +1203,57 @@ void cmTarget::SetProperty(const std::string& prop, const char* value) if (prop == propINCLUDE_DIRECTORIES) { this->impl->IncludeDirectoriesEntries.clear(); - this->impl->IncludeDirectoriesBacktraces.clear(); if (value) { - this->impl->IncludeDirectoriesEntries.emplace_back(value); cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); - this->impl->IncludeDirectoriesBacktraces.push_back(lfbt); + this->impl->IncludeDirectoriesEntries.emplace_back(value, lfbt); } } else if (prop == propCOMPILE_OPTIONS) { this->impl->CompileOptionsEntries.clear(); - this->impl->CompileOptionsBacktraces.clear(); if (value) { - this->impl->CompileOptionsEntries.emplace_back(value); cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); - this->impl->CompileOptionsBacktraces.push_back(lfbt); + this->impl->CompileOptionsEntries.emplace_back(value, lfbt); } } else if (prop == propCOMPILE_FEATURES) { this->impl->CompileFeaturesEntries.clear(); - this->impl->CompileFeaturesBacktraces.clear(); if (value) { - this->impl->CompileFeaturesEntries.emplace_back(value); cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); - this->impl->CompileFeaturesBacktraces.push_back(lfbt); + this->impl->CompileFeaturesEntries.emplace_back(value, lfbt); } } else if (prop == propCOMPILE_DEFINITIONS) { this->impl->CompileDefinitionsEntries.clear(); - this->impl->CompileDefinitionsBacktraces.clear(); if (value) { - this->impl->CompileDefinitionsEntries.emplace_back(value); cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); - this->impl->CompileDefinitionsBacktraces.push_back(lfbt); + this->impl->CompileDefinitionsEntries.emplace_back(value, lfbt); } } else if (prop == propLINK_OPTIONS) { this->impl->LinkOptionsEntries.clear(); - this->impl->LinkOptionsBacktraces.clear(); if (value) { - this->impl->LinkOptionsEntries.emplace_back(value); cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); - this->impl->LinkOptionsBacktraces.push_back(lfbt); + this->impl->LinkOptionsEntries.emplace_back(value, lfbt); } } else if (prop == propLINK_DIRECTORIES) { this->impl->LinkDirectoriesEntries.clear(); - this->impl->LinkDirectoriesBacktraces.clear(); if (value) { - this->impl->LinkDirectoriesEntries.emplace_back(value); cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); - this->impl->LinkDirectoriesBacktraces.push_back(lfbt); + this->impl->LinkDirectoriesEntries.emplace_back(value, lfbt); } } else if (prop == propPRECOMPILE_HEADERS) { this->impl->PrecompileHeadersEntries.clear(); - this->impl->PrecompileHeadersBacktraces.clear(); if (value) { - this->impl->PrecompileHeadersEntries.emplace_back(value); cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); - this->impl->PrecompileHeadersBacktraces.push_back(lfbt); + this->impl->PrecompileHeadersEntries.emplace_back(value, lfbt); } } else if (prop == propLINK_LIBRARIES) { this->impl->LinkImplementationPropertyEntries.clear(); - this->impl->LinkImplementationPropertyBacktraces.clear(); if (value) { cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); - this->impl->LinkImplementationPropertyEntries.emplace_back(value); - this->impl->LinkImplementationPropertyBacktraces.push_back(lfbt); + this->impl->LinkImplementationPropertyEntries.emplace_back(value, lfbt); } } else if (prop == propSOURCES) { this->impl->SourceEntries.clear(); - this->impl->SourceBacktraces.clear(); if (value) { cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); - this->impl->SourceEntries.emplace_back(value); - this->impl->SourceBacktraces.push_back(lfbt); + this->impl->SourceEntries.emplace_back(value, lfbt); } } else if (prop == propIMPORTED_GLOBAL) { if (!cmIsOn(value)) { @@ -1315,7 +1269,8 @@ void cmTarget::SetProperty(const std::string& prop, const char* value) this->GetGlobalGenerator()->IndexTarget(this); } } else if (cmHasLiteralPrefix(prop, "IMPORTED_LIBNAME") && - !this->impl->CheckImportedLibName(prop, value ? value : "")) { + !this->impl->CheckImportedLibName( + prop, value ? value : std::string{})) { /* error was reported by check method */ } else if (prop == propCUDA_PTX_COMPILATION && this->GetType() != cmStateEnums::OBJECT_LIBRARY) { @@ -1345,17 +1300,17 @@ void cmTarget::SetProperty(const std::string& prop, const char* value) std::string reusedFrom = reusedTarget->GetSafeProperty(prop); if (reusedFrom.empty()) { - reusedFrom = value; + reusedFrom = ConvertToString(value); } - this->impl->Properties.SetProperty(prop, reusedFrom.c_str()); + this->impl->Properties.SetProperty(prop, reusedFrom); reusedTarget->SetProperty("COMPILE_PDB_NAME", reusedFrom); reusedTarget->SetProperty("COMPILE_PDB_OUTPUT_DIRECTORY", cmStrCat(reusedFrom, ".dir/")); - cmProp tmp = reusedTarget->GetProperty("COMPILE_PDB_NAME"); - this->SetProperty("COMPILE_PDB_NAME", cmToCStr(tmp)); + cmValue tmp = reusedTarget->GetProperty("COMPILE_PDB_NAME"); + this->SetProperty("COMPILE_PDB_NAME", tmp); this->AddUtility(reusedFrom, false, this->impl->Makefile); } else if (prop == propC_STANDARD || prop == propCXX_STANDARD || prop == propCUDA_STANDARD || prop == propHIP_STANDARD || @@ -1403,39 +1358,33 @@ void cmTarget::AppendProperty(const std::string& prop, } if (prop == "INCLUDE_DIRECTORIES") { if (!value.empty()) { - this->impl->IncludeDirectoriesEntries.emplace_back(value); cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); - this->impl->IncludeDirectoriesBacktraces.push_back(lfbt); + this->impl->IncludeDirectoriesEntries.emplace_back(value, lfbt); } } else if (prop == "COMPILE_OPTIONS") { if (!value.empty()) { - this->impl->CompileOptionsEntries.emplace_back(value); cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); - this->impl->CompileOptionsBacktraces.push_back(lfbt); + this->impl->CompileOptionsEntries.emplace_back(value, lfbt); } } else if (prop == "COMPILE_FEATURES") { if (!value.empty()) { - this->impl->CompileFeaturesEntries.emplace_back(value); cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); - this->impl->CompileFeaturesBacktraces.push_back(lfbt); + this->impl->CompileFeaturesEntries.emplace_back(value, lfbt); } } else if (prop == "COMPILE_DEFINITIONS") { if (!value.empty()) { - this->impl->CompileDefinitionsEntries.emplace_back(value); cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); - this->impl->CompileDefinitionsBacktraces.push_back(lfbt); + this->impl->CompileDefinitionsEntries.emplace_back(value, lfbt); } } else if (prop == "LINK_OPTIONS") { if (!value.empty()) { - this->impl->LinkOptionsEntries.emplace_back(value); cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); - this->impl->LinkOptionsBacktraces.push_back(lfbt); + this->impl->LinkOptionsEntries.emplace_back(value, lfbt); } } else if (prop == "LINK_DIRECTORIES") { if (!value.empty()) { - this->impl->LinkDirectoriesEntries.emplace_back(value); cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); - this->impl->LinkDirectoriesBacktraces.push_back(lfbt); + this->impl->LinkDirectoriesEntries.emplace_back(value, lfbt); } } else if (prop == "PRECOMPILE_HEADERS") { if (this->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM")) { @@ -1447,20 +1396,17 @@ void cmTarget::AppendProperty(const std::string& prop, return; } if (!value.empty()) { - this->impl->PrecompileHeadersEntries.emplace_back(value); cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); - this->impl->PrecompileHeadersBacktraces.push_back(lfbt); + this->impl->PrecompileHeadersEntries.emplace_back(value, lfbt); } } else if (prop == "LINK_LIBRARIES") { if (!value.empty()) { cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); - this->impl->LinkImplementationPropertyEntries.emplace_back(value); - this->impl->LinkImplementationPropertyBacktraces.push_back(lfbt); + this->impl->LinkImplementationPropertyEntries.emplace_back(value, lfbt); } } else if (prop == "SOURCES") { cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); - this->impl->SourceEntries.emplace_back(value); - this->impl->SourceBacktraces.push_back(lfbt); + this->impl->SourceEntries.emplace_back(value, lfbt); } else if (cmHasLiteralPrefix(prop, "IMPORTED_LIBNAME")) { this->impl->Makefile->IssueMessage( MessageType::FATAL_ERROR, prop + " property may not be APPENDed."); @@ -1474,6 +1420,15 @@ void cmTarget::AppendProperty(const std::string& prop, } } +void cmTarget::SetProperty(const std::string& prop, const char* value) +{ + this->StoreProperty(prop, value); +} +void cmTarget::SetProperty(const std::string& prop, cmValue value) +{ + this->StoreProperty(prop, value); +} + void cmTarget::AppendBuildInterfaceIncludes() { if (this->GetType() != cmStateEnums::SHARED_LIBRARY && @@ -1501,70 +1456,46 @@ void cmTarget::AppendBuildInterfaceIncludes() } } -void cmTarget::InsertInclude(std::string const& entry, - cmListFileBacktrace const& bt, bool before) +void cmTarget::InsertInclude(BT<std::string> const& entry, bool before) { auto position = before ? this->impl->IncludeDirectoriesEntries.begin() : this->impl->IncludeDirectoriesEntries.end(); - auto btPosition = before ? this->impl->IncludeDirectoriesBacktraces.begin() - : this->impl->IncludeDirectoriesBacktraces.end(); - this->impl->IncludeDirectoriesEntries.insert(position, entry); - this->impl->IncludeDirectoriesBacktraces.insert(btPosition, bt); } -void cmTarget::InsertCompileOption(std::string const& entry, - cmListFileBacktrace const& bt, bool before) +void cmTarget::InsertCompileOption(BT<std::string> const& entry, bool before) { auto position = before ? this->impl->CompileOptionsEntries.begin() : this->impl->CompileOptionsEntries.end(); - auto btPosition = before ? this->impl->CompileOptionsBacktraces.begin() - : this->impl->CompileOptionsBacktraces.end(); - this->impl->CompileOptionsEntries.insert(position, entry); - this->impl->CompileOptionsBacktraces.insert(btPosition, bt); } -void cmTarget::InsertCompileDefinition(std::string const& entry, - cmListFileBacktrace const& bt) +void cmTarget::InsertCompileDefinition(BT<std::string> const& entry) { this->impl->CompileDefinitionsEntries.push_back(entry); - this->impl->CompileDefinitionsBacktraces.push_back(bt); } -void cmTarget::InsertLinkOption(std::string const& entry, - cmListFileBacktrace const& bt, bool before) +void cmTarget::InsertLinkOption(BT<std::string> const& entry, bool before) { auto position = before ? this->impl->LinkOptionsEntries.begin() : this->impl->LinkOptionsEntries.end(); - auto btPosition = before ? this->impl->LinkOptionsBacktraces.begin() - : this->impl->LinkOptionsBacktraces.end(); - this->impl->LinkOptionsEntries.insert(position, entry); - this->impl->LinkOptionsBacktraces.insert(btPosition, bt); } -void cmTarget::InsertLinkDirectory(std::string const& entry, - cmListFileBacktrace const& bt, bool before) +void cmTarget::InsertLinkDirectory(BT<std::string> const& entry, bool before) { auto position = before ? this->impl->LinkDirectoriesEntries.begin() : this->impl->LinkDirectoriesEntries.end(); - auto btPosition = before ? this->impl->LinkDirectoriesBacktraces.begin() - : this->impl->LinkDirectoriesBacktraces.end(); - this->impl->LinkDirectoriesEntries.insert(position, entry); - this->impl->LinkDirectoriesBacktraces.insert(btPosition, bt); } -void cmTarget::InsertPrecompileHeader(std::string const& entry, - cmListFileBacktrace const& bt) +void cmTarget::InsertPrecompileHeader(BT<std::string> const& entry) { this->impl->PrecompileHeadersEntries.push_back(entry); - this->impl->PrecompileHeadersBacktraces.push_back(bt); } static void cmTargetCheckLINK_INTERFACE_LIBRARIES(const std::string& prop, @@ -1651,17 +1582,17 @@ void cmTarget::CheckProperty(const std::string& prop, { // Certain properties need checking. if (cmHasLiteralPrefix(prop, "LINK_INTERFACE_LIBRARIES")) { - if (cmProp value = this->GetProperty(prop)) { + if (cmValue value = this->GetProperty(prop)) { cmTargetCheckLINK_INTERFACE_LIBRARIES(prop, *value, context, false); } } if (cmHasLiteralPrefix(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES")) { - if (cmProp value = this->GetProperty(prop)) { + if (cmValue value = this->GetProperty(prop)) { cmTargetCheckLINK_INTERFACE_LIBRARIES(prop, *value, context, true); } } if (prop == "INTERFACE_LINK_LIBRARIES") { - if (cmProp value = this->GetProperty(prop)) { + if (cmValue value = this->GetProperty(prop)) { cmTargetCheckINTERFACE_LINK_LIBRARIES(*value, context); } } @@ -1672,40 +1603,15 @@ void cmTarget::CheckProperty(const std::string& prop, } } -cmProp cmTarget::GetComputedProperty(const std::string& prop, - cmMessenger* messenger, - cmListFileBacktrace const& context) const +cmValue cmTarget::GetComputedProperty(const std::string& prop, + cmMessenger* messenger, + cmListFileBacktrace const& context) const { return cmTargetPropertyComputer::GetProperty(this, prop, messenger, context); } -cmProp cmTarget::GetProperty(const std::string& prop) const -{ -#define MAKE_STATIC_PROP(PROP) static const std::string prop##PROP = #PROP - MAKE_STATIC_PROP(C_STANDARD); - MAKE_STATIC_PROP(CXX_STANDARD); - MAKE_STATIC_PROP(CUDA_STANDARD); - MAKE_STATIC_PROP(OBJC_STANDARD); - MAKE_STATIC_PROP(OBJCXX_STANDARD); - MAKE_STATIC_PROP(LINK_LIBRARIES); - MAKE_STATIC_PROP(TYPE); - MAKE_STATIC_PROP(INCLUDE_DIRECTORIES); - MAKE_STATIC_PROP(COMPILE_FEATURES); - MAKE_STATIC_PROP(COMPILE_OPTIONS); - MAKE_STATIC_PROP(COMPILE_DEFINITIONS); - MAKE_STATIC_PROP(LINK_OPTIONS); - MAKE_STATIC_PROP(LINK_DIRECTORIES); - MAKE_STATIC_PROP(PRECOMPILE_HEADERS); - MAKE_STATIC_PROP(IMPORTED); - MAKE_STATIC_PROP(IMPORTED_GLOBAL); - MAKE_STATIC_PROP(MANUALLY_ADDED_DEPENDENCIES); - MAKE_STATIC_PROP(NAME); - MAKE_STATIC_PROP(BINARY_DIR); - MAKE_STATIC_PROP(SOURCE_DIR); - MAKE_STATIC_PROP(SOURCES); - MAKE_STATIC_PROP(FALSE); - MAKE_STATIC_PROP(TRUE); -#undef MAKE_STATIC_PROP +cmValue cmTarget::GetProperty(const std::string& prop) const +{ static std::unordered_set<std::string> const specialProps{ propC_STANDARD, propCXX_STANDARD, @@ -1737,7 +1643,7 @@ cmProp cmTarget::GetProperty(const std::string& prop) const if (propertyIter == this->impl->LanguageStandardProperties.end()) { return nullptr; } - return &(propertyIter->second.Value); + return cmValue(propertyIter->second.Value); } if (prop == propLINK_LIBRARIES) { if (this->impl->LinkImplementationPropertyEntries.empty()) { @@ -1746,11 +1652,11 @@ cmProp cmTarget::GetProperty(const std::string& prop) const static std::string output; output = cmJoin(this->impl->LinkImplementationPropertyEntries, ";"); - return &output; + return cmValue(output); } // the type property returns what type the target is if (prop == propTYPE) { - return &cmState::GetTargetTypeName(this->GetType()); + return cmValue(cmState::GetTargetTypeName(this->GetType())); } if (prop == propINCLUDE_DIRECTORIES) { if (this->impl->IncludeDirectoriesEntries.empty()) { @@ -1759,7 +1665,7 @@ cmProp cmTarget::GetProperty(const std::string& prop) const static std::string output; output = cmJoin(this->impl->IncludeDirectoriesEntries, ";"); - return &output; + return cmValue(output); } if (prop == propCOMPILE_FEATURES) { if (this->impl->CompileFeaturesEntries.empty()) { @@ -1768,7 +1674,7 @@ cmProp cmTarget::GetProperty(const std::string& prop) const static std::string output; output = cmJoin(this->impl->CompileFeaturesEntries, ";"); - return &output; + return cmValue(output); } if (prop == propCOMPILE_OPTIONS) { if (this->impl->CompileOptionsEntries.empty()) { @@ -1777,7 +1683,7 @@ cmProp cmTarget::GetProperty(const std::string& prop) const static std::string output; output = cmJoin(this->impl->CompileOptionsEntries, ";"); - return &output; + return cmValue(output); } if (prop == propCOMPILE_DEFINITIONS) { if (this->impl->CompileDefinitionsEntries.empty()) { @@ -1786,7 +1692,7 @@ cmProp cmTarget::GetProperty(const std::string& prop) const static std::string output; output = cmJoin(this->impl->CompileDefinitionsEntries, ";"); - return &output; + return cmValue(output); } if (prop == propLINK_OPTIONS) { if (this->impl->LinkOptionsEntries.empty()) { @@ -1795,7 +1701,7 @@ cmProp cmTarget::GetProperty(const std::string& prop) const static std::string output; output = cmJoin(this->impl->LinkOptionsEntries, ";"); - return &output; + return cmValue(output); } if (prop == propLINK_DIRECTORIES) { if (this->impl->LinkDirectoriesEntries.empty()) { @@ -1805,7 +1711,7 @@ cmProp cmTarget::GetProperty(const std::string& prop) const static std::string output; output = cmJoin(this->impl->LinkDirectoriesEntries, ";"); - return &output; + return cmValue(output); } if (prop == propMANUALLY_ADDED_DEPENDENCIES) { if (this->impl->Utilities.empty()) { @@ -1822,7 +1728,7 @@ cmProp cmTarget::GetProperty(const std::string& prop) const return item.Value.first; }); output = cmJoin(utilities, ";"); - return &output; + return cmValue(output); } if (prop == propPRECOMPILE_HEADERS) { if (this->impl->PrecompileHeadersEntries.empty()) { @@ -1831,30 +1737,31 @@ cmProp cmTarget::GetProperty(const std::string& prop) const static std::string output; output = cmJoin(this->impl->PrecompileHeadersEntries, ";"); - return &output; + return cmValue(output); } if (prop == propIMPORTED) { - return this->IsImported() ? &propTRUE : &propFALSE; + return this->IsImported() ? cmValue(propTRUE) : cmValue(propFALSE); } if (prop == propIMPORTED_GLOBAL) { - return this->IsImportedGloballyVisible() ? &propTRUE : &propFALSE; + return this->IsImportedGloballyVisible() ? cmValue(propTRUE) + : cmValue(propFALSE); } if (prop == propNAME) { - return &this->GetName(); + return cmValue(this->GetName()); } if (prop == propBINARY_DIR) { - return &this->impl->Makefile->GetStateSnapshot() - .GetDirectory() - .GetCurrentBinary(); + return cmValue(this->impl->Makefile->GetStateSnapshot() + .GetDirectory() + .GetCurrentBinary()); } if (prop == propSOURCE_DIR) { - return &this->impl->Makefile->GetStateSnapshot() - .GetDirectory() - .GetCurrentSource(); + return cmValue(this->impl->Makefile->GetStateSnapshot() + .GetDirectory() + .GetCurrentSource()); } } - cmProp retVal = this->impl->Properties.GetPropertyValue(prop); + cmValue retVal = this->impl->Properties.GetPropertyValue(prop); if (!retVal) { const bool chain = this->impl->Makefile->GetState()->IsPropertyChained( prop, cmProperty::TARGET); @@ -1870,7 +1777,7 @@ cmProp cmTarget::GetProperty(const std::string& prop) const std::string const& cmTarget::GetSafeProperty(std::string const& prop) const { - cmProp ret = this->GetProperty(prop); + cmValue ret = this->GetProperty(prop); if (ret) { return *ret; } @@ -2031,8 +1938,8 @@ std::string cmTarget::ImportedGetFullPath( std::string result; - cmProp loc = nullptr; - cmProp imp = nullptr; + cmValue loc = nullptr; + cmValue imp = nullptr; std::string suffix; if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY && @@ -2043,9 +1950,9 @@ std::string cmTarget::ImportedGetFullPath( result = *loc; } else { std::string impProp = cmStrCat("IMPORTED_LOCATION", suffix); - if (cmProp config_location = this->GetProperty(impProp)) { + if (cmValue config_location = this->GetProperty(impProp)) { result = *config_location; - } else if (cmProp location = + } else if (cmValue location = this->GetProperty("IMPORTED_LOCATION")) { result = *location; } @@ -2058,9 +1965,9 @@ std::string cmTarget::ImportedGetFullPath( } else if (this->GetType() == cmStateEnums::SHARED_LIBRARY || this->IsExecutableWithExports()) { std::string impProp = cmStrCat("IMPORTED_IMPLIB", suffix); - if (cmProp config_implib = this->GetProperty(impProp)) { + if (cmValue config_implib = this->GetProperty(impProp)) { result = *config_implib; - } else if (cmProp implib = this->GetProperty("IMPORTED_IMPLIB")) { + } else if (cmValue implib = this->GetProperty("IMPORTED_IMPLIB")) { result = *implib; } } @@ -2138,8 +2045,8 @@ bool cmTargetInternals::CheckImportedLibName(std::string const& prop, return true; } -bool cmTarget::GetMappedConfig(std::string const& desired_config, cmProp& loc, - cmProp& imp, std::string& suffix) const +bool cmTarget::GetMappedConfig(std::string const& desired_config, cmValue& loc, + cmValue& imp, std::string& suffix) const { std::string config_upper; if (!desired_config.empty()) { @@ -2161,7 +2068,7 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config, cmProp& loc, std::vector<std::string> mappedConfigs; { std::string mapProp = cmStrCat("MAP_IMPORTED_CONFIG_", config_upper); - if (cmProp mapValue = this->GetProperty(mapProp)) { + if (cmValue mapValue = this->GetProperty(mapProp)) { cmExpandList(*mapValue, mappedConfigs, true); } } @@ -2243,7 +2150,7 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config, cmProp& loc, // any available configuration. if (!loc && !imp) { std::vector<std::string> availableConfigs; - if (cmProp iconfigs = this->GetProperty("IMPORTED_CONFIGURATIONS")) { + if (cmValue iconfigs = this->GetProperty("IMPORTED_CONFIGURATIONS")) { cmExpandList(*iconfigs, availableConfigs); } for (auto aci = availableConfigs.begin(); diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 30d9f5d06..3cf69429c 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -14,10 +14,10 @@ #include "cmAlgorithms.h" #include "cmListFileCache.h" #include "cmPolicies.h" -#include "cmProperty.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmTargetLinkLibraryType.h" +#include "cmValue.h" class cmCustomCommand; class cmGlobalGenerator; @@ -170,20 +170,21 @@ public: //! Set/Get a property of this target file void SetProperty(const std::string& prop, const char* value); + void SetProperty(const std::string& prop, cmValue value); void SetProperty(const std::string& prop, const std::string& value) { - this->SetProperty(prop, value.c_str()); + this->SetProperty(prop, cmValue(value)); } void AppendProperty(const std::string& prop, const std::string& value, bool asString = false); //! Might return a nullptr if the property is not set or invalid - cmProp GetProperty(const std::string& prop) const; + cmValue GetProperty(const std::string& prop) const; //! Always returns a valid pointer std::string const& GetSafeProperty(std::string const& prop) const; bool GetPropertyAsBool(const std::string& prop) const; void CheckProperty(const std::string& prop, cmMakefile* context) const; - cmProp GetComputedProperty(const std::string& prop, cmMessenger* messenger, - cmListFileBacktrace const& context) const; + cmValue GetComputedProperty(const std::string& prop, cmMessenger* messenger, + cmListFileBacktrace const& context) const; //! Get all properties cmPropertyMap const& GetProperties() const; @@ -198,8 +199,8 @@ public: bool IsPerConfig() const; bool CanCompileSources() const; - bool GetMappedConfig(std::string const& desired_config, cmProp& loc, - cmProp& imp, std::string& suffix) const; + bool GetMappedConfig(std::string const& desired_config, cmValue& loc, + cmValue& imp, std::string& suffix) const; //! Return whether this target is an executable with symbol exports enabled. bool IsExecutableWithExports() const; @@ -216,18 +217,12 @@ public: //! Get a backtrace from the creation of the target. cmListFileBacktrace const& GetBacktrace() const; - void InsertInclude(std::string const& entry, cmListFileBacktrace const& bt, - bool before = false); - void InsertCompileOption(std::string const& entry, - cmListFileBacktrace const& bt, bool before = false); - void InsertCompileDefinition(std::string const& entry, - cmListFileBacktrace const& bt); - void InsertLinkOption(std::string const& entry, - cmListFileBacktrace const& bt, bool before = false); - void InsertLinkDirectory(std::string const& entry, - cmListFileBacktrace const& bt, bool before = false); - void InsertPrecompileHeader(std::string const& entry, - cmListFileBacktrace const& bt); + void InsertInclude(BT<std::string> const& entry, bool before = false); + void InsertCompileOption(BT<std::string> const& entry, bool before = false); + void InsertCompileDefinition(BT<std::string> const& entry); + void InsertLinkOption(BT<std::string> const& entry, bool before = false); + void InsertLinkDirectory(BT<std::string> const& entry, bool before = false); + void InsertPrecompileHeader(BT<std::string> const& entry); void AppendBuildInterfaceIncludes(); @@ -237,6 +232,9 @@ public: void AddSystemIncludeDirectories(std::set<std::string> const& incs); std::set<std::string> const& GetSystemIncludeDirectories() const; + void AddInstallIncludeDirectories(cmStringRange const& incs); + cmStringRange GetInstallIncludeDirectoriesEntries() const; + BTs<std::string> const* GetLanguageStandardProperty( const std::string& propertyName) const; @@ -244,32 +242,23 @@ public: std::string const& value, const std::string& feature); - cmStringRange GetIncludeDirectoriesEntries() const; - cmBacktraceRange GetIncludeDirectoriesBacktraces() const; + cmBTStringRange GetIncludeDirectoriesEntries() const; - cmStringRange GetCompileOptionsEntries() const; - cmBacktraceRange GetCompileOptionsBacktraces() const; + cmBTStringRange GetCompileOptionsEntries() const; - cmStringRange GetCompileFeaturesEntries() const; - cmBacktraceRange GetCompileFeaturesBacktraces() const; + cmBTStringRange GetCompileFeaturesEntries() const; - cmStringRange GetCompileDefinitionsEntries() const; - cmBacktraceRange GetCompileDefinitionsBacktraces() const; + cmBTStringRange GetCompileDefinitionsEntries() const; - cmStringRange GetPrecompileHeadersEntries() const; - cmBacktraceRange GetPrecompileHeadersBacktraces() const; + cmBTStringRange GetPrecompileHeadersEntries() const; - cmStringRange GetSourceEntries() const; - cmBacktraceRange GetSourceBacktraces() const; + cmBTStringRange GetSourceEntries() const; - cmStringRange GetLinkOptionsEntries() const; - cmBacktraceRange GetLinkOptionsBacktraces() const; + cmBTStringRange GetLinkOptionsEntries() const; - cmStringRange GetLinkDirectoriesEntries() const; - cmBacktraceRange GetLinkDirectoriesBacktraces() const; + cmBTStringRange GetLinkDirectoriesEntries() const; - cmStringRange GetLinkImplementationEntries() const; - cmBacktraceRange GetLinkImplementationBacktraces() const; + cmBTStringRange GetLinkImplementationEntries() const; std::string ImportedGetFullPath(const std::string& config, cmStateEnums::ArtifactType artifact) const; @@ -280,6 +269,9 @@ public: }; private: + template <typename ValueType> + void StoreProperty(const std::string& prop, ValueType value); + // Internal representation details. friend class cmGeneratorTarget; diff --git a/Source/cmTargetCompileOptionsCommand.cxx b/Source/cmTargetCompileOptionsCommand.cxx index dee2c10a3..8ca3842d3 100644 --- a/Source/cmTargetCompileOptionsCommand.cxx +++ b/Source/cmTargetCompileOptionsCommand.cxx @@ -37,7 +37,8 @@ private: } cmListFileBacktrace lfbt = this->Makefile->GetBacktrace(); - tgt->InsertCompileOption(this->Join(content), lfbt, prepend); + tgt->InsertCompileOption(BT<std::string>(this->Join(content), lfbt), + prepend); return true; // Successfully handled. } diff --git a/Source/cmTargetExport.h b/Source/cmTargetExport.h index 1e38d8492..19fc9319a 100644 --- a/Source/cmTargetExport.h +++ b/Source/cmTargetExport.h @@ -29,7 +29,6 @@ public: cmInstallTargetGenerator* FrameworkGenerator; cmInstallTargetGenerator* BundleGenerator; cmInstallFilesGenerator* HeaderGenerator; - std::string InterfaceIncludeDirectories; ///@} bool NamelinkOnly = false; diff --git a/Source/cmTargetIncludeDirectoriesCommand.cxx b/Source/cmTargetIncludeDirectoriesCommand.cxx index 3897499f3..f31501ebd 100644 --- a/Source/cmTargetIncludeDirectoriesCommand.cxx +++ b/Source/cmTargetIncludeDirectoriesCommand.cxx @@ -63,7 +63,7 @@ bool TargetIncludeDirectoriesImpl::HandleDirectContent( bool system) { cmListFileBacktrace lfbt = this->Makefile->GetBacktrace(); - tgt->InsertInclude(this->Join(content), lfbt, prepend); + tgt->InsertInclude(BT<std::string>(this->Join(content), lfbt), prepend); if (system) { std::string prefix = this->Makefile->GetCurrentSourceDirectory() + "/"; std::set<std::string> sdirs; diff --git a/Source/cmTargetLinkDirectoriesCommand.cxx b/Source/cmTargetLinkDirectoriesCommand.cxx index 0c68d604c..3ba27a83a 100644 --- a/Source/cmTargetLinkDirectoriesCommand.cxx +++ b/Source/cmTargetLinkDirectoriesCommand.cxx @@ -34,7 +34,8 @@ private: bool prepend, bool /*system*/) override { cmListFileBacktrace lfbt = this->Makefile->GetBacktrace(); - tgt->InsertLinkDirectory(this->Join(content), lfbt, prepend); + tgt->InsertLinkDirectory(BT<std::string>(this->Join(content), lfbt), + prepend); return true; // Successfully handled. } }; diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx index 3423b30dc..e15c9418a 100644 --- a/Source/cmTargetLinkLibrariesCommand.cxx +++ b/Source/cmTargetLinkLibrariesCommand.cxx @@ -14,13 +14,13 @@ #include "cmMakefile.h" #include "cmMessageType.h" #include "cmPolicies.h" -#include "cmProperty.h" #include "cmState.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" #include "cmTargetLinkLibraryType.h" +#include "cmValue.h" #include "cmake.h" namespace { @@ -143,6 +143,7 @@ bool cmTargetLinkLibrariesCommand(std::vector<std::string> const& args, case cmPolicies::WARN: e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0039) << "\n"; modal = "should"; + CM_FALLTHROUGH; case cmPolicies::OLD: break; case cmPolicies::REQUIRED_ALWAYS: @@ -150,6 +151,7 @@ bool cmTargetLinkLibrariesCommand(std::vector<std::string> const& args, case cmPolicies::NEW: modal = "must"; messageType = MessageType::FATAL_ERROR; + break; } if (modal) { e << "Utility target \"" << target->GetName() << "\" " << modal @@ -278,7 +280,7 @@ bool cmTargetLinkLibrariesCommand(std::vector<std::string> const& args, // with old versions of CMake and new) llt = GENERAL_LibraryType; std::string linkType = cmStrCat(args[0], "_LINK_TYPE"); - cmProp linkTypeString = mf.GetDefinition(linkType); + cmValue linkTypeString = mf.GetDefinition(linkType); if (linkTypeString) { if (*linkTypeString == "debug") { llt = DEBUG_LibraryType; @@ -395,6 +397,7 @@ bool TLL::HandleLibrary(ProcessingState currentProcessingState, case cmPolicies::WARN: e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0023) << "\n"; modal = "should"; + CM_FALLTHROUGH; case cmPolicies::OLD: break; case cmPolicies::REQUIRED_ALWAYS: @@ -402,6 +405,7 @@ bool TLL::HandleLibrary(ProcessingState currentProcessingState, case cmPolicies::NEW: modal = "must"; messageType = MessageType::FATAL_ERROR; + break; } if (modal) { diff --git a/Source/cmTargetLinkOptionsCommand.cxx b/Source/cmTargetLinkOptionsCommand.cxx index df9416fad..3ea2d7175 100644 --- a/Source/cmTargetLinkOptionsCommand.cxx +++ b/Source/cmTargetLinkOptionsCommand.cxx @@ -30,7 +30,7 @@ private: bool prepend, bool /*system*/) override { cmListFileBacktrace lfbt = this->Makefile->GetBacktrace(); - tgt->InsertLinkOption(this->Join(content), lfbt, prepend); + tgt->InsertLinkOption(BT<std::string>(this->Join(content), lfbt), prepend); return true; // Successfully handled. } diff --git a/Source/cmTargetPropCommandBase.cxx b/Source/cmTargetPropCommandBase.cxx index e41714aba..3bd1ea3c6 100644 --- a/Source/cmTargetPropCommandBase.cxx +++ b/Source/cmTargetPropCommandBase.cxx @@ -5,9 +5,9 @@ #include "cmExecutionStatus.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" -#include "cmProperty.h" #include "cmStateTypes.h" #include "cmTarget.h" +#include "cmValue.h" #include "cmake.h" cmTargetPropCommandBase::cmTargetPropCommandBase(cmExecutionStatus& status) @@ -181,7 +181,7 @@ void cmTargetPropCommandBase::HandleInterfaceContent( { if (prepend) { const std::string propName = std::string("INTERFACE_") + this->Property; - cmProp propValue = tgt->GetProperty(propName); + cmValue propValue = tgt->GetProperty(propName); const std::string totalContent = this->Join(content) + (propValue ? (";" + *propValue) : std::string()); tgt->SetProperty(propName, totalContent); diff --git a/Source/cmTargetPropertyComputer.cxx b/Source/cmTargetPropertyComputer.cxx index b9c93659f..9b9414277 100644 --- a/Source/cmTargetPropertyComputer.cxx +++ b/Source/cmTargetPropertyComputer.cxx @@ -21,6 +21,7 @@ bool cmTargetPropertyComputer::HandleLocationPropertyPolicy( case cmPolicies::WARN: e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0026) << "\n"; modal = "should"; + CM_FALLTHROUGH; case cmPolicies::OLD: break; case cmPolicies::REQUIRED_ALWAYS: @@ -28,6 +29,7 @@ bool cmTargetPropertyComputer::HandleLocationPropertyPolicy( case cmPolicies::NEW: modal = "may"; messageType = MessageType::FATAL_ERROR; + break; } if (modal) { diff --git a/Source/cmTargetPropertyComputer.h b/Source/cmTargetPropertyComputer.h index f2be318b8..e61a1fcda 100644 --- a/Source/cmTargetPropertyComputer.h +++ b/Source/cmTargetPropertyComputer.h @@ -7,10 +7,10 @@ #include <string> #include "cmListFileCache.h" -#include "cmProperty.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" class cmMessenger; @@ -18,11 +18,11 @@ class cmTargetPropertyComputer { public: template <typename Target> - static cmProp GetProperty(Target const* tgt, const std::string& prop, - cmMessenger* messenger, - cmListFileBacktrace const& context) + static cmValue GetProperty(Target const* tgt, const std::string& prop, + cmMessenger* messenger, + cmListFileBacktrace const& context) { - if (cmProp loc = GetLocation(tgt, prop, messenger, context)) { + if (cmValue loc = GetLocation(tgt, prop, messenger, context)) { return loc; } if (cmSystemTools::GetFatalErrorOccured()) { @@ -46,9 +46,9 @@ private: std::string const& config); template <typename Target> - static cmProp GetLocation(Target const* tgt, std::string const& prop, - cmMessenger* messenger, - cmListFileBacktrace const& context) + static cmValue GetLocation(Target const* tgt, std::string const& prop, + cmMessenger* messenger, + cmListFileBacktrace const& context) { // Watch for special "computed" properties that are dependent on @@ -65,7 +65,7 @@ private: context)) { return nullptr; } - return &ComputeLocationForBuild(tgt); + return cmValue(ComputeLocationForBuild(tgt)); } // Support "LOCATION_<CONFIG>". @@ -76,7 +76,7 @@ private: return nullptr; } std::string configName = prop.substr(9); - return &ComputeLocation(tgt, configName); + return cmValue(ComputeLocation(tgt, configName)); } // Support "<CONFIG>_LOCATION". @@ -89,7 +89,7 @@ private: context)) { return nullptr; } - return &ComputeLocation(tgt, configName); + return cmValue(ComputeLocation(tgt, configName)); } } } @@ -97,6 +97,6 @@ private: } template <typename Target> - static cmProp GetSources(Target const* tgt, cmMessenger* messenger, - cmListFileBacktrace const& context); + static cmValue GetSources(Target const* tgt, cmMessenger* messenger, + cmListFileBacktrace const& context); }; diff --git a/Source/cmTest.cxx b/Source/cmTest.cxx index a26bef3db..7c0f9e722 100644 --- a/Source/cmTest.cxx +++ b/Source/cmTest.cxx @@ -5,7 +5,7 @@ #include "cmMakefile.h" #include "cmProperty.h" #include "cmState.h" -#include "cmStringAlgorithms.h" +#include "cmValue.h" cmTest::cmTest(cmMakefile* mf) : CommandExpandLists(false) @@ -32,20 +32,20 @@ void cmTest::SetCommand(std::vector<std::string> const& command) this->Command = command; } -const char* cmTest::GetProperty(const std::string& prop) const +cmValue cmTest::GetProperty(const std::string& prop) const { - cmProp retVal = this->Properties.GetPropertyValue(prop); + cmValue retVal = this->Properties.GetPropertyValue(prop); if (!retVal) { const bool chain = this->Makefile->GetState()->IsPropertyChained(prop, cmProperty::TEST); if (chain) { - if (cmProp p = this->Makefile->GetProperty(prop, chain)) { - return p->c_str(); + if (cmValue p = this->Makefile->GetProperty(prop, chain)) { + return p; } } return nullptr; } - return retVal->c_str(); + return retVal; } bool cmTest::GetPropertyAsBool(const std::string& prop) const @@ -57,6 +57,10 @@ void cmTest::SetProperty(const std::string& prop, const char* value) { this->Properties.SetProperty(prop, value); } +void cmTest::SetProperty(const std::string& prop, cmValue value) +{ + this->Properties.SetProperty(prop, value); +} void cmTest::AppendProperty(const std::string& prop, const std::string& value, bool asString) diff --git a/Source/cmTest.h b/Source/cmTest.h index f33b7e286..85978dac2 100644 --- a/Source/cmTest.h +++ b/Source/cmTest.h @@ -9,6 +9,7 @@ #include "cmListFileCache.h" #include "cmPropertyMap.h" +#include "cmValue.h" class cmMakefile; @@ -34,9 +35,14 @@ public: //! Set/Get a property of this source file void SetProperty(const std::string& prop, const char* value); + void SetProperty(const std::string& prop, cmValue value); + void SetProperty(const std::string& prop, const std::string& value) + { + this->SetProperty(prop, cmValue(value)); + } void AppendProperty(const std::string& prop, const std::string& value, bool asString = false); - const char* GetProperty(const std::string& prop) const; + cmValue GetProperty(const std::string& prop) const; bool GetPropertyAsBool(const std::string& prop) const; cmPropertyMap& GetProperties() { return this->Properties; } diff --git a/Source/cmTestGenerator.cxx b/Source/cmTestGenerator.cxx index 7022c4eb1..dbb087608 100644 --- a/Source/cmTestGenerator.cxx +++ b/Source/cmTestGenerator.cxx @@ -19,13 +19,13 @@ #include "cmMessageType.h" #include "cmOutputConverter.h" #include "cmPolicies.h" -#include "cmProperty.h" #include "cmPropertyMap.h" #include "cmRange.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTest.h" +#include "cmValue.h" namespace /* anonymous */ { @@ -167,7 +167,7 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os, exe = target->GetFullPath(config); // Prepend with the emulator when cross compiling if required. - cmProp emulator = target->GetProperty("CROSSCOMPILING_EMULATOR"); + cmValue emulator = target->GetProperty("CROSSCOMPILING_EMULATOR"); if (cmNonempty(emulator)) { std::vector<std::string> emulatorWithArgs = cmExpandedList(*emulator); std::string emulatorExe(emulatorWithArgs[0]); diff --git a/Source/cmTimestamp.cxx b/Source/cmTimestamp.cxx index 056696d4b..c8f5a4b22 100644 --- a/Source/cmTimestamp.cxx +++ b/Source/cmTimestamp.cxx @@ -18,6 +18,10 @@ #include <cstring> #include <sstream> +#ifdef __MINGW32__ +# include <libloaderapi.h> +#endif + #include "cmStringAlgorithms.h" #include "cmSystemTools.h" @@ -159,6 +163,7 @@ std::string cmTimestamp::AddTimestampComponent(char flag, case 'M': case 'S': case 'U': + case 'V': case 'w': case 'y': case 'Y': @@ -189,6 +194,30 @@ std::string cmTimestamp::AddTimestampComponent(char flag, char buffer[16]; +#ifdef __MINGW32__ + /* See a bug in MinGW: https://sourceforge.net/p/mingw-w64/bugs/793/. A work + * around is to try to use strftime() from ucrtbase.dll. */ + using T = size_t(WINAPI*)(char*, size_t, const char*, const struct tm*); + auto loadUcrtStrftime = []() -> T { + auto handle = + LoadLibraryExA("ucrtbase.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32); + if (handle) { +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wcast-function-type" + return reinterpret_cast<T>(GetProcAddress(handle, "strftime")); +# pragma GCC diagnostic pop + } + return nullptr; + }; + static T ucrtStrftime = loadUcrtStrftime(); + + if (ucrtStrftime) { + size_t size = + ucrtStrftime(buffer, sizeof(buffer), formatString.c_str(), &timeStruct); + return std::string(buffer, size); + } +#endif + size_t size = strftime(buffer, sizeof(buffer), formatString.c_str(), &timeStruct); diff --git a/Source/cmTryRunCommand.cxx b/Source/cmTryRunCommand.cxx index 8cac74d34..cc9e15864 100644 --- a/Source/cmTryRunCommand.cxx +++ b/Source/cmTryRunCommand.cxx @@ -9,12 +9,12 @@ #include "cmDuration.h" #include "cmMakefile.h" #include "cmMessageType.h" -#include "cmProperty.h" #include "cmRange.h" #include "cmState.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" #include "cmake.h" class cmExecutionStatus; @@ -162,7 +162,7 @@ bool cmTryRunCommand::InitialPass(std::vector<std::string> const& argv, if (!this->OutputVariable.empty()) { // if the TryCompileCore saved output in this outputVariable then // prepend that output to this output - cmProp compileOutput = + cmValue compileOutput = this->Makefile->GetDefinition(this->OutputVariable); if (compileOutput) { runOutputContents = *compileOutput + runOutputContents; @@ -260,7 +260,7 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs, comment.c_str(), cmStateEnums::STRING); cmState* state = this->Makefile->GetState(); - cmProp existingValue = state->GetCacheEntryValue(this->RunResultVariable); + cmValue existingValue = state->GetCacheEntryValue(this->RunResultVariable); if (existingValue) { state->SetCacheEntryProperty(this->RunResultVariable, "ADVANCED", "1"); } @@ -282,7 +282,7 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs, internalRunOutputName, "PLEASE_FILL_OUT-NOTFOUND", comment.c_str(), cmStateEnums::STRING); cmState* state = this->Makefile->GetState(); - cmProp existing = state->GetCacheEntryValue(internalRunOutputName); + cmValue existing = state->GetCacheEntryValue(internalRunOutputName); if (existing) { state->SetCacheEntryProperty(internalRunOutputName, "ADVANCED", "1"); } diff --git a/Source/cmUVHandlePtr.h b/Source/cmUVHandlePtr.h index 8c5ad5983..027d6905f 100644 --- a/Source/cmUVHandlePtr.h +++ b/Source/cmUVHandlePtr.h @@ -23,7 +23,7 @@ #else -# define CM_INHERIT_CTOR(Class, Base, Tpl) using Base Tpl ::Base; +# define CM_INHERIT_CTOR(Class, Base, Tpl) using Base Tpl ::Base #endif diff --git a/Source/cmUtilitySourceCommand.cxx b/Source/cmUtilitySourceCommand.cxx index d276c8a60..2805a33bb 100644 --- a/Source/cmUtilitySourceCommand.cxx +++ b/Source/cmUtilitySourceCommand.cxx @@ -6,11 +6,11 @@ #include "cmExecutionStatus.h" #include "cmMakefile.h" -#include "cmProperty.h" #include "cmState.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" // cmUtilitySourceCommand bool cmUtilitySourceCommand(std::vector<std::string> const& args, @@ -25,7 +25,7 @@ bool cmUtilitySourceCommand(std::vector<std::string> const& args, // The first argument is the cache entry name. std::string const& cacheEntry = *arg++; - cmProp cacheValue = status.GetMakefile().GetDefinition(cacheEntry); + cmValue cacheValue = status.GetMakefile().GetDefinition(cacheEntry); // If it exists already and appears up to date then we are done. If // the string contains "(IntDir)" but that is not the // CMAKE_CFG_INTDIR setting then the value is out of date. @@ -85,7 +85,7 @@ bool cmUtilitySourceCommand(std::vector<std::string> const& args, std::string utilityDirectory = status.GetMakefile().GetCurrentBinaryDirectory(); std::string exePath; - if (cmProp d = + if (cmValue d = status.GetMakefile().GetDefinition("EXECUTABLE_OUTPUT_PATH")) { exePath = *d; } diff --git a/Source/cmValue.cxx b/Source/cmValue.cxx new file mode 100644 index 000000000..044db2909 --- /dev/null +++ b/Source/cmValue.cxx @@ -0,0 +1,123 @@ + +#include "cmValue.h" + +#include <string> + +#include <cmext/string_view> + +#include "cmStringAlgorithms.h" + +std::string cmValue::Empty; + +bool cmValue::IsOn(cm::string_view value) noexcept +{ + switch (value.size()) { + case 1: + return value[0] == '1' || value[0] == 'Y' || value[0] == 'y'; + case 2: + return // + (value[0] == 'O' || value[0] == 'o') && // + (value[1] == 'N' || value[1] == 'n'); + case 3: + return // + (value[0] == 'Y' || value[0] == 'y') && // + (value[1] == 'E' || value[1] == 'e') && // + (value[2] == 'S' || value[2] == 's'); + case 4: + return // + (value[0] == 'T' || value[0] == 't') && // + (value[1] == 'R' || value[1] == 'r') && // + (value[2] == 'U' || value[2] == 'u') && // + (value[3] == 'E' || value[3] == 'e'); + default: + break; + } + + return false; +} + +bool cmValue::IsOff(cm::string_view value) noexcept +{ + switch (value.size()) { + case 0: + return true; + case 1: + return value[0] == '0' || value[0] == 'N' || value[0] == 'n'; + case 2: + return // + (value[0] == 'N' || value[0] == 'n') && // + (value[1] == 'O' || value[1] == 'o'); + case 3: + return // + (value[0] == 'O' || value[0] == 'o') && // + (value[1] == 'F' || value[1] == 'f') && // + (value[2] == 'F' || value[2] == 'f'); + case 5: + return // + (value[0] == 'F' || value[0] == 'f') && // + (value[1] == 'A' || value[1] == 'a') && // + (value[2] == 'L' || value[2] == 'l') && // + (value[3] == 'S' || value[3] == 's') && // + (value[4] == 'E' || value[4] == 'e'); + case 6: + return // + (value[0] == 'I' || value[0] == 'i') && // + (value[1] == 'G' || value[1] == 'g') && // + (value[2] == 'N' || value[2] == 'n') && // + (value[3] == 'O' || value[3] == 'o') && // + (value[4] == 'R' || value[4] == 'r') && // + (value[5] == 'E' || value[5] == 'e'); + default: + break; + } + + return IsNOTFOUND(value); +} + +bool cmValue::IsNOTFOUND(cm::string_view value) noexcept +{ + return (value == "NOTFOUND"_s) || cmHasSuffix(value, "-NOTFOUND"_s); +} + +bool cmValue::IsInternallyOn(cm::string_view value) noexcept +{ + return (value.size() == 4) && // + (value[0] == 'I' || value[0] == 'i') && // + (value[1] == '_') && // + (value[2] == 'O' || value[2] == 'o') && // + (value[3] == 'N' || value[3] == 'n'); +} + +int cmValue::Compare(cmValue value) const noexcept +{ + if (this->Value == nullptr && !value) { + return 0; + } + if (this->Value == nullptr) { + return -1; + } + if (!value) { + return 1; + } + return this->Value->compare(*value); +} + +int cmValue::Compare(cm::string_view value) const noexcept +{ + if (this->Value == nullptr && value.data() == nullptr) { + return 0; + } + if (this->Value == nullptr) { + return -1; + } + if (value.data() == nullptr) { + return 1; + } + return cm::string_view(*this->Value).compare(value); +} + +std::ostream& operator<<(std::ostream& o, cmValue v) +{ + o << *v; + return o; +} diff --git a/Source/cmValue.h b/Source/cmValue.h new file mode 100644 index 000000000..f96d2f5de --- /dev/null +++ b/Source/cmValue.h @@ -0,0 +1,314 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#pragma once + +#include "cmConfigure.h" // IWYU pragma: keep + +#include <cstddef> +#include <iosfwd> +#include <string> + +#include <cm/string_view> + +class cmValue +{ +public: + cmValue() noexcept = default; + cmValue(std::nullptr_t) noexcept {} + explicit cmValue(const std::string* value) noexcept + : Value(value) + { + } + explicit cmValue(const std::string& value) noexcept + : Value(&value) + { + } + cmValue(const cmValue& other) noexcept = default; + + cmValue& operator=(const cmValue& other) noexcept = default; + cmValue& operator=(std::nullptr_t) noexcept + { + this->Value = nullptr; + return *this; + } + + const std::string* Get() const noexcept { return this->Value; } + const char* GetCStr() const noexcept + { + return this->Value == nullptr ? nullptr : this->Value->c_str(); + } + + const std::string* operator->() const noexcept + { + return this->Value == nullptr ? &cmValue::Empty : this->Value; + } + const std::string& operator*() const noexcept + { + return this->Value == nullptr ? cmValue::Empty : *this->Value; + } + + explicit operator bool() const noexcept { return this->Value != nullptr; } + operator const std::string&() const noexcept { return this->operator*(); } + explicit operator cm::string_view() const noexcept + { + return this->operator*(); + } + + /** + * Does the value indicate a true or ON value? + */ + bool IsOn() const noexcept + { + return this->Value != nullptr && + cmValue::IsOn(cm::string_view(*this->Value)); + } + /** + * Does the value indicate a false or off value ? Note that this is + * not the same as !IsOn(...) because there are a number of + * ambiguous values such as "/usr/local/bin" a path will result in + * IsOn and IsOff both returning false. Note that the special path + * NOTFOUND, *-NOTFOUND or IGNORE will cause IsOff to return true. + */ + bool IsOff() const noexcept + { + return this->Value == nullptr || + cmValue::IsOff(cm::string_view(*this->Value)); + } + /** Return true if value is NOTFOUND or ends in -NOTFOUND. */ + bool IsNOTFOUND() const noexcept + { + return this->Value != nullptr && + cmValue::IsNOTFOUND(cm::string_view(*this->Value)); + } + bool IsEmpty() const noexcept + { + return this->Value == nullptr || this->Value->empty(); + } + + /** + * Does a string indicates that CMake/CPack/CTest internally + * forced this value. This is not the same as On, but this + * may be considered as "internally switched on". + */ + bool IsInternallyOn() const noexcept + { + return this->Value != nullptr && + cmValue::IsInternallyOn(cm::string_view(*this->Value)); + } + + bool IsSet() const noexcept + { + return !this->IsEmpty() && !this->IsNOTFOUND(); + } + + /** + * Does a string indicate a true or ON value? + */ + static bool IsOn(const char* value) noexcept + { + return value != nullptr && IsOn(cm::string_view(value)); + } + static bool IsOn(cm::string_view) noexcept; + + /** + * Compare method has same semantic as std::optional::compare + */ + int Compare(cmValue value) const noexcept; + int Compare(cm::string_view value) const noexcept; + + /** + * Does a string indicate a false or off value ? Note that this is + * not the same as !IsOn(...) because there are a number of + * ambiguous values such as "/usr/local/bin" a path will result in + * IsOn and IsOff both returning false. Note that the special path + * NOTFOUND, *-NOTFOUND or IGNORE will cause IsOff to return true. + */ + static bool IsOff(const char* value) noexcept + { + return value == nullptr || IsOff(cm::string_view(value)); + } + static bool IsOff(cm::string_view) noexcept; + + /** Return true if value is NOTFOUND or ends in -NOTFOUND. */ + static bool IsNOTFOUND(const char* value) noexcept + { + return value == nullptr || IsNOTFOUND(cm::string_view(value)); + } + static bool IsNOTFOUND(cm::string_view) noexcept; + + static bool IsEmpty(const char* value) noexcept + { + return value == nullptr || *value == '\0'; + } + static bool IsEmpty(cm::string_view value) noexcept { return value.empty(); } + + /** + * Does a string indicates that CMake/CPack/CTest internally + * forced this value. This is not the same as On, but this + * may be considered as "internally switched on". + */ + static bool IsInternallyOn(const char* value) noexcept + { + return value != nullptr && IsInternallyOn(cm::string_view(value)); + } + static bool IsInternallyOn(cm::string_view) noexcept; + +private: + static std::string Empty; + const std::string* Value = nullptr; +}; + +std::ostream& operator<<(std::ostream& o, cmValue v); + +inline bool operator==(cmValue l, cmValue r) noexcept +{ + return l.Compare(r) == 0; +} +inline bool operator!=(cmValue l, cmValue r) noexcept +{ + return l.Compare(r) != 0; +} +inline bool operator<(cmValue l, cmValue r) noexcept +{ + return l.Compare(r) < 0; +} +inline bool operator<=(cmValue l, cmValue r) noexcept +{ + return l.Compare(r) <= 0; +} +inline bool operator>(cmValue l, cmValue r) noexcept +{ + return l.Compare(r) > 0; +} +inline bool operator>=(cmValue l, cmValue r) noexcept +{ + return l.Compare(r) >= 0; +} + +inline bool operator==(cmValue l, cm::string_view r) noexcept +{ + return l.Compare(r) == 0; +} +inline bool operator!=(cmValue l, cm::string_view r) noexcept +{ + return l.Compare(r) != 0; +} +inline bool operator<(cmValue l, cm::string_view r) noexcept +{ + return l.Compare(r) < 0; +} +inline bool operator<=(cmValue l, cm::string_view r) noexcept +{ + return l.Compare(r) <= 0; +} +inline bool operator>(cmValue l, cm::string_view r) noexcept +{ + return l.Compare(r) > 0; +} +inline bool operator>=(cmValue l, cm::string_view r) noexcept +{ + return l.Compare(r) >= 0; +} + +inline bool operator==(cmValue l, std::nullptr_t) noexcept +{ + return l.Compare(cmValue{}) == 0; +} +inline bool operator!=(cmValue l, std::nullptr_t) noexcept +{ + return l.Compare(cmValue{}) != 0; +} +inline bool operator<(cmValue l, std::nullptr_t) noexcept +{ + return l.Compare(cmValue{}) < 0; +} +inline bool operator<=(cmValue l, std::nullptr_t) noexcept +{ + return l.Compare(cmValue{}) <= 0; +} +inline bool operator>(cmValue l, std::nullptr_t) noexcept +{ + return l.Compare(cmValue{}) > 0; +} +inline bool operator>=(cmValue l, std::nullptr_t) noexcept +{ + return l.Compare(cmValue{}) >= 0; +} + +/** + * Does a string indicate a true or ON value? This is not the same as ifdef. + */ +inline bool cmIsOn(cm::string_view val) +{ + return cmValue::IsOn(val); +} +inline bool cmIsOn(const char* val) +{ + return cmValue::IsOn(val); +} +inline bool cmIsOn(cmValue val) +{ + return val.IsOn(); +} + +/** + * Does a string indicate a false or off value ? Note that this is + * not the same as !IsOn(...) because there are a number of + * ambiguous values such as "/usr/local/bin" a path will result in + * IsON and IsOff both returning false. Note that the special path + * NOTFOUND, *-NOTFOUND or IGNORE will cause IsOff to return true. + */ +inline bool cmIsOff(cm::string_view val) +{ + return cmValue::IsOff(val); +} +inline bool cmIsOff(const char* val) +{ + return cmValue::IsOff(val); +} +inline bool cmIsOff(cmValue val) +{ + return val.IsOff(); +} + +/** Return true if value is NOTFOUND or ends in -NOTFOUND. */ +inline bool cmIsNOTFOUND(cm::string_view val) +{ + return cmValue::IsNOTFOUND(val); +} +inline bool cmIsNOTFOUND(cmValue val) +{ + return val.IsNOTFOUND(); +} + +/** Check for non-empty Property/Variable value. */ +inline bool cmNonempty(cm::string_view val) +{ + return !cmValue::IsEmpty(val); +} +inline bool cmNonempty(const char* val) +{ + return !cmValue::IsEmpty(val); +} +inline bool cmNonempty(cmValue val) +{ + return !val.IsEmpty(); +} + +/** + * Does a string indicates that CMake/CPack/CTest internally + * forced this value. This is not the same as On, but this + * may be considered as "internally switched on". + */ +inline bool cmIsInternallyOn(cm::string_view val) +{ + return cmValue::IsInternallyOn(val); +} +inline bool cmIsInternallyOn(const char* val) +{ + return cmValue::IsInternallyOn(val); +} +inline bool cmIsInternallyOn(cmValue val) +{ + return val.IsInternallyOn(); +} diff --git a/Source/cmVariableRequiresCommand.cxx b/Source/cmVariableRequiresCommand.cxx index 1fe03ab26..2b1efbac2 100644 --- a/Source/cmVariableRequiresCommand.cxx +++ b/Source/cmVariableRequiresCommand.cxx @@ -4,10 +4,10 @@ #include "cmExecutionStatus.h" #include "cmMakefile.h" -#include "cmProperty.h" #include "cmState.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" // cmLibraryCommand bool cmVariableRequiresCommand(std::vector<std::string> const& args, @@ -38,7 +38,7 @@ bool cmVariableRequiresCommand(std::vector<std::string> const& args, } } } - cmProp reqVar = status.GetMakefile().GetDefinition(resultVariable); + cmValue reqVar = status.GetMakefile().GetDefinition(resultVariable); // if reqVar is unset, then set it to requirementsMet // if reqVar is set to true, but requirementsMet is false , then // set reqVar to false. diff --git a/Source/cmVariableWatchCommand.cxx b/Source/cmVariableWatchCommand.cxx index 7c7fbca5b..fd5402cf6 100644 --- a/Source/cmVariableWatchCommand.cxx +++ b/Source/cmVariableWatchCommand.cxx @@ -10,9 +10,9 @@ #include "cmListFileCache.h" #include "cmMakefile.h" #include "cmMessageType.h" -#include "cmProperty.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" #include "cmVariableWatch.h" #include "cmake.h" @@ -45,7 +45,7 @@ void cmVariableWatchCommandVariableAccessed(const std::string& variable, std::string stack = *mf->GetProperty("LISTFILE_STACK"); if (!data->Command.empty()) { - cmProp const currentListFile = + cmValue const currentListFile = mf->GetDefinition("CMAKE_CURRENT_LIST_FILE"); const auto fakeLineNo = std::numeric_limits<decltype(cmListFileArgument::Line)>::max(); diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 97cb1bf14..d2c49ae36 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -6,6 +6,7 @@ #include <set> #include <cm/memory> +#include <cm/optional> #include <cm/string_view> #include <cm/vector> #include <cmext/algorithm> @@ -437,7 +438,7 @@ void cmVisualStudio10TargetGenerator::Generate() this->VerifyNecessaryFiles(); } - cmProp vsProjectTypes = + cmValue vsProjectTypes = this->GeneratorTarget->GetProperty("VS_GLOBAL_PROJECT_TYPES"); if (vsProjectTypes) { const char* tagName = "ProjectTypes"; @@ -447,11 +448,11 @@ void cmVisualStudio10TargetGenerator::Generate() e1.Element(tagName, *vsProjectTypes); } - cmProp vsProjectName = + cmValue vsProjectName = this->GeneratorTarget->GetProperty("VS_SCC_PROJECTNAME"); - cmProp vsLocalPath = + cmValue vsLocalPath = this->GeneratorTarget->GetProperty("VS_SCC_LOCALPATH"); - cmProp vsProvider = + cmValue vsProvider = this->GeneratorTarget->GetProperty("VS_SCC_PROVIDER"); if (vsProjectName && vsLocalPath && vsProvider) { @@ -459,7 +460,7 @@ void cmVisualStudio10TargetGenerator::Generate() e1.Element("SccLocalPath", *vsLocalPath); e1.Element("SccProvider", *vsProvider); - cmProp vsAuxPath = + cmValue vsAuxPath = this->GeneratorTarget->GetProperty("VS_SCC_AUXPATH"); if (vsAuxPath) { e1.Element("SccAuxPath", *vsAuxPath); @@ -470,7 +471,7 @@ void cmVisualStudio10TargetGenerator::Generate() e1.Element("WinMDAssembly", "true"); } - cmProp vsGlobalKeyword = + cmValue vsGlobalKeyword = this->GeneratorTarget->GetProperty("VS_GLOBAL_KEYWORD"); if (!vsGlobalKeyword) { if (this->GlobalGenerator->TargetsAndroid()) { @@ -482,63 +483,78 @@ void cmVisualStudio10TargetGenerator::Generate() e1.Element("Keyword", *vsGlobalKeyword); } - cmProp vsGlobalRootNamespace = + cmValue vsGlobalRootNamespace = this->GeneratorTarget->GetProperty("VS_GLOBAL_ROOTNAMESPACE"); if (vsGlobalRootNamespace) { e1.Element("RootNamespace", *vsGlobalRootNamespace); } e1.Element("Platform", this->Platform); - cmProp projLabel = this->GeneratorTarget->GetProperty("PROJECT_LABEL"); - if (!projLabel) { - projLabel = &this->Name; - } - e1.Element("ProjectName", *projLabel); + cmValue projLabel = this->GeneratorTarget->GetProperty("PROJECT_LABEL"); + e1.Element("ProjectName", projLabel ? projLabel : this->Name); { - cmProp targetFramework = - this->GeneratorTarget->GetProperty("DOTNET_TARGET_FRAMEWORK"); + cm::optional<std::string> targetFramework; + cm::optional<std::string> targetFrameworkVersion; + cm::optional<std::string> targetFrameworkIdentifier; + cm::optional<std::string> targetFrameworkTargetsVersion; + if (cmValue tf = + this->GeneratorTarget->GetProperty("DOTNET_TARGET_FRAMEWORK")) { + targetFramework = *tf; + } else if (cmValue vstfVer = this->GeneratorTarget->GetProperty( + "VS_DOTNET_TARGET_FRAMEWORK_VERSION")) { + // FIXME: Someday, add a deprecation warning for VS_* property. + targetFrameworkVersion = *vstfVer; + } else if (cmValue tfVer = this->GeneratorTarget->GetProperty( + "DOTNET_TARGET_FRAMEWORK_VERSION")) { + targetFrameworkVersion = *tfVer; + } else if (this->ProjectType == csproj) { + targetFrameworkVersion = + this->GlobalGenerator->GetTargetFrameworkVersion(); + } + if (this->ProjectType == vcxproj && + this->GlobalGenerator->TargetsWindowsCE()) { + e1.Element("EnableRedirectPlatform", "true"); + e1.Element("RedirectPlatformValue", this->Platform); + } + if (this->ProjectType == csproj) { + if (this->GlobalGenerator->TargetsWindowsCE()) { + // FIXME: These target VS_TARGET_FRAMEWORK* target properties + // are undocumented settings only ever supported for WinCE. + // We need a better way to control these in general. + if (cmValue tfId = this->GeneratorTarget->GetProperty( + "VS_TARGET_FRAMEWORK_IDENTIFIER")) { + targetFrameworkIdentifier = *tfId; + } + if (cmValue tfTargetsVer = this->GeneratorTarget->GetProperty( + "VS_TARGET_FRAMEWORKS_TARGET_VERSION")) { + targetFrameworkTargetsVersion = *tfTargetsVer; + } + } + if (!targetFrameworkIdentifier) { + targetFrameworkIdentifier = + this->GlobalGenerator->GetTargetFrameworkIdentifier(); + } + if (!targetFrameworkTargetsVersion) { + targetFrameworkTargetsVersion = + this->GlobalGenerator->GetTargetFrameworkTargetsVersion(); + } + } if (targetFramework) { if (targetFramework->find(';') != std::string::npos) { e1.Element("TargetFrameworks", *targetFramework); } else { e1.Element("TargetFramework", *targetFramework); } - } else { - // TODO: add deprecation warning for VS_* property? - cmProp p = this->GeneratorTarget->GetProperty( - "VS_DOTNET_TARGET_FRAMEWORK_VERSION"); - if (!p) { - p = this->GeneratorTarget->GetProperty( - "DOTNET_TARGET_FRAMEWORK_VERSION"); - } - const char* targetFrameworkVersion = cmToCStr(p); - if (!targetFrameworkVersion && this->ProjectType == csproj && - this->GlobalGenerator->TargetsWindowsCE() && - this->GlobalGenerator->GetVersion() == - cmGlobalVisualStudioGenerator::VS12) { - // VS12 .NETCF default to .NET framework 3.9 - targetFrameworkVersion = "v3.9"; - } - if (targetFrameworkVersion) { - e1.Element("TargetFrameworkVersion", targetFrameworkVersion); - } } - if (this->ProjectType == vcxproj && - this->GlobalGenerator->TargetsWindowsCE()) { - e1.Element("EnableRedirectPlatform", "true"); - e1.Element("RedirectPlatformValue", this->Platform); + if (targetFrameworkVersion) { + e1.Element("TargetFrameworkVersion", *targetFrameworkVersion); } - if (this->ProjectType == csproj && - this->GlobalGenerator->TargetsWindowsCE()) { - cmProp targetFrameworkId = this->GeneratorTarget->GetProperty( - "VS_TARGET_FRAMEWORK_IDENTIFIER"); - e1.Element("TargetFrameworkIdentifier", - targetFrameworkId ? *targetFrameworkId - : "WindowsEmbeddedCompact"); - cmProp targetFrameworkVer = this->GeneratorTarget->GetProperty( - "VS_TARGET_FRAMEWORKS_TARGET_VERSION"); + if (targetFrameworkIdentifier) { + e1.Element("TargetFrameworkIdentifier", *targetFrameworkIdentifier); + } + if (targetFrameworkTargetsVersion) { e1.Element("TargetFrameworkTargetsVersion", - targetFrameworkVer ? *targetFrameworkVer : "v8.0"); + *targetFrameworkTargetsVersion); } if (!this->GlobalGenerator->GetPlatformToolsetCudaCustomDirString() .empty()) { @@ -574,7 +590,7 @@ void cmVisualStudio10TargetGenerator::Generate() globalKey == "ROOTNAMESPACE" || globalKey == "KEYWORD") { continue; } - cmProp value = this->GeneratorTarget->GetProperty(keyIt); + cmValue value = this->GeneratorTarget->GetProperty(keyIt); if (!value) continue; e1.Element(globalKey, *value); @@ -697,7 +713,7 @@ void cmVisualStudio10TargetGenerator::Generate() props = VS10_CSharp_USER_PROPS; break; } - if (cmProp p = this->GeneratorTarget->GetProperty("VS_USER_PROPS")) { + if (cmValue p = this->GeneratorTarget->GetProperty("VS_USER_PROPS")) { props = *p; } if (!props.empty()) { @@ -810,7 +826,7 @@ void cmVisualStudio10TargetGenerator::Generate() void cmVisualStudio10TargetGenerator::WritePackageReferences(Elem& e0) { std::vector<std::string> packageReferences; - if (cmProp vsPackageReferences = + if (cmValue vsPackageReferences = this->GeneratorTarget->GetProperty("VS_PACKAGE_REFERENCES")) { cmExpandList(*vsPackageReferences, packageReferences); } @@ -830,7 +846,7 @@ void cmVisualStudio10TargetGenerator::WritePackageReferences(Elem& e0) void cmVisualStudio10TargetGenerator::WriteDotNetReferences(Elem& e0) { std::vector<std::string> references; - if (cmProp vsDotNetReferences = + if (cmValue vsDotNetReferences = this->GeneratorTarget->GetProperty("VS_DOTNET_REFERENCES")) { cmExpandList(*vsDotNetReferences, references); } @@ -889,7 +905,7 @@ void cmVisualStudio10TargetGenerator::WriteDotNetReference( e2.Element("ReferenceOutputAssembly", "true"); if (!hint.empty()) { const char* privateReference = "True"; - if (cmProp value = this->GeneratorTarget->GetProperty( + if (cmValue value = this->GeneratorTarget->GetProperty( "VS_DOTNET_REFERENCES_COPY_LOCAL")) { if (cmIsOff(*value)) { privateReference = "False"; @@ -903,7 +919,7 @@ void cmVisualStudio10TargetGenerator::WriteDotNetReference( void cmVisualStudio10TargetGenerator::WriteImports(Elem& e0) { - cmProp imports = + cmValue imports = this->GeneratorTarget->Target->GetProperty("VS_PROJECT_IMPORT"); if (imports) { std::vector<std::string> argsSplit = cmExpandedList(*imports, false); @@ -1007,7 +1023,7 @@ void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup(Elem& e0) ".Designer.cs"; if (cmsys::SystemTools::FileExists(designerResource)) { std::string generator = "PublicResXFileCodeGenerator"; - if (cmProp g = oi->GetProperty("VS_RESOURCE_GENERATOR")) { + if (cmValue g = oi->GetProperty("VS_RESOURCE_GENERATOR")) { generator = *g; } if (!generator.empty()) { @@ -1031,7 +1047,7 @@ void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup(Elem& e0) cm::string_view tagName = cm::string_view(p).substr(propNamePrefix.length()); if (!tagName.empty()) { - cmProp value = props.GetPropertyValue(p); + cmValue value = props.GetPropertyValue(p); if (cmNonempty(value)) { e2.Element(tagName, *value); } @@ -1050,7 +1066,7 @@ void cmVisualStudio10TargetGenerator::WriteXamlFilesGroup(Elem& e0) for (cmSourceFile const* oi : this->XamlObjs) { std::string obj = oi->GetFullPath(); std::string xamlType; - cmProp xamlTypeProperty = oi->GetProperty("VS_XAML_TYPE"); + cmValue xamlTypeProperty = oi->GetProperty("VS_XAML_TYPE"); if (xamlTypeProperty) { xamlType = *xamlTypeProperty; } else { @@ -1104,7 +1120,7 @@ void cmVisualStudio10TargetGenerator::WriteTargetsFileReferences(Elem& e1) void cmVisualStudio10TargetGenerator::WriteWinRTReferences(Elem& e0) { std::vector<std::string> references; - if (cmProp vsWinRTReferences = + if (cmValue vsWinRTReferences = this->GeneratorTarget->GetProperty("VS_WINRT_REFERENCES")) { cmExpandList(*vsWinRTReferences, references); } @@ -1147,7 +1163,7 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues(Elem& e0) if (this->ProjectType != csproj) { std::string configType; - if (cmProp vsConfigurationType = + if (cmValue vsConfigurationType = this->GeneratorTarget->GetProperty("VS_CONFIGURATION_TYPE")) { configType = cmGeneratorExpression::Evaluate(*vsConfigurationType, this->LocalGenerator, c); @@ -1209,9 +1225,9 @@ void cmVisualStudio10TargetGenerator::WriteCEDebugProjectConfigurationValues( if (!this->GlobalGenerator->TargetsWindowsCE()) { return; } - cmProp additionalFiles = + cmValue additionalFiles = this->GeneratorTarget->GetProperty("DEPLOYMENT_ADDITIONAL_FILES"); - cmProp remoteDirectory = + cmValue remoteDirectory = this->GeneratorTarget->GetProperty("DEPLOYMENT_REMOTE_DIRECTORY"); if (!(additionalFiles || remoteDirectory)) { return; @@ -1233,7 +1249,7 @@ void cmVisualStudio10TargetGenerator::WriteMSToolConfigurationValues( Elem& e1, std::string const& config) { cmGlobalVisualStudio10Generator* gg = this->GlobalGenerator; - cmProp mfcFlag = this->Makefile->GetDefinition("CMAKE_MFC_FLAG"); + cmValue mfcFlag = this->Makefile->GetDefinition("CMAKE_MFC_FLAG"); if (mfcFlag) { std::string const mfcFlagValue = cmGeneratorExpression::Evaluate(*mfcFlag, this->LocalGenerator, config); @@ -1263,7 +1279,7 @@ void cmVisualStudio10TargetGenerator::WriteMSToolConfigurationValues( } else { e1.Element("CharacterSet", "MultiByte"); } - if (cmProp projectToolsetOverride = + if (cmValue projectToolsetOverride = this->GeneratorTarget->GetProperty("VS_PLATFORM_TOOLSET")) { e1.Element("PlatformToolset", *projectToolsetOverride); } else if (const char* toolset = gg->GetPlatformToolset()) { @@ -1309,7 +1325,7 @@ void cmVisualStudio10TargetGenerator::WriteMSToolConfigurationValuesManaged( o.RemoveFlag("Platform"); } - if (cmProp projectToolsetOverride = + if (cmValue projectToolsetOverride = this->GeneratorTarget->GetProperty("VS_PLATFORM_TOOLSET")) { e1.Element("PlatformToolset", *projectToolsetOverride); } else if (const char* toolset = gg->GetPlatformToolset()) { @@ -1320,7 +1336,7 @@ void cmVisualStudio10TargetGenerator::WriteMSToolConfigurationValuesManaged( cmStrCat(cmSystemTools::UpperCase(config), "_POSTFIX"); std::string assemblyName = this->GeneratorTarget->GetOutputName( config, cmStateEnums::RuntimeBinaryArtifact); - if (cmProp postfix = this->GeneratorTarget->GetProperty(postfixName)) { + if (cmValue postfix = this->GeneratorTarget->GetProperty(postfixName)) { assemblyName += *postfix; } e1.Element("AssemblyName", assemblyName); @@ -1341,18 +1357,18 @@ void cmVisualStudio10TargetGenerator::WriteNsightTegraConfigurationValues( cmGlobalVisualStudio10Generator* gg = this->GlobalGenerator; const char* toolset = gg->GetPlatformToolset(); e1.Element("NdkToolchainVersion", toolset ? toolset : "Default"); - if (cmProp minApi = this->GeneratorTarget->GetProperty("ANDROID_API_MIN")) { + if (cmValue minApi = this->GeneratorTarget->GetProperty("ANDROID_API_MIN")) { e1.Element("AndroidMinAPI", "android-" + *minApi); } - if (cmProp api = this->GeneratorTarget->GetProperty("ANDROID_API")) { + if (cmValue api = this->GeneratorTarget->GetProperty("ANDROID_API")) { e1.Element("AndroidTargetAPI", "android-" + *api); } - if (cmProp cpuArch = this->GeneratorTarget->GetProperty("ANDROID_ARCH")) { + if (cmValue cpuArch = this->GeneratorTarget->GetProperty("ANDROID_ARCH")) { e1.Element("AndroidArch", *cpuArch); } - if (cmProp stlType = + if (cmValue stlType = this->GeneratorTarget->GetProperty("ANDROID_STL_TYPE")) { e1.Element("AndroidStlType", *stlType); } @@ -1362,13 +1378,13 @@ void cmVisualStudio10TargetGenerator::WriteAndroidConfigurationValues( Elem& e1, std::string const&) { cmGlobalVisualStudio10Generator* gg = this->GlobalGenerator; - if (cmProp projectToolsetOverride = + if (cmValue projectToolsetOverride = this->GeneratorTarget->GetProperty("VS_PLATFORM_TOOLSET")) { e1.Element("PlatformToolset", *projectToolsetOverride); } else if (const char* toolset = gg->GetPlatformToolset()) { e1.Element("PlatformToolset", toolset); } - if (cmProp stlType = + if (cmValue stlType = this->GeneratorTarget->GetProperty("ANDROID_STL_TYPE")) { if (*stlType != "none") { e1.Element("UseOfStl", *stlType); @@ -1472,7 +1488,10 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule( cmCustomCommandGenerator ccg(command, c, lg, true); std::string comment = lg->ConstructComment(ccg); comment = cmVS10EscapeComment(comment); - std::string script = lg->ConstructScript(ccg); + cmLocalVisualStudioGenerator::IsManaged isManaged = (this->Managed) + ? cmLocalVisualStudioGenerator::managed + : cmLocalVisualStudioGenerator::unmanaged; + std::string script = lg->ConstructScript(ccg, isManaged); bool symbolic = false; // input files for custom command std::stringstream additional_inputs; @@ -1803,8 +1822,8 @@ void cmVisualStudio10TargetGenerator::WriteGroupSources( } } -void cmVisualStudio10TargetGenerator::WriteHeaderSource(Elem& e1, - cmSourceFile const* sf) +void cmVisualStudio10TargetGenerator::WriteHeaderSource( + Elem& e1, cmSourceFile const* sf, ConfigToSettings const& toolSettings) { std::string const& fileName = sf->GetFullPath(); Elem e2(e1, "ClInclude"); @@ -1815,6 +1834,7 @@ void cmVisualStudio10TargetGenerator::WriteHeaderSource(Elem& e1, e2.Element("DependentUpon", fileName.substr(0, fileName.find_last_of("."))); } + this->FinishWritingSource(e2, toolSettings); } void cmVisualStudio10TargetGenerator::ParseSettingsProperty( @@ -1871,8 +1891,8 @@ bool cmVisualStudio10TargetGenerator::PropertyIsSameInAllConfigs( return true; } -void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1, - cmSourceFile const* sf) +void cmVisualStudio10TargetGenerator::WriteExtraSource( + Elem& e1, cmSourceFile const* sf, ConfigToSettings& toolSettings) { bool toolHasSettings = false; const char* tool = "None"; @@ -1883,10 +1903,6 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1, std::string copyToOutDir; std::string includeInVsix; std::string ext = cmSystemTools::LowerCase(sf->GetExtension()); - ConfigToSettings toolSettings; - for (const auto& config : this->Configurations) { - toolSettings[config]; - } if (this->ProjectType == csproj && !this->InSourceBuild) { toolHasSettings = true; @@ -1894,37 +1910,37 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1, if (ext == "hlsl") { tool = "FXCompile"; // Figure out the type of shader compiler to use. - if (cmProp st = sf->GetProperty("VS_SHADER_TYPE")) { + if (cmValue st = sf->GetProperty("VS_SHADER_TYPE")) { for (const std::string& config : this->Configurations) { toolSettings[config]["ShaderType"] = *st; } } // Figure out which entry point to use if any - if (cmProp se = sf->GetProperty("VS_SHADER_ENTRYPOINT")) { + if (cmValue se = sf->GetProperty("VS_SHADER_ENTRYPOINT")) { for (const std::string& config : this->Configurations) { toolSettings[config]["EntryPointName"] = *se; } } // Figure out which shader model to use if any - if (cmProp sm = sf->GetProperty("VS_SHADER_MODEL")) { + if (cmValue sm = sf->GetProperty("VS_SHADER_MODEL")) { for (const std::string& config : this->Configurations) { toolSettings[config]["ShaderModel"] = *sm; } } // Figure out which output header file to use if any - if (cmProp ohf = sf->GetProperty("VS_SHADER_OUTPUT_HEADER_FILE")) { + if (cmValue ohf = sf->GetProperty("VS_SHADER_OUTPUT_HEADER_FILE")) { for (const std::string& config : this->Configurations) { toolSettings[config]["HeaderFileOutput"] = *ohf; } } // Figure out which variable name to use if any - if (cmProp vn = sf->GetProperty("VS_SHADER_VARIABLE_NAME")) { + if (cmValue vn = sf->GetProperty("VS_SHADER_VARIABLE_NAME")) { for (const std::string& config : this->Configurations) { toolSettings[config]["VariableName"] = *vn; } } // Figure out if there's any additional flags to use - if (cmProp saf = sf->GetProperty("VS_SHADER_FLAGS")) { + if (cmValue saf = sf->GetProperty("VS_SHADER_FLAGS")) { cmGeneratorExpression ge; std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(*saf); @@ -1937,7 +1953,7 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1, } } // Figure out if debug information should be generated - if (cmProp sed = sf->GetProperty("VS_SHADER_ENABLE_DEBUG")) { + if (cmValue sed = sf->GetProperty("VS_SHADER_ENABLE_DEBUG")) { cmGeneratorExpression ge; std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(*sed); @@ -1951,7 +1967,7 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1, } } // Figure out if optimizations should be disabled - if (cmProp sdo = sf->GetProperty("VS_SHADER_DISABLE_OPTIMIZATIONS")) { + if (cmValue sdo = sf->GetProperty("VS_SHADER_DISABLE_OPTIMIZATIONS")) { cmGeneratorExpression ge; std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(*sdo); @@ -1964,7 +1980,7 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1, } } } - if (cmProp sofn = sf->GetProperty("VS_SHADER_OBJECT_FILE_NAME")) { + if (cmValue sofn = sf->GetProperty("VS_SHADER_OBJECT_FILE_NAME")) { for (const std::string& config : this->Configurations) { toolSettings[config]["ObjectFileOutput"] = *sofn; } @@ -1987,7 +2003,7 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1, } else if (ext == "vsixmanifest") { subType = "Designer"; } - if (cmProp c = sf->GetProperty("VS_COPY_TO_OUT_DIR")) { + if (cmValue c = sf->GetProperty("VS_COPY_TO_OUT_DIR")) { tool = "Content"; copyToOutDir = *c; toolHasSettings = true; @@ -2016,7 +2032,7 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1, } } - cmProp toolOverride = sf->GetProperty("VS_TOOL_OVERRIDE"); + cmValue toolOverride = sf->GetProperty("VS_TOOL_OVERRIDE"); if (cmNonempty(toolOverride)) { tool = toolOverride->c_str(); } @@ -2025,12 +2041,12 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1, std::string deployLocation; if (this->GlobalGenerator->TargetsWindowsPhone() || this->GlobalGenerator->TargetsWindowsStore()) { - cmProp content = sf->GetProperty("VS_DEPLOYMENT_CONTENT"); + cmValue content = sf->GetProperty("VS_DEPLOYMENT_CONTENT"); if (cmNonempty(content)) { toolHasSettings = true; deployContent = *content; - cmProp location = sf->GetProperty("VS_DEPLOYMENT_LOCATION"); + cmValue location = sf->GetProperty("VS_DEPLOYMENT_LOCATION"); if (cmNonempty(location)) { deployLocation = *location; } @@ -2038,7 +2054,7 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1, } if (ParsedToolTargetSettings.find(tool) == ParsedToolTargetSettings.end()) { - cmProp toolTargetProperty = this->GeneratorTarget->Target->GetProperty( + cmValue toolTargetProperty = this->GeneratorTarget->Target->GetProperty( "VS_SOURCE_SETTINGS_" + std::string(tool)); ConfigToSettings toolTargetSettings; if (toolTargetProperty) { @@ -2054,10 +2070,6 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1, } } - if (cmProp p = sf->GetProperty("VS_SETTINGS")) { - ParseSettingsProperty(*p, toolSettings); - } - if (!toolSettings.empty()) { toolHasSettings = true; } @@ -2067,27 +2079,7 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1, if (toolHasSettings) { e2.SetHasElements(); - std::vector<std::string> writtenSettings; - for (const auto& configSettings : toolSettings) { - for (const auto& setting : configSettings.second) { - - if (std::find(writtenSettings.begin(), writtenSettings.end(), - setting.first) != writtenSettings.end()) { - continue; - } - - if (PropertyIsSameInAllConfigs(toolSettings, setting.first)) { - e2.Element(setting.first, setting.second); - writtenSettings.push_back(setting.first); - } else { - e2.WritePlatformConfigTag(setting.first, - "'$(Configuration)|$(Platform)'=='" + - configSettings.first + "|" + - this->Platform + "'", - setting.second); - } - } - } + this->FinishWritingSource(e2, toolSettings); if (!deployContent.empty()) { cmGeneratorExpression ge; @@ -2224,6 +2216,15 @@ void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0) // Skip explicit reference to CMakeLists.txt source. continue; } + + ConfigToSettings toolSettings; + for (const auto& config : this->Configurations) { + toolSettings[config]; + } + if (cmValue p = si.Source->GetProperty("VS_SETTINGS")) { + ParseSettingsProperty(*p, toolSettings); + } + const char* tool = nullptr; switch (si.Kind) { case cmGeneratorTarget::SourceKindAppManifest: @@ -2251,10 +2252,10 @@ void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0) } break; case cmGeneratorTarget::SourceKindExtra: - this->WriteExtraSource(e1, si.Source); + this->WriteExtraSource(e1, si.Source, toolSettings); break; case cmGeneratorTarget::SourceKindHeader: - this->WriteHeaderSource(e1, si.Source); + this->WriteHeaderSource(e1, si.Source, toolSettings); break; case cmGeneratorTarget::SourceKindIDL: tool = "Midl"; @@ -2364,6 +2365,8 @@ void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0) if (!isCSharp && !exclude_configs.empty()) { this->WriteExcludeFromBuild(e2, exclude_configs); } + + this->FinishWritingSource(e2, toolSettings); } } @@ -2372,6 +2375,32 @@ void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0) } } +void cmVisualStudio10TargetGenerator::FinishWritingSource( + Elem& e2, ConfigToSettings const& toolSettings) +{ + std::vector<std::string> writtenSettings; + for (const auto& configSettings : toolSettings) { + for (const auto& setting : configSettings.second) { + + if (std::find(writtenSettings.begin(), writtenSettings.end(), + setting.first) != writtenSettings.end()) { + continue; + } + + if (PropertyIsSameInAllConfigs(toolSettings, setting.first)) { + e2.Element(setting.first, setting.second); + writtenSettings.push_back(setting.first); + } else { + e2.WritePlatformConfigTag(setting.first, + "'$(Configuration)|$(Platform)'=='" + + configSettings.first + "|" + + this->Platform + "'", + setting.second); + } + } + } +} + void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags( Elem& e2, cmSourceFile const* source) { @@ -2389,22 +2418,22 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags( bool configDependentDefines = false; std::string includes; bool configDependentIncludes = false; - if (cmProp cflags = sf.GetProperty("COMPILE_FLAGS")) { + if (cmValue cflags = sf.GetProperty("COMPILE_FLAGS")) { configDependentFlags = cmGeneratorExpression::Find(*cflags) != std::string::npos; flags += *cflags; } - if (cmProp coptions = sf.GetProperty("COMPILE_OPTIONS")) { + if (cmValue coptions = sf.GetProperty("COMPILE_OPTIONS")) { configDependentOptions = cmGeneratorExpression::Find(*coptions) != std::string::npos; options += *coptions; } - if (cmProp cdefs = sf.GetProperty("COMPILE_DEFINITIONS")) { + if (cmValue cdefs = sf.GetProperty("COMPILE_DEFINITIONS")) { configDependentDefines = cmGeneratorExpression::Find(*cdefs) != std::string::npos; defines += *cdefs; } - if (cmProp cincludes = sf.GetProperty("INCLUDE_DIRECTORIES")) { + if (cmValue cincludes = sf.GetProperty("INCLUDE_DIRECTORIES")) { configDependentIncludes = cmGeneratorExpression::Find(*cincludes) != std::string::npos; includes += *cincludes; @@ -2442,7 +2471,7 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags( std::string configUpper = cmSystemTools::UpperCase(config); std::string configDefines = defines; std::string defPropName = cmStrCat("COMPILE_DEFINITIONS_", configUpper); - if (cmProp ccdefs = sf.GetProperty(defPropName)) { + if (cmValue ccdefs = sf.GetProperty(defPropName)) { if (!configDefines.empty()) { configDefines += ";"; } @@ -2618,7 +2647,7 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions( const std::string cond = this->CalcCondition(config); if (ttype <= cmStateEnums::UTILITY) { - if (cmProp workingDir = this->GeneratorTarget->GetProperty( + if (cmValue workingDir = this->GeneratorTarget->GetProperty( "VS_DEBUGGER_WORKING_DIRECTORY")) { std::string genWorkingDir = cmGeneratorExpression::Evaluate( *workingDir, this->LocalGenerator, config); @@ -2626,7 +2655,7 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions( genWorkingDir); } - if (cmProp environment = + if (cmValue environment = this->GeneratorTarget->GetProperty("VS_DEBUGGER_ENVIRONMENT")) { std::string genEnvironment = cmGeneratorExpression::Evaluate( *environment, this->LocalGenerator, config); @@ -2634,7 +2663,7 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions( genEnvironment); } - if (cmProp debuggerCommand = + if (cmValue debuggerCommand = this->GeneratorTarget->GetProperty("VS_DEBUGGER_COMMAND")) { std::string genDebuggerCommand = cmGeneratorExpression::Evaluate( *debuggerCommand, this->LocalGenerator, config); @@ -2642,7 +2671,7 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions( genDebuggerCommand); } - if (cmProp commandArguments = this->GeneratorTarget->GetProperty( + if (cmValue commandArguments = this->GeneratorTarget->GetProperty( "VS_DEBUGGER_COMMAND_ARGUMENTS")) { std::string genCommandArguments = cmGeneratorExpression::Evaluate( *commandArguments, this->LocalGenerator, config); @@ -2674,40 +2703,40 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions( e1.WritePlatformConfigTag("IntDir", cond, intermediateDir); - if (cmProp sdkExecutableDirectories = this->Makefile->GetDefinition( + if (cmValue sdkExecutableDirectories = this->Makefile->GetDefinition( "CMAKE_VS_SDK_EXECUTABLE_DIRECTORIES")) { e1.WritePlatformConfigTag("ExecutablePath", cond, *sdkExecutableDirectories); } - if (cmProp sdkIncludeDirectories = this->Makefile->GetDefinition( + if (cmValue sdkIncludeDirectories = this->Makefile->GetDefinition( "CMAKE_VS_SDK_INCLUDE_DIRECTORIES")) { e1.WritePlatformConfigTag("IncludePath", cond, *sdkIncludeDirectories); } - if (cmProp sdkReferenceDirectories = this->Makefile->GetDefinition( + if (cmValue sdkReferenceDirectories = this->Makefile->GetDefinition( "CMAKE_VS_SDK_REFERENCE_DIRECTORIES")) { e1.WritePlatformConfigTag("ReferencePath", cond, *sdkReferenceDirectories); } - if (cmProp sdkLibraryDirectories = this->Makefile->GetDefinition( + if (cmValue sdkLibraryDirectories = this->Makefile->GetDefinition( "CMAKE_VS_SDK_LIBRARY_DIRECTORIES")) { e1.WritePlatformConfigTag("LibraryPath", cond, *sdkLibraryDirectories); } - if (cmProp sdkLibraryWDirectories = this->Makefile->GetDefinition( + if (cmValue sdkLibraryWDirectories = this->Makefile->GetDefinition( "CMAKE_VS_SDK_LIBRARY_WINRT_DIRECTORIES")) { e1.WritePlatformConfigTag("LibraryWPath", cond, *sdkLibraryWDirectories); } - if (cmProp sdkSourceDirectories = + if (cmValue sdkSourceDirectories = this->Makefile->GetDefinition("CMAKE_VS_SDK_SOURCE_DIRECTORIES")) { e1.WritePlatformConfigTag("SourcePath", cond, *sdkSourceDirectories); } - if (cmProp sdkExcludeDirectories = this->Makefile->GetDefinition( + if (cmValue sdkExcludeDirectories = this->Makefile->GetDefinition( "CMAKE_VS_SDK_EXCLUDE_DIRECTORIES")) { e1.WritePlatformConfigTag("ExcludePath", cond, *sdkExcludeDirectories); } @@ -2905,7 +2934,7 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions( this->Makefile->IssueMessage(MessageType::WARNING, message); } } - if (cmProp clr = + if (cmValue clr = this->GeneratorTarget->GetProperty("COMMON_LANGUAGE_RUNTIME")) { std::string clrString = *clr; if (!clrString.empty()) { @@ -3048,7 +3077,7 @@ void cmVisualStudio10TargetGenerator::WriteClOptions( oh.OutputPreprocessorDefinitions(this->LangForClCompile); if (this->NsightTegra) { - if (cmProp processMax = + if (cmValue processMax = this->GeneratorTarget->GetProperty("ANDROID_PROCESS_MAX")) { e2.Element("ProcessMax", *processMax); } @@ -3547,8 +3576,6 @@ void cmVisualStudio10TargetGenerator::WriteNasmOptions( } Elem e2(e1, "NASM"); - std::vector<std::string> includes = - this->GetIncludes(configName, "ASM_NASM"); OptionsHelper nasmOptions(*(this->NasmOptions[configName]), e2); nasmOptions.OutputAdditionalIncludeDirectories("ASM_NASM"); nasmOptions.OutputFlagMap(); @@ -3608,7 +3635,7 @@ void cmVisualStudio10TargetGenerator::WriteManifestOptions( std::vector<cmSourceFile const*> manifest_srcs; this->GeneratorTarget->GetManifests(manifest_srcs, config); - cmProp dpiAware = this->GeneratorTarget->GetProperty("VS_DPI_AWARE"); + cmValue dpiAware = this->GeneratorTarget->GetProperty("VS_DPI_AWARE"); if (!manifest_srcs.empty() || dpiAware) { Elem e2(e1, "Manifest"); @@ -3669,24 +3696,24 @@ void cmVisualStudio10TargetGenerator::WriteAntBuildOptions( e2.Element("EnableProGuard", "true"); } - if (cmProp proGuardConfigLocation = + if (cmValue proGuardConfigLocation = this->GeneratorTarget->GetProperty("ANDROID_PROGUARD_CONFIG_PATH")) { e2.Element("ProGuardConfigLocation", *proGuardConfigLocation); } - if (cmProp securePropertiesLocation = + if (cmValue securePropertiesLocation = this->GeneratorTarget->GetProperty("ANDROID_SECURE_PROPS_PATH")) { e2.Element("SecurePropertiesLocation", *securePropertiesLocation); } - if (cmProp nativeLibDirectoriesExpression = + if (cmValue nativeLibDirectoriesExpression = this->GeneratorTarget->GetProperty("ANDROID_NATIVE_LIB_DIRECTORIES")) { std::string nativeLibDirs = cmGeneratorExpression::Evaluate( *nativeLibDirectoriesExpression, this->LocalGenerator, configName); e2.Element("NativeLibDirectories", nativeLibDirs); } - if (cmProp nativeLibDependenciesExpression = + if (cmValue nativeLibDependenciesExpression = this->GeneratorTarget->GetProperty( "ANDROID_NATIVE_LIB_DEPENDENCIES")) { std::string nativeLibDeps = cmGeneratorExpression::Evaluate( @@ -3694,24 +3721,24 @@ void cmVisualStudio10TargetGenerator::WriteAntBuildOptions( e2.Element("NativeLibDependencies", nativeLibDeps); } - if (cmProp javaSourceDir = + if (cmValue javaSourceDir = this->GeneratorTarget->GetProperty("ANDROID_JAVA_SOURCE_DIR")) { e2.Element("JavaSourceDir", *javaSourceDir); } - if (cmProp jarDirectoriesExpression = + if (cmValue jarDirectoriesExpression = this->GeneratorTarget->GetProperty("ANDROID_JAR_DIRECTORIES")) { std::string jarDirectories = cmGeneratorExpression::Evaluate( *jarDirectoriesExpression, this->LocalGenerator, configName); e2.Element("JarDirectories", jarDirectories); } - if (cmProp jarDeps = + if (cmValue jarDeps = this->GeneratorTarget->GetProperty("ANDROID_JAR_DEPENDENCIES")) { e2.Element("JarDependencies", *jarDeps); } - if (cmProp assetsDirectories = + if (cmValue assetsDirectories = this->GeneratorTarget->GetProperty("ANDROID_ASSETS_DIRECTORIES")) { e2.Element("AssetsDirectories", *assetsDirectories); } @@ -3722,7 +3749,7 @@ void cmVisualStudio10TargetGenerator::WriteAntBuildOptions( e2.Element("AndroidManifestLocation", manifest_xml); } - if (cmProp antAdditionalOptions = + if (cmValue antAdditionalOptions = this->GeneratorTarget->GetProperty("ANDROID_ANT_ADDITIONAL_OPTIONS")) { e2.Element("AdditionalOptions", *antAdditionalOptions + " %(AdditionalOptions)"); @@ -3777,13 +3804,13 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions( std::string linkFlagVar = linkFlagVarBase + "_" + CONFIG; flags += " "; flags += this->Makefile->GetRequiredDefinition(linkFlagVar); - cmProp targetLinkFlags = this->GeneratorTarget->GetProperty("LINK_FLAGS"); + cmValue targetLinkFlags = this->GeneratorTarget->GetProperty("LINK_FLAGS"); if (targetLinkFlags) { flags += " "; flags += *targetLinkFlags; } std::string flagsProp = cmStrCat("LINK_FLAGS_", CONFIG); - if (cmProp flagsConfig = this->GeneratorTarget->GetProperty(flagsProp)) { + if (cmValue flagsConfig = this->GeneratorTarget->GetProperty(flagsProp)) { flags += " "; flags += *flagsConfig; } @@ -3864,7 +3891,7 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions( }; } - if (cmProp stackVal = this->Makefile->GetDefinition( + if (cmValue stackVal = this->Makefile->GetDefinition( "CMAKE_" + linkLanguage + "_STACK_SIZE")) { linkOptions.AddFlag("StackReserveSize", *stackVal); } @@ -4214,7 +4241,10 @@ void cmVisualStudio10TargetGenerator::WriteEvent( comment += lg->ConstructComment(ccg); script += pre; pre = "\n"; - script += lg->ConstructScript(ccg); + cmLocalVisualStudioGenerator::IsManaged isManaged = (this->Managed) + ? cmLocalVisualStudioGenerator::managed + : cmLocalVisualStudioGenerator::unmanaged; + script += lg->ConstructScript(ccg, isManaged); stdPipesUTF8 = stdPipesUTF8 || cc.GetStdPipesUTF8(); } @@ -4262,7 +4292,7 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences(Elem& e0) cmLocalGenerator* lg = dt->GetLocalGenerator(); std::string name = dt->GetName(); std::string path; - if (cmProp p = dt->GetProperty("EXTERNAL_MSPROJECT")) { + if (cmValue p = dt->GetProperty("EXTERNAL_MSPROJECT")) { path = *p; } else { path = cmStrCat(lg->GetCurrentBinaryDirectory(), '/', dt->GetName(), @@ -4292,13 +4322,13 @@ void cmVisualStudio10TargetGenerator::WritePlatformExtensions(Elem& e1) // This only applies to Windows 10 apps if (this->GlobalGenerator->TargetsWindowsStore() && cmHasLiteralPrefix(this->GlobalGenerator->GetSystemVersion(), "10.0")) { - cmProp desktopExtensionsVersion = + cmValue desktopExtensionsVersion = this->GeneratorTarget->GetProperty("VS_DESKTOP_EXTENSIONS_VERSION"); if (desktopExtensionsVersion) { this->WriteSinglePlatformExtension(e1, "WindowsDesktop", *desktopExtensionsVersion); } - cmProp mobileExtensionsVersion = + cmValue mobileExtensionsVersion = this->GeneratorTarget->GetProperty("VS_MOBILE_EXTENSIONS_VERSION"); if (mobileExtensionsVersion) { this->WriteSinglePlatformExtension(e1, "WindowsMobile", @@ -4327,7 +4357,7 @@ void cmVisualStudio10TargetGenerator::WriteSDKReferences(Elem& e0) { std::vector<std::string> sdkReferences; std::unique_ptr<Elem> spe1; - if (cmProp vsSDKReferences = + if (cmValue vsSDKReferences = this->GeneratorTarget->GetProperty("VS_SDK_REFERENCES")) { cmExpandList(*vsSDKReferences, sdkReferences); spe1 = cm::make_unique<Elem>(e0, "ItemGroup"); @@ -4339,11 +4369,11 @@ void cmVisualStudio10TargetGenerator::WriteSDKReferences(Elem& e0) // This only applies to Windows 10 apps if (this->GlobalGenerator->TargetsWindowsStore() && cmHasLiteralPrefix(this->GlobalGenerator->GetSystemVersion(), "10.0")) { - cmProp desktopExtensionsVersion = + cmValue desktopExtensionsVersion = this->GeneratorTarget->GetProperty("VS_DESKTOP_EXTENSIONS_VERSION"); - cmProp mobileExtensionsVersion = + cmValue mobileExtensionsVersion = this->GeneratorTarget->GetProperty("VS_MOBILE_EXTENSIONS_VERSION"); - cmProp iotExtensionsVersion = + cmValue iotExtensionsVersion = this->GeneratorTarget->GetProperty("VS_IOT_EXTENSIONS_VERSION"); if (desktopExtensionsVersion || mobileExtensionsVersion || @@ -4553,7 +4583,7 @@ void cmVisualStudio10TargetGenerator::WriteApplicationTypeSettings(Elem& e1) if (!targetPlatformVersion.empty()) { e1.Element("WindowsTargetPlatformVersion", targetPlatformVersion); } - cmProp targetPlatformMinVersion = this->GeneratorTarget->GetProperty( + cmValue targetPlatformMinVersion = this->GeneratorTarget->GetProperty( "VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION"); if (targetPlatformMinVersion) { e1.Element("WindowsTargetPlatformMinVersion", *targetPlatformMinVersion); @@ -5049,7 +5079,7 @@ void cmVisualStudio10TargetGenerator::GetCSharpSourceProperties( if (cmHasPrefix(p, propNamePrefix)) { std::string tagName = p.substr(propNamePrefix.length()); if (!tagName.empty()) { - cmProp val = props.GetPropertyValue(p); + cmValue val = props.GetPropertyValue(p); if (cmNonempty(val)) { tags[tagName] = *val; } else { @@ -5101,7 +5131,7 @@ std::string cmVisualStudio10TargetGenerator::GetCSharpSourceLink( } else if (!cmHasSuffix(fullFileName, ".cs") && cmHasPrefix(fullFileName, binDir)) { link = fullFileName.substr(binDir.length() + 1); - } else if (cmProp l = source->GetProperty("VS_CSHARP_Link")) { + } else if (cmValue l = source->GetProperty("VS_CSHARP_Link")) { link = *l; } diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h index 55c5444f1..a5ce5e58f 100644 --- a/Source/cmVisualStudio10TargetGenerator.h +++ b/Source/cmVisualStudio10TargetGenerator.h @@ -58,6 +58,10 @@ private: struct Elem; struct OptionsHelper; + using ConfigToSettings = + std::unordered_map<std::string, + std::unordered_map<std::string, std::string>>; + std::string ConvertPath(std::string const& path, bool forceRelative); std::string CalcCondition(const std::string& config) const; void WriteProjectConfigurations(Elem& e0); @@ -66,12 +70,15 @@ private: void WriteCEDebugProjectConfigurationValues(Elem& e0); void WriteMSToolConfigurationValuesManaged(Elem& e1, std::string const& config); - void WriteHeaderSource(Elem& e1, cmSourceFile const* sf); - void WriteExtraSource(Elem& e1, cmSourceFile const* sf); + void WriteHeaderSource(Elem& e1, cmSourceFile const* sf, + ConfigToSettings const& toolSettings); + void WriteExtraSource(Elem& e1, cmSourceFile const* sf, + ConfigToSettings& toolSettings); void WriteNsightTegraConfigurationValues(Elem& e1, std::string const& config); void WriteAndroidConfigurationValues(Elem& e1, std::string const& config); void WriteSource(Elem& e2, cmSourceFile const* sf); + void FinishWritingSource(Elem& e2, ConfigToSettings const& toolSettings); void WriteExcludeFromBuild(Elem& e2, std::vector<size_t> const& exclude_configs); void WriteAllSources(Elem& e0); @@ -252,9 +259,6 @@ private: void ClassifyAllConfigSources(); void ClassifyAllConfigSource(cmGeneratorTarget::AllConfigSource const& acs); - using ConfigToSettings = - std::unordered_map<std::string, - std::unordered_map<std::string, std::string>>; std::unordered_map<std::string, ConfigToSettings> ParsedToolTargetSettings; bool PropertyIsSameInAllConfigs(const ConfigToSettings& toolSettings, const std::string& propName); diff --git a/Source/cmWhileCommand.cxx b/Source/cmWhileCommand.cxx index 327c1c7ba..b8297ce21 100644 --- a/Source/cmWhileCommand.cxx +++ b/Source/cmWhileCommand.cxx @@ -16,13 +16,14 @@ #include "cmListFileCache.h" #include "cmMakefile.h" #include "cmMessageType.h" +#include "cmOutputConverter.h" #include "cmSystemTools.h" #include "cmake.h" class cmWhileFunctionBlocker : public cmFunctionBlocker { public: - cmWhileFunctionBlocker(cmMakefile* mf); + cmWhileFunctionBlocker(cmMakefile* mf, std::vector<cmListFileArgument> args); ~cmWhileFunctionBlocker() override; cm::string_view StartCommandName() const override { return "while"_s; } @@ -34,14 +35,15 @@ public: bool Replay(std::vector<cmListFileFunction> functions, cmExecutionStatus& inStatus) override; - std::vector<cmListFileArgument> Args; - private: cmMakefile* Makefile; + std::vector<cmListFileArgument> Args; }; -cmWhileFunctionBlocker::cmWhileFunctionBlocker(cmMakefile* mf) - : Makefile(mf) +cmWhileFunctionBlocker::cmWhileFunctionBlocker( + cmMakefile* const mf, std::vector<cmListFileArgument> args) + : Makefile{ mf } + , Args{ std::move(args) } { this->Makefile->PushLoopBlock(); } @@ -60,39 +62,29 @@ bool cmWhileFunctionBlocker::ArgumentsMatch(cmListFileFunction const& lff, bool cmWhileFunctionBlocker::Replay(std::vector<cmListFileFunction> functions, cmExecutionStatus& inStatus) { - cmMakefile& mf = inStatus.GetMakefile(); - std::string errorString; - - std::vector<cmExpandedCommandArgument> expandedArguments; - mf.ExpandArguments(this->Args, expandedArguments); - MessageType messageType; + auto& mf = inStatus.GetMakefile(); cmListFileBacktrace whileBT = mf.GetBacktrace().Push(this->GetStartingContext()); - cmConditionEvaluator conditionEvaluator(mf, whileBT); - - bool isTrue = - conditionEvaluator.IsTrue(expandedArguments, errorString, messageType); - - while (isTrue) { - if (!errorString.empty()) { - std::string err = "had incorrect arguments: "; - for (cmListFileArgument const& arg : this->Args) { - err += (arg.Delim ? "\"" : ""); - err += arg.Value; - err += (arg.Delim ? "\"" : ""); - err += " "; - } - err += "("; - err += errorString; - err += ")."; - mf.GetCMakeInstance()->IssueMessage(messageType, err, whileBT); - if (messageType == MessageType::FATAL_ERROR) { - cmSystemTools::SetFatalErrorOccured(); - return true; - } - } + std::vector<cmExpandedCommandArgument> expandedArguments; + // At least same size expected for `expandedArguments` as `Args` + expandedArguments.reserve(this->Args.size()); + + auto expandArgs = [&mf](std::vector<cmListFileArgument> const& args, + std::vector<cmExpandedCommandArgument>& out) + -> std::vector<cmExpandedCommandArgument>& { + out.clear(); + mf.ExpandArguments(args, out); + return out; + }; + + std::string errorString; + MessageType messageType; + + for (cmConditionEvaluator conditionEvaluator(mf, whileBT); + conditionEvaluator.IsTrue(expandArgs(this->Args, expandedArguments), + errorString, messageType);) { // Invoke all the functions that were collected in the block. for (cmListFileFunction const& fn : functions) { cmExecutionStatus status(mf); @@ -111,11 +103,22 @@ bool cmWhileFunctionBlocker::Replay(std::vector<cmListFileFunction> functions, return true; } } - expandedArguments.clear(); - mf.ExpandArguments(this->Args, expandedArguments); - isTrue = - conditionEvaluator.IsTrue(expandedArguments, errorString, messageType); } + + if (!errorString.empty()) { + std::string err = "had incorrect arguments:\n "; + for (auto const& i : expandedArguments) { + err += " "; + err += cmOutputConverter::EscapeForCMake(i.GetValue()); + } + err += "\n"; + err += errorString; + mf.GetCMakeInstance()->IssueMessage(messageType, err, whileBT); + if (messageType == MessageType::FATAL_ERROR) { + cmSystemTools::SetFatalErrorOccured(); + } + } + return true; } @@ -128,11 +131,9 @@ bool cmWhileCommand(std::vector<cmListFileArgument> const& args, } // create a function blocker - { - cmMakefile& makefile = status.GetMakefile(); - auto fb = cm::make_unique<cmWhileFunctionBlocker>(&makefile); - fb->Args = args; - makefile.AddFunctionBlocker(std::move(fb)); - } + auto& makefile = status.GetMakefile(); + makefile.AddFunctionBlocker( + cm::make_unique<cmWhileFunctionBlocker>(&makefile, args)); + return true; } diff --git a/Source/cmWorkerPool.h b/Source/cmWorkerPool.h index ff255261d..403565016 100644 --- a/Source/cmWorkerPool.h +++ b/Source/cmWorkerPool.h @@ -87,7 +87,7 @@ public: * Get the user data. * Only valid during the JobT::Process() call! */ - void* UserData() const { return this->Pool_->UserData(); }; + void* UserData() const { return this->Pool_->UserData(); } /** * Get the worker index. @@ -138,7 +138,7 @@ public: { } //! Does nothing - void Process() override{}; + void Process() override {} }; /** diff --git a/Source/cmXCodeScheme.cxx b/Source/cmXCodeScheme.cxx index e4329afc6..e2c0f2daf 100644 --- a/Source/cmXCodeScheme.cxx +++ b/Source/cmXCodeScheme.cxx @@ -204,7 +204,7 @@ void cmXCodeScheme::WriteLaunchAction(cmXMLWriter& xout, // Info tab begin - if (cmProp exe = + if (cmValue exe = this->Target->GetTarget()->GetProperty("XCODE_SCHEME_EXECUTABLE")) { xout.StartElement("PathRunnable"); @@ -220,7 +220,7 @@ void cmXCodeScheme::WriteLaunchAction(cmXMLWriter& xout, // Arguments tab begin - if (cmProp argList = + if (cmValue argList = this->Target->GetTarget()->GetProperty("XCODE_SCHEME_ARGUMENTS")) { std::vector<std::string> arguments = cmExpandedList(*argList); if (!arguments.empty()) { @@ -240,7 +240,7 @@ void cmXCodeScheme::WriteLaunchAction(cmXMLWriter& xout, } } - if (cmProp envList = + if (cmValue envList = this->Target->GetTarget()->GetProperty("XCODE_SCHEME_ENVIRONMENT")) { std::vector<std::string> envs = cmExpandedList(*envList); if (!envs.empty()) { @@ -323,7 +323,7 @@ bool cmXCodeScheme::WriteLaunchActionBooleanAttribute( cmXMLWriter& xout, const std::string& attrName, const std::string& varName, bool defaultValue) { - cmProp property = Target->GetTarget()->GetProperty(varName); + cmValue property = Target->GetTarget()->GetProperty(varName); bool isOn = (!property && defaultValue) || cmIsOn(property); if (isOn) { diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 73f5ad5b8..fda790091 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -114,7 +114,9 @@ # include "cmExtraSublimeTextGenerator.h" #endif -#if defined(__linux__) || defined(_WIN32) +// NOTE: the __linux__ macro is predefined on Android host too, but +// main CMakeLists.txt filters out this generator by host name. +#if (defined(__linux__) && !defined(__ANDROID__)) || defined(_WIN32) # include "cmGlobalGhsMultiGenerator.h" #endif @@ -156,17 +158,16 @@ static void cmWarnUnusedCliWarning(const std::string& variable, int /*unused*/, } #endif -cmake::cmake(Role role, cmState::Mode mode) +cmake::cmake(Role role, cmState::Mode mode, cmState::ProjectKind projectKind) : CMakeWorkingDirectory(cmSystemTools::GetCurrentWorkingDirectory()) , FileTimeCache(cm::make_unique<cmFileTimeCache>()) #ifndef CMAKE_BOOTSTRAP , VariableWatch(cm::make_unique<cmVariableWatch>()) #endif - , State(cm::make_unique<cmState>()) + , State(cm::make_unique<cmState>(mode, projectKind)) , Messenger(cm::make_unique<cmMessenger>()) { this->TraceFile.close(); - this->State->SetMode(mode); this->CurrentSnapshot = this->State->CreateBaseSnapshot(); #ifdef __APPLE__ @@ -598,15 +599,14 @@ void cmake::ProcessCacheArg(const std::string& var, const std::string& value, bool haveValue = false; std::string cachedValue; if (this->WarnUnusedCli) { - if (cmProp v = this->State->GetInitializedCacheValue(var)) { + if (cmValue v = this->State->GetInitializedCacheValue(var)) { haveValue = true; cachedValue = *v; } } - this->AddCacheEntry(var, value.c_str(), - "No help, variable specified on the command line.", - type); + this->AddCacheEntry( + var, value, "No help, variable specified on the command line.", type); if (this->WarnUnusedCli) { if (!haveValue || @@ -1468,7 +1468,7 @@ void cmake::SetDirectoriesFromFile(const std::string& arg) // If there is a CMakeCache.txt file, use its settings. if (!cachePath.empty()) { if (this->LoadCache(cachePath)) { - cmProp existingValue = + cmValue existingValue = this->State->GetCacheEntryValue("CMAKE_HOME_DIRECTORY"); if (existingValue) { this->SetHomeOutputDirectory(cachePath); @@ -1516,16 +1516,15 @@ void cmake::SetDirectoriesFromFile(const std::string& arg) int cmake::AddCMakePaths() { // Save the value in the cache - this->AddCacheEntry("CMAKE_COMMAND", - cmSystemTools::GetCMakeCommand().c_str(), + this->AddCacheEntry("CMAKE_COMMAND", cmSystemTools::GetCMakeCommand(), "Path to CMake executable.", cmStateEnums::INTERNAL); #ifndef CMAKE_BOOTSTRAP - this->AddCacheEntry( - "CMAKE_CTEST_COMMAND", cmSystemTools::GetCTestCommand().c_str(), - "Path to ctest program executable.", cmStateEnums::INTERNAL); - this->AddCacheEntry( - "CMAKE_CPACK_COMMAND", cmSystemTools::GetCPackCommand().c_str(), - "Path to cpack program executable.", cmStateEnums::INTERNAL); + this->AddCacheEntry("CMAKE_CTEST_COMMAND", cmSystemTools::GetCTestCommand(), + "Path to ctest program executable.", + cmStateEnums::INTERNAL); + this->AddCacheEntry("CMAKE_CPACK_COMMAND", cmSystemTools::GetCPackCommand(), + "Path to cpack program executable.", + cmStateEnums::INTERNAL); #endif if (!cmSystemTools::FileExists( (cmSystemTools::GetCMakeRoot() + "/Modules/CMake.cmake"))) { @@ -1537,7 +1536,7 @@ int cmake::AddCMakePaths() cmSystemTools::GetCMakeRoot()); return 0; } - this->AddCacheEntry("CMAKE_ROOT", cmSystemTools::GetCMakeRoot().c_str(), + this->AddCacheEntry("CMAKE_ROOT", cmSystemTools::GetCMakeRoot(), "Path to CMake installation.", cmStateEnums::INTERNAL); return 1; @@ -1843,7 +1842,7 @@ int cmake::HandleDeleteCacheVariables(const std::string& var) std::vector<std::string> argsSplit = cmExpandedList(var, true); // erase the property to avoid infinite recursion this->State->SetGlobalProperty("__CMAKE_DELETE_CACHE_CHANGE_VARS_", ""); - if (this->State->GetIsInTryCompile()) { + if (this->GetIsInTryCompile()) { return 0; } std::vector<SaveCacheEntry> saved; @@ -1866,10 +1865,10 @@ int cmake::HandleDeleteCacheVariables(const std::string& var) warning << "\n"; i -= 1; } - cmProp existingValue = this->State->GetCacheEntryValue(save.key); + cmValue existingValue = this->State->GetCacheEntryValue(save.key); if (existingValue) { save.type = this->State->GetCacheEntryType(save.key); - if (cmProp help = + if (cmValue help = this->State->GetCacheEntryProperty(save.key, "HELPSTRING")) { save.help = *help; } @@ -1885,7 +1884,7 @@ int cmake::HandleDeleteCacheVariables(const std::string& var) this->LoadCache(); // restore the changed compilers for (SaveCacheEntry const& i : saved) { - this->AddCacheEntry(i.key, i.value.c_str(), i.help.c_str(), i.type); + this->AddCacheEntry(i.key, i.value, i.help.c_str(), i.type); } cmSystemTools::Message(warning.str()); // avoid reconfigure if there were errors @@ -1918,9 +1917,9 @@ int cmake::Configure() if (this->DiagLevels.count("dev") == 1) { bool setDeprecatedVariables = false; - cmProp cachedWarnDeprecated = + cmValue cachedWarnDeprecated = this->State->GetCacheEntryValue("CMAKE_WARN_DEPRECATED"); - cmProp cachedErrorDeprecated = + cmValue cachedErrorDeprecated = this->State->GetCacheEntryValue("CMAKE_ERROR_DEPRECATED"); // don't overwrite deprecated warning setting from a previous invocation @@ -1959,7 +1958,7 @@ int cmake::Configure() // Cache variables may have already been set by a previous invocation, // so we cannot rely on command line options alone. Always ensure our // messenger is in sync with the cache. - cmProp value = this->State->GetCacheEntryValue("CMAKE_WARN_DEPRECATED"); + cmValue value = this->State->GetCacheEntryValue("CMAKE_WARN_DEPRECATED"); this->Messenger->SetSuppressDeprecatedWarnings(value && cmIsOff(*value)); value = this->State->GetCacheEntryValue("CMAKE_ERROR_DEPRECATED"); @@ -1972,7 +1971,7 @@ int cmake::Configure() this->Messenger->SetDevWarningsAsErrors(value && cmIsOff(*value)); int ret = this->ActualConfigure(); - cmProp delCacheVars = + cmValue delCacheVars = this->State->GetGlobalProperty("__CMAKE_DELETE_CACHE_CHANGE_VARS_"); if (delCacheVars && !delCacheVars->empty()) { return this->HandleDeleteCacheVariables(*delCacheVars); @@ -1992,7 +1991,7 @@ int cmake::ActualConfigure() } if (!res) { this->AddCacheEntry( - "CMAKE_HOME_DIRECTORY", this->GetHomeDirectory().c_str(), + "CMAKE_HOME_DIRECTORY", this->GetHomeDirectory(), "Source directory with the top level CMakeLists.txt file for this " "project", cmStateEnums::INTERNAL); @@ -2000,8 +1999,8 @@ int cmake::ActualConfigure() // no generator specified on the command line if (!this->GlobalGenerator) { - cmProp genName = this->State->GetInitializedCacheValue("CMAKE_GENERATOR"); - cmProp extraGenName = + cmValue genName = this->State->GetInitializedCacheValue("CMAKE_GENERATOR"); + cmValue extraGenName = this->State->GetInitializedCacheValue("CMAKE_EXTRA_GENERATOR"); if (genName) { std::string fullName = @@ -2024,7 +2023,7 @@ int cmake::ActualConfigure() } } - cmProp genName = this->State->GetInitializedCacheValue("CMAKE_GENERATOR"); + cmValue genName = this->State->GetInitializedCacheValue("CMAKE_GENERATOR"); if (genName) { if (!this->GlobalGenerator->MatchesGeneratorName(*genName)) { std::string message = @@ -2037,26 +2036,24 @@ int cmake::ActualConfigure() } } if (!this->State->GetInitializedCacheValue("CMAKE_GENERATOR")) { - this->AddCacheEntry("CMAKE_GENERATOR", - this->GlobalGenerator->GetName().c_str(), + this->AddCacheEntry("CMAKE_GENERATOR", this->GlobalGenerator->GetName(), "Name of generator.", cmStateEnums::INTERNAL); - this->AddCacheEntry("CMAKE_EXTRA_GENERATOR", - this->GlobalGenerator->GetExtraGeneratorName().c_str(), - "Name of external makefile project generator.", - cmStateEnums::INTERNAL); + this->AddCacheEntry( + "CMAKE_EXTRA_GENERATOR", this->GlobalGenerator->GetExtraGeneratorName(), + "Name of external makefile project generator.", cmStateEnums::INTERNAL); if (!this->State->GetInitializedCacheValue("CMAKE_TOOLCHAIN_FILE")) { std::string envToolchain; if (cmSystemTools::GetEnv("CMAKE_TOOLCHAIN_FILE", envToolchain) && !envToolchain.empty()) { - this->AddCacheEntry("CMAKE_TOOLCHAIN_FILE", envToolchain.c_str(), + this->AddCacheEntry("CMAKE_TOOLCHAIN_FILE", envToolchain, "The CMake toolchain file", cmStateEnums::FILEPATH); } } } - if (cmProp instance = + if (cmValue instance = this->State->GetInitializedCacheValue("CMAKE_GENERATOR_INSTANCE")) { if (this->GeneratorInstanceSet && this->GeneratorInstance != *instance) { std::string message = @@ -2068,12 +2065,12 @@ int cmake::ActualConfigure() return -2; } } else { - this->AddCacheEntry( - "CMAKE_GENERATOR_INSTANCE", this->GeneratorInstance.c_str(), - "Generator instance identifier.", cmStateEnums::INTERNAL); + this->AddCacheEntry("CMAKE_GENERATOR_INSTANCE", this->GeneratorInstance, + "Generator instance identifier.", + cmStateEnums::INTERNAL); } - if (cmProp platformName = + if (cmValue platformName = this->State->GetInitializedCacheValue("CMAKE_GENERATOR_PLATFORM")) { if (this->GeneratorPlatformSet && this->GeneratorPlatform != *platformName) { @@ -2086,12 +2083,11 @@ int cmake::ActualConfigure() return -2; } } else { - this->AddCacheEntry("CMAKE_GENERATOR_PLATFORM", - this->GeneratorPlatform.c_str(), + this->AddCacheEntry("CMAKE_GENERATOR_PLATFORM", this->GeneratorPlatform, "Name of generator platform.", cmStateEnums::INTERNAL); } - if (cmProp tsName = + if (cmValue tsName = this->State->GetInitializedCacheValue("CMAKE_GENERATOR_TOOLSET")) { if (this->GeneratorToolsetSet && this->GeneratorToolset != *tsName) { std::string message = @@ -2103,15 +2099,14 @@ int cmake::ActualConfigure() return -2; } } else { - this->AddCacheEntry("CMAKE_GENERATOR_TOOLSET", - this->GeneratorToolset.c_str(), + this->AddCacheEntry("CMAKE_GENERATOR_TOOLSET", this->GeneratorToolset, "Name of generator toolset.", cmStateEnums::INTERNAL); } // reset any system configuration information, except for when we are // InTryCompile. With TryCompile the system info is taken from the parent's // info to save time - if (!this->State->GetIsInTryCompile()) { + if (!this->GetIsInTryCompile()) { this->GlobalGenerator->ClearEnabledLanguages(); this->TruncateOutputLog("CMakeOutput.log"); @@ -2415,7 +2410,7 @@ int cmake::Generate() return 0; } -void cmake::AddCacheEntry(const std::string& key, const char* value, +void cmake::AddCacheEntry(const std::string& key, cmValue value, const char* helpString, int type) { this->State->AddCacheEntry(key, value, helpString, @@ -2491,7 +2486,7 @@ std::string cmake::StripExtension(const std::string& file) const return file; } -cmProp cmake::GetCacheDefinition(const std::string& name) const +cmValue cmake::GetCacheDefinition(const std::string& name) const { return this->State->GetInitializedCacheValue(name); } @@ -2529,7 +2524,7 @@ void cmake::AddDefaultGenerators() this->Generators.push_back(cmGlobalMinGWMakefileGenerator::NewFactory()); #endif #if !defined(CMAKE_BOOTSTRAP) -# if defined(__linux__) || defined(_WIN32) +# if (defined(__linux__) && !defined(__ANDROID__)) || defined(_WIN32) this->Generators.push_back(cmGlobalGhsMultiGenerator::NewFactory()); # endif this->Generators.push_back(cmGlobalUnixMakefileGenerator3::NewFactory()); @@ -2622,19 +2617,14 @@ void cmake::SetProgressCallback(ProgressCallbackType f) void cmake::UpdateProgress(const std::string& msg, float prog) { - if (this->ProgressCallback && !this->State->GetIsInTryCompile()) { + if (this->ProgressCallback && !this->GetIsInTryCompile()) { this->ProgressCallback(msg, prog); } } bool cmake::GetIsInTryCompile() const { - return this->State->GetIsInTryCompile(); -} - -void cmake::SetIsInTryCompile(bool b) -{ - this->State->SetIsInTryCompile(b); + return this->State->GetProjectKind() == cmState::ProjectKind::TryCompile; } void cmake::AppendGlobalGeneratorsDocumentation( @@ -2705,7 +2695,7 @@ void cmake::PrintGeneratorList() void cmake::UpdateConversionPathTable() { // Update the path conversion table with any specified file: - cmProp tablepath = + cmValue tablepath = this->State->GetInitializedCacheValue("CMAKE_PATH_TRANSLATION_FILE"); if (tablepath) { @@ -2923,6 +2913,10 @@ void cmake::SetProperty(const std::string& prop, const char* value) { this->State->SetGlobalProperty(prop, value); } +void cmake::SetProperty(const std::string& prop, cmValue value) +{ + this->State->SetGlobalProperty(prop, value); +} void cmake::AppendProperty(const std::string& prop, const std::string& value, bool asString) @@ -2930,7 +2924,7 @@ void cmake::AppendProperty(const std::string& prop, const std::string& value, this->State->AppendGlobalProperty(prop, value, asString); } -cmProp cmake::GetProperty(const std::string& prop) +cmValue cmake::GetProperty(const std::string& prop) { return this->State->GetGlobalProperty(prop); } @@ -3175,7 +3169,7 @@ void cmake::IssueMessage(MessageType t, std::string const& text, std::vector<std::string> cmake::GetDebugConfigs() { std::vector<std::string> configs; - if (cmProp config_list = + if (cmValue config_list = this->State->GetGlobalProperty("DEBUG_CONFIGURATIONS")) { // Expand the specified list and convert to upper-case. cmExpandList(*config_list, configs); @@ -3324,7 +3318,7 @@ int cmake::Build(int jobs, std::string dir, std::vector<std::string> targets, std::cerr << "Error: could not load cache\n"; return 1; } - cmProp cachedGenerator = this->State->GetCacheEntryValue("CMAKE_GENERATOR"); + cmValue cachedGenerator = this->State->GetCacheEntryValue("CMAKE_GENERATOR"); if (!cachedGenerator) { std::cerr << "Error: could not find CMAKE_GENERATOR in Cache\n"; return 1; @@ -3336,7 +3330,7 @@ int cmake::Build(int jobs, std::string dir, std::vector<std::string> targets, return 1; } this->SetGlobalGenerator(std::move(gen)); - cmProp cachedGeneratorInstance = + cmValue cachedGeneratorInstance = this->State->GetCacheEntryValue("CMAKE_GENERATOR_INSTANCE"); if (cachedGeneratorInstance) { cmMakefile mf(this->GetGlobalGenerator(), this->GetCurrentSnapshot()); @@ -3345,7 +3339,7 @@ int cmake::Build(int jobs, std::string dir, std::vector<std::string> targets, return 1; } } - cmProp cachedGeneratorPlatform = + cmValue cachedGeneratorPlatform = this->State->GetCacheEntryValue("CMAKE_GENERATOR_PLATFORM"); if (cachedGeneratorPlatform) { cmMakefile mf(this->GetGlobalGenerator(), this->GetCurrentSnapshot()); @@ -3354,7 +3348,7 @@ int cmake::Build(int jobs, std::string dir, std::vector<std::string> targets, return 1; } } - cmProp cachedGeneratorToolset = + cmValue cachedGeneratorToolset = this->State->GetCacheEntryValue("CMAKE_GENERATOR_TOOLSET"); if (cachedGeneratorToolset) { cmMakefile mf(this->GetGlobalGenerator(), this->GetCurrentSnapshot()); @@ -3365,7 +3359,7 @@ int cmake::Build(int jobs, std::string dir, std::vector<std::string> targets, } std::string output; std::string projName; - cmProp cachedProjectName = + cmValue cachedProjectName = this->State->GetCacheEntryValue("CMAKE_PROJECT_NAME"); if (!cachedProjectName) { std::cerr << "Error: could not find CMAKE_PROJECT_NAME in Cache\n"; @@ -3457,12 +3451,12 @@ bool cmake::Open(const std::string& dir, bool dryRun) std::cerr << "Error: could not load cache\n"; return false; } - cmProp genName = this->State->GetCacheEntryValue("CMAKE_GENERATOR"); + cmValue genName = this->State->GetCacheEntryValue("CMAKE_GENERATOR"); if (!genName) { std::cerr << "Error: could not find CMAKE_GENERATOR in Cache\n"; return false; } - cmProp extraGenName = + cmValue extraGenName = this->State->GetInitializedCacheValue("CMAKE_EXTRA_GENERATOR"); std::string fullName = cmExternalMakefileProjectGenerator::CreateFullGeneratorName( @@ -3476,7 +3470,7 @@ bool cmake::Open(const std::string& dir, bool dryRun) return false; } - cmProp cachedProjectName = + cmValue cachedProjectName = this->State->GetCacheEntryValue("CMAKE_PROJECT_NAME"); if (!cachedProjectName) { std::cerr << "Error: could not find CMAKE_PROJECT_NAME in Cache\n"; @@ -3540,7 +3534,7 @@ void cmake::SetSuppressDevWarnings(bool b) value = "FALSE"; } - this->AddCacheEntry("CMAKE_SUPPRESS_DEVELOPER_WARNINGS", value.c_str(), + this->AddCacheEntry("CMAKE_SUPPRESS_DEVELOPER_WARNINGS", value, "Suppress Warnings that are meant for" " the author of the CMakeLists.txt files.", cmStateEnums::INTERNAL); @@ -3564,7 +3558,7 @@ void cmake::SetSuppressDeprecatedWarnings(bool b) value = "TRUE"; } - this->AddCacheEntry("CMAKE_WARN_DEPRECATED", value.c_str(), + this->AddCacheEntry("CMAKE_WARN_DEPRECATED", value, "Whether to issue warnings for deprecated " "functionality.", cmStateEnums::INTERNAL); @@ -3588,7 +3582,7 @@ void cmake::SetDevWarningsAsErrors(bool b) value = "TRUE"; } - this->AddCacheEntry("CMAKE_SUPPRESS_DEVELOPER_ERRORS", value.c_str(), + this->AddCacheEntry("CMAKE_SUPPRESS_DEVELOPER_ERRORS", value, "Suppress errors that are meant for" " the author of the CMakeLists.txt files.", cmStateEnums::INTERNAL); @@ -3612,7 +3606,7 @@ void cmake::SetDeprecatedWarningsAsErrors(bool b) value = "FALSE"; } - this->AddCacheEntry("CMAKE_ERROR_DEPRECATED", value.c_str(), + this->AddCacheEntry("CMAKE_ERROR_DEPRECATED", value, "Whether to issue deprecation errors for macros" " and functions.", cmStateEnums::INTERNAL); diff --git a/Source/cmake.h b/Source/cmake.h index 5a2a88fac..3f2b2eda4 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -21,10 +21,10 @@ #include "cmInstalledFile.h" #include "cmListFileCache.h" #include "cmMessageType.h" -#include "cmProperty.h" #include "cmState.h" #include "cmStateSnapshot.h" #include "cmStateTypes.h" +#include "cmValue.h" #if !defined(CMAKE_BOOTSTRAP) # include <cm/optional> @@ -168,7 +168,8 @@ public: static const int DEFAULT_BUILD_PARALLEL_LEVEL = 0; /// Default constructor - cmake(Role role, cmState::Mode mode); + cmake(Role role, cmState::Mode mode, + cmState::ProjectKind projectKind = cmState::ProjectKind::Normal); /// Destructor ~cmake(); @@ -328,9 +329,21 @@ public: /** * Given a variable name, return its value (as a string). */ - cmProp GetCacheDefinition(const std::string&) const; + cmValue GetCacheDefinition(const std::string&) const; //! Add an entry into the cache void AddCacheEntry(const std::string& key, const char* value, + const char* helpString, int type) + { + this->AddCacheEntry(key, + value ? cmValue(std::string(value)) : cmValue(nullptr), + helpString, type); + } + void AddCacheEntry(const std::string& key, const std::string& value, + const char* helpString, int type) + { + this->AddCacheEntry(key, cmValue(value), helpString, type); + } + void AddCacheEntry(const std::string& key, cmValue value, const char* helpString, int type); bool DoWriteGlobVerifyTarget() const; @@ -356,7 +369,6 @@ public: //! Is this cmake running as a result of a TRY_COMPILE command bool GetIsInTryCompile() const; - void SetIsInTryCompile(bool b); #ifndef CMAKE_BOOTSTRAP void SetWarningFromPreset(const std::string& name, @@ -396,9 +408,14 @@ public: //! Set/Get a property of this target file void SetProperty(const std::string& prop, const char* value); + void SetProperty(const std::string& prop, cmValue value); + void SetProperty(const std::string& prop, const std::string& value) + { + this->SetProperty(prop, cmValue(value)); + } void AppendProperty(const std::string& prop, const std::string& value, bool asString = false); - cmProp GetProperty(const std::string& prop); + cmValue GetProperty(const std::string& prop); bool GetPropertyAsBool(const std::string& prop); //! Get or create an cmInstalledFile instance and return a pointer to it diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index 95ad32048..61d4ae486 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -25,11 +25,11 @@ #include "cmGlobalGenerator.h" #include "cmMakefile.h" #include "cmMessageMetadata.h" -#include "cmProperty.h" #include "cmState.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmValue.h" #include "cmake.h" #include "cmcmd.h" @@ -161,11 +161,11 @@ void cmakemainMessageCallback(const std::string& m, // cannot use it to print messages. Another implementation will // be needed to print colored messages on Windows. static_cast<void>(md); - std::cerr << m << cmakemainGetStack(cm) << '\n' << std::flush; + std::cerr << m << cmakemainGetStack(cm) << "\n"; #else cmsysTerminal_cfprintf(md.desiredColor, stderr, "%s", m.c_str()); fflush(stderr); // stderr is buffered in some cases. - std::cerr << cmakemainGetStack(cm) << '\n' << std::flush; + std::cerr << cmakemainGetStack(cm) << "\n"; #endif } @@ -375,11 +375,11 @@ int do_cmake(int ac, char const* const* av) cmStateEnums::CacheEntryType t = cm.GetState()->GetCacheEntryType(k); if (t != cmStateEnums::INTERNAL && t != cmStateEnums::STATIC && t != cmStateEnums::UNINITIALIZED) { - cmProp advancedProp = + cmValue advancedProp = cm.GetState()->GetCacheEntryProperty(k, "ADVANCED"); if (list_all_cached || !advancedProp) { if (list_help) { - cmProp help = + cmValue help = cm.GetState()->GetCacheEntryProperty(k, "HELPSTRING"); std::cout << "// " << (help ? *help : "") << std::endl; } diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index db45add4f..bdddc4e78 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -23,6 +23,7 @@ #include "cmTransformDepfile.h" #include "cmUVProcessChain.h" #include "cmUtils.hxx" +#include "cmValue.h" #include "cmVersion.h" #include "cmake.h" @@ -385,18 +386,15 @@ int HandleTidy(const std::string& runCmd, const std::string& sourceFile, return ret; } -int HandleLWYU(const std::string& runCmd, const std::string& /* sourceFile */, +int HandleLWYU(const std::string& runCmd, const std::string& sourceFile, const std::vector<std::string>&) { // Construct the ldd -r -u (link what you use lwyu) command line // ldd -u -r lwuy target - std::vector<std::string> lwyu_cmd; - lwyu_cmd.emplace_back("ldd"); - lwyu_cmd.emplace_back("-u"); - lwyu_cmd.emplace_back("-r"); - lwyu_cmd.push_back(runCmd); + std::vector<std::string> lwyu_cmd = cmExpandedList(runCmd, true); + lwyu_cmd.push_back(sourceFile); - // Run the ldd -u -r command line. + // Run the lwyu check command line, currently ldd is expected. // Capture its stdout and hide its stderr. // Ignore its return code because the tool always returns non-zero // if there are any warnings, but we just want to warn. @@ -1071,6 +1069,8 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args, } else if (!cmSystemTools::FileExists(arg)) { cmSystemTools::Error(arg + ": no such file or directory (ignoring)"); return_value = 1; + } else if (cmSystemTools::FileLength(arg) == 0) { + // Ignore empty files, this is not an error } else { // Destroy console buffers to drop cout/cerr encoding transform. consoleBuf.reset(); diff --git a/Source/kwsys/Status.hxx.in b/Source/kwsys/Status.hxx.in index ed46d5c2b..16efaefdf 100644 --- a/Source/kwsys/Status.hxx.in +++ b/Source/kwsys/Status.hxx.in @@ -55,7 +55,10 @@ public: #endif /** Return true on "Success", false otherwise. */ - explicit operator bool() const { return this->Kind_ == Kind::Success; } + bool IsSuccess() const { return this->Kind_ == Kind::Success; } + + /** Return true on "Success", false otherwise. */ + explicit operator bool() const { return this->IsSuccess(); } /** Return the kind of status. */ Kind GetKind() const { return this->Kind_; } diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx index 12f9139cc..f2bf85f6a 100644 --- a/Source/kwsys/SystemInformation.cxx +++ b/Source/kwsys/SystemInformation.cxx @@ -1356,14 +1356,12 @@ std::string SymbolProperties::Demangle(const char* symbol) const std::string result = safes(symbol); # if defined(KWSYS_SYSTEMINFORMATION_HAS_CPP_DEMANGLE) int status = 0; - size_t bufferLen = 1024; - char* buffer = (char*)malloc(1024); char* demangledSymbol = - abi::__cxa_demangle(symbol, buffer, &bufferLen, &status); + abi::__cxa_demangle(symbol, nullptr, nullptr, &status); if (!status) { result = demangledSymbol; } - free(buffer); + free(demangledSymbol); # else (void)symbol; # endif diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx index f610a7050..930d84c87 100644 --- a/Source/kwsys/SystemTools.cxx +++ b/Source/kwsys/SystemTools.cxx @@ -2423,7 +2423,7 @@ Status SystemTools::CopyFileAlways(std::string const& source, if (SystemTools::FileIsDirectory(source)) { status = SystemTools::MakeDirectory(destination); - if (!status) { + if (!status.IsSuccess()) { return status; } } else { @@ -2448,17 +2448,17 @@ Status SystemTools::CopyFileAlways(std::string const& source, // Create destination directory if (!destination_dir.empty()) { status = SystemTools::MakeDirectory(destination_dir); - if (!status) { + if (!status.IsSuccess()) { return status; } } status = SystemTools::CloneFileContent(source, real_destination); // if cloning did not succeed, fall back to blockwise copy - if (!status) { + if (!status.IsSuccess()) { status = SystemTools::CopyFileContentBlockwise(source, real_destination); } - if (!status) { + if (!status.IsSuccess()) { return status; } } @@ -2488,11 +2488,11 @@ Status SystemTools::CopyADirectory(std::string const& source, Status status; Directory dir; status = dir.Load(source); - if (!status) { + if (!status.IsSuccess()) { return status; } status = SystemTools::MakeDirectory(destination); - if (!status) { + if (!status.IsSuccess()) { return status; } @@ -2507,12 +2507,12 @@ Status SystemTools::CopyADirectory(std::string const& source, fullDestPath += "/"; fullDestPath += dir.GetFile(static_cast<unsigned long>(fileNum)); status = SystemTools::CopyADirectory(fullPath, fullDestPath, always); - if (!status) { + if (!status.IsSuccess()) { return status; } } else { status = SystemTools::CopyAFile(fullPath, destination, always); - if (!status) { + if (!status.IsSuccess()) { return status; } } @@ -2664,7 +2664,7 @@ Status SystemTools::RemoveADirectory(std::string const& source) Status status; Directory dir; status = dir.Load(source); - if (!status) { + if (!status.IsSuccess()) { return status; } @@ -2678,12 +2678,12 @@ Status SystemTools::RemoveADirectory(std::string const& source) if (SystemTools::FileIsDirectory(fullPath) && !SystemTools::FileIsSymlink(fullPath)) { status = SystemTools::RemoveADirectory(fullPath); - if (!status) { + if (!status.IsSuccess()) { return status; } } else { status = SystemTools::RemoveFile(fullPath); - if (!status) { + if (!status.IsSuccess()) { return status; } } @@ -3147,7 +3147,7 @@ Status SystemTools::ReadSymlink(std::string const& newName, status = Status::Windows_GetLastError(); } CloseHandle(hFile); - if (!status) { + if (!status.IsSuccess()) { return status; } PREPARSE_DATA_BUFFER data = diff --git a/Source/kwsys/testDirectory.cxx b/Source/kwsys/testDirectory.cxx index 06a22dc47..a847462a3 100644 --- a/Source/kwsys/testDirectory.cxx +++ b/Source/kwsys/testDirectory.cxx @@ -122,7 +122,7 @@ int _copyDirectoryTest() } const Status copysuccess = SystemTools::CopyADirectory(source, destination); const bool destinationexists = SystemTools::PathExists(destination); - if (copysuccess) { + if (copysuccess.IsSuccess()) { std::cerr << "CopyADirectory should have returned false" << std::endl; SystemTools::RemoveADirectory(destination); return 3; diff --git a/Source/kwsys/testStatus.cxx b/Source/kwsys/testStatus.cxx index f85ef422d..0a767a854 100644 --- a/Source/kwsys/testStatus.cxx +++ b/Source/kwsys/testStatus.cxx @@ -31,6 +31,10 @@ int testStatus(int, char* []) std::cerr << "Status Success constructor does not produce Success\n"; res = false; } + if (!status.IsSuccess()) { + std::cerr << "Status Success gives false IsSuccess\n"; + res = false; + } if (!status) { std::cerr << "Status Success kind is not true\n"; res = false; @@ -55,6 +59,10 @@ int testStatus(int, char* []) std::cerr << "Status POSIX constructor does not produce POSIX\n"; res = false; } + if (status.IsSuccess()) { + std::cerr << "Status POSIX gives true IsSuccess\n"; + res = false; + } if (status) { std::cerr << "Status POSIX kind is not false\n"; res = false; @@ -87,6 +95,10 @@ int testStatus(int, char* []) std::cerr << "Status Windows constructor does not produce Windows\n"; res = false; } + if (status.IsSuccess()) { + std::cerr << "Status Windows gives true IsSuccess\n"; + res = false; + } if (status) { std::cerr << "Status Windows kind is not false\n"; res = false; diff --git a/Source/kwsys/testSystemTools.cxx b/Source/kwsys/testSystemTools.cxx index 39a19cbf2..6ccc7a7cb 100644 --- a/Source/kwsys/testSystemTools.cxx +++ b/Source/kwsys/testSystemTools.cxx @@ -436,7 +436,7 @@ static bool CheckFileOperations() if (symlinkStatus.GetWindows() != ERROR_PRIVILEGE_NOT_HELD) #endif { - if (!symlinkStatus) { + if (!symlinkStatus.IsSuccess()) { std::cerr << "CreateSymlink for: " << testBadSymlink << " -> " << testBadSymlinkTgt << " failed: " << symlinkStatus.GetString() << std::endl; |