summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/CMakeLists.txt1
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/CPack/IFW/cmCPackIFWCommon.cxx15
-rw-r--r--Source/CPack/IFW/cmCPackIFWGenerator.cxx5
-rw-r--r--Source/CPack/IFW/cmCPackIFWInstaller.cxx1
-rw-r--r--Source/CPack/IFW/cmCPackIFWPackage.cxx11
-rw-r--r--Source/CPack/WiX/cmCPackWIXGenerator.cxx20
-rw-r--r--Source/CPack/WiX/cmWIXAccessControlList.cxx5
-rw-r--r--Source/CPack/WiX/cmWIXShortcut.cxx5
-rw-r--r--Source/CPack/cmCPackBundleGenerator.cxx3
-rw-r--r--Source/CPack/cmCPackDebGenerator.cxx4
-rw-r--r--Source/CPack/cmCPackDragNDropGenerator.cxx10
-rw-r--r--Source/CPack/cmCPackExternalGenerator.cxx4
-rw-r--r--Source/CPack/cmCPackFreeBSDGenerator.cxx27
-rw-r--r--Source/CPack/cmCPackGenerator.cxx80
-rw-r--r--Source/CPack/cmCPackGeneratorFactory.cxx5
-rw-r--r--Source/CPack/cmCPackInnoSetupGenerator.cxx1159
-rw-r--r--Source/CPack/cmCPackInnoSetupGenerator.h116
-rw-r--r--Source/CPack/cmCPackNSISGenerator.cxx36
-rw-r--r--Source/CPack/cpack.cxx5
-rw-r--r--Source/CTest/cmCTestBuildHandler.cxx1
-rw-r--r--Source/CTest/cmCTestConfigureCommand.cxx6
-rw-r--r--Source/CTest/cmCTestGIT.cxx3
-rw-r--r--Source/CTest/cmCTestP4.cxx4
-rw-r--r--Source/CTest/cmCTestScriptHandler.cxx7
-rw-r--r--Source/CTest/cmCTestSubmitCommand.cxx6
-rw-r--r--Source/CTest/cmCTestSubmitHandler.cxx5
-rw-r--r--Source/CTest/cmCTestTestHandler.cxx28
-rw-r--r--Source/CursesDialog/cmCursesCacheEntryComposite.cxx5
-rw-r--r--Source/Modules/CMakeBuildUtilities.cmake2
-rw-r--r--Source/cmCMakeHostSystemInformationCommand.cxx15
-rw-r--r--Source/cmCMakePathCommand.cxx7
-rw-r--r--Source/cmCMakePresetsGraph.cxx29
-rw-r--r--Source/cmCMakePresetsGraphInternal.h10
-rw-r--r--Source/cmCMakePresetsGraphReadJSON.cxx37
-rw-r--r--Source/cmCTest.cxx10
-rw-r--r--Source/cmCacheManager.cxx9
-rw-r--r--Source/cmCommonTargetGenerator.cxx4
-rw-r--r--Source/cmComputeLinkDepends.cxx3
-rw-r--r--Source/cmComputeLinkInformation.cxx63
-rw-r--r--Source/cmConditionEvaluator.cxx5
-rw-r--r--Source/cmCoreTryCompile.cxx7
-rw-r--r--Source/cmCoreTryCompile.h3
-rw-r--r--Source/cmCustomCommandGenerator.cxx5
-rw-r--r--Source/cmDepends.cxx5
-rw-r--r--Source/cmDependsC.cxx7
-rw-r--r--Source/cmDependsCompiler.cxx24
-rw-r--r--Source/cmDependsFortran.cxx10
-rw-r--r--Source/cmEvaluatedTargetProperty.cxx2
-rw-r--r--Source/cmExportBuildAndroidMKGenerator.cxx8
-rw-r--r--Source/cmExportFileGenerator.cxx22
-rw-r--r--Source/cmExportTryCompileFileGenerator.cxx3
-rw-r--r--Source/cmExtraCodeBlocksGenerator.cxx5
-rw-r--r--Source/cmExtraEclipseCDT4Generator.cxx11
-rw-r--r--Source/cmExtraSublimeTextGenerator.cxx3
-rw-r--r--Source/cmFileAPIToolchains.cxx8
-rw-r--r--Source/cmFileCopier.cxx4
-rw-r--r--Source/cmFileSet.cxx9
-rw-r--r--Source/cmFindBase.cxx5
-rw-r--r--Source/cmFindCommon.cxx17
-rw-r--r--Source/cmFindLibraryCommand.cxx16
-rw-r--r--Source/cmFindPackageCommand.cxx36
-rw-r--r--Source/cmForEachCommand.cxx9
-rw-r--r--Source/cmGccDepfileLexerHelper.cxx6
-rw-r--r--Source/cmGeneratorExpression.cxx1
-rw-r--r--Source/cmGeneratorExpressionNode.cxx750
-rw-r--r--Source/cmGeneratorTarget.cxx223
-rw-r--r--Source/cmGeneratorTarget.h5
-rw-r--r--Source/cmGhsMultiTargetGenerator.cxx3
-rw-r--r--Source/cmGlobalGenerator.cxx52
-rw-r--r--Source/cmGlobalGenerator.h2
-rw-r--r--Source/cmGlobalGhsMultiGenerator.cxx3
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx28
-rw-r--r--Source/cmGlobalNinjaGenerator.h2
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.h6
-rw-r--r--Source/cmGlobalVisualStudio71Generator.cxx5
-rw-r--r--Source/cmGlobalVisualStudio7Generator.cxx3
-rw-r--r--Source/cmGlobalVisualStudio8Generator.cxx44
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx30
-rw-r--r--Source/cmGraphVizWriter.cxx6
-rw-r--r--Source/cmIDEOptions.cxx1
-rw-r--r--Source/cmInstallCommand.cxx11
-rw-r--r--Source/cmInstallDirectoryGenerator.cxx10
-rw-r--r--Source/cmInstallFilesGenerator.cxx14
-rw-r--r--Source/cmInstalledFile.cxx9
-rw-r--r--Source/cmInstalledFile.h3
-rw-r--r--Source/cmLDConfigLDConfigTool.cxx4
-rw-r--r--Source/cmList.cxx47
-rw-r--r--Source/cmList.h330
-rw-r--r--Source/cmListCommand.cxx4
-rw-r--r--Source/cmListFileCache.cxx7
-rw-r--r--Source/cmListFileCache.h3
-rw-r--r--Source/cmLocalCommonGenerator.cxx16
-rw-r--r--Source/cmLocalCommonGenerator.h15
-rw-r--r--Source/cmLocalGenerator.cxx116
-rw-r--r--Source/cmLocalGenerator.h11
-rw-r--r--Source/cmLocalNinjaGenerator.cxx44
-rw-r--r--Source/cmLocalNinjaGenerator.h11
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx50
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.h3
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx13
-rw-r--r--Source/cmMakefile.cxx57
-rw-r--r--Source/cmMakefile.h2
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.cxx24
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx40
-rw-r--r--Source/cmMakefileTargetGenerator.cxx77
-rw-r--r--Source/cmMakefileTargetGenerator.h2
-rw-r--r--Source/cmMessageCommand.cxx7
-rw-r--r--Source/cmNinjaNormalTargetGenerator.cxx96
-rw-r--r--Source/cmNinjaNormalTargetGenerator.h2
-rw-r--r--Source/cmNinjaTargetGenerator.cxx75
-rw-r--r--Source/cmOutputConverter.cxx12
-rw-r--r--Source/cmOutputConverter.h10
-rw-r--r--Source/cmOutputRequiredFilesCommand.cxx5
-rw-r--r--Source/cmParseArgumentsCommand.cxx11
-rw-r--r--Source/cmPolicies.h11
-rw-r--r--Source/cmQtAutoGenInitializer.cxx50
-rw-r--r--Source/cmRemoveCommand.cxx7
-rw-r--r--Source/cmRuntimeDependencyArchive.cxx18
-rw-r--r--Source/cmSearchPath.cxx5
-rw-r--r--Source/cmStandardLevelResolver.cxx5
-rw-r--r--Source/cmStringAlgorithms.cxx71
-rw-r--r--Source/cmStringAlgorithms.h57
-rw-r--r--Source/cmTarget.cxx22
-rw-r--r--Source/cmTargetSourcesCommand.cxx3
-rw-r--r--Source/cmTestGenerator.cxx22
-rw-r--r--Source/cmTryRunCommand.cxx3
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx94
-rw-r--r--Source/cmVisualStudio10TargetGenerator.h4
-rw-r--r--Source/cmXCodeScheme.cxx5
-rw-r--r--Source/cmake.cxx31
-rw-r--r--Source/cmakemain.cxx3
-rw-r--r--Source/cmcmd.cxx30
133 files changed, 3539 insertions, 1205 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 4a7d9bc591..2354f3d999 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -1018,6 +1018,7 @@ add_library(
CPack/cmCPackGeneratorFactory.cxx
CPack/cmCPackGenerator.cxx
CPack/cmCPackLog.cxx
+ CPack/cmCPackInnoSetupGenerator.cxx
CPack/cmCPackNSISGenerator.cxx
CPack/cmCPackNuGetGenerator.cxx
CPack/cmCPackSTGZGenerator.cxx
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 34eb248804..524f706433 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 26)
-set(CMake_VERSION_PATCH 20230411)
+set(CMake_VERSION_PATCH 20230505)
#set(CMake_VERSION_RC 0)
set(CMake_VERSION_IS_DIRTY 0)
diff --git a/Source/CPack/IFW/cmCPackIFWCommon.cxx b/Source/CPack/IFW/cmCPackIFWCommon.cxx
index 5d995c335d..4a868ae88f 100644
--- a/Source/CPack/IFW/cmCPackIFWCommon.cxx
+++ b/Source/CPack/IFW/cmCPackIFWCommon.cxx
@@ -5,12 +5,11 @@
#include <cstddef> // IWYU pragma: keep
#include <sstream>
#include <utility>
-#include <vector>
#include "cmCPackGenerator.h"
#include "cmCPackIFWGenerator.h"
#include "cmCPackLog.h" // IWYU pragma: keep
-#include "cmStringAlgorithms.h"
+#include "cmList.h"
#include "cmSystemTools.h"
#include "cmTimestamp.h"
#include "cmVersionConfig.h"
@@ -76,13 +75,13 @@ bool cmCPackIFWCommon::IsVersionEqual(const char* version) const
void cmCPackIFWCommon::ExpandListArgument(
const std::string& arg, std::map<std::string, std::string>& argsOut)
{
- std::vector<std::string> args = cmExpandedList(arg, false);
+ cmList args{ arg };
if (args.empty()) {
return;
}
- std::size_t i = 0;
- std::size_t c = args.size();
+ cmList::size_type i = 0;
+ auto c = args.size();
if (c % 2) {
argsOut[""] = args[i];
++i;
@@ -97,13 +96,13 @@ void cmCPackIFWCommon::ExpandListArgument(
void cmCPackIFWCommon::ExpandListArgument(
const std::string& arg, std::multimap<std::string, std::string>& argsOut)
{
- std::vector<std::string> args = cmExpandedList(arg, false);
+ cmList args{ arg };
if (args.empty()) {
return;
}
- std::size_t i = 0;
- std::size_t c = args.size();
+ cmList::size_type i = 0;
+ auto c = args.size();
if (c % 2) {
argsOut.insert(std::pair<std::string, std::string>("", args[i]));
++i;
diff --git a/Source/CPack/IFW/cmCPackIFWGenerator.cxx b/Source/CPack/IFW/cmCPackIFWGenerator.cxx
index bc14eb40b1..5724175510 100644
--- a/Source/CPack/IFW/cmCPackIFWGenerator.cxx
+++ b/Source/CPack/IFW/cmCPackIFWGenerator.cxx
@@ -14,6 +14,7 @@
#include "cmCPackLog.h" // IWYU pragma: keep
#include "cmDuration.h"
#include "cmGeneratedFileStream.h"
+#include "cmList.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"
@@ -409,8 +410,8 @@ int cmCPackIFWGenerator::InitializeInternal()
// Repositories
if (cmValue RepoAllStr = this->GetOption("CPACK_IFW_REPOSITORIES_ALL")) {
- std::vector<std::string> RepoAllVector = cmExpandedList(RepoAllStr);
- for (std::string const& r : RepoAllVector) {
+ cmList RepoAllList{ RepoAllStr };
+ for (std::string const& r : RepoAllList) {
this->GetRepository(r);
}
}
diff --git a/Source/CPack/IFW/cmCPackIFWInstaller.cxx b/Source/CPack/IFW/cmCPackIFWInstaller.cxx
index 69440d9748..a77c22fa81 100644
--- a/Source/CPack/IFW/cmCPackIFWInstaller.cxx
+++ b/Source/CPack/IFW/cmCPackIFWInstaller.cxx
@@ -12,6 +12,7 @@
#include "cmCPackIFWRepository.h"
#include "cmCPackLog.h" // IWYU pragma: keep
#include "cmGeneratedFileStream.h"
+#include "cmList.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"
diff --git a/Source/CPack/IFW/cmCPackIFWPackage.cxx b/Source/CPack/IFW/cmCPackIFWPackage.cxx
index 1668fb5d56..083f1ef7b1 100644
--- a/Source/CPack/IFW/cmCPackIFWPackage.cxx
+++ b/Source/CPack/IFW/cmCPackIFWPackage.cxx
@@ -15,6 +15,7 @@
#include "cmCPackIFWInstaller.h"
#include "cmCPackLog.h" // IWYU pragma: keep
#include "cmGeneratedFileStream.h"
+#include "cmList.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTimestamp.h"
@@ -427,16 +428,16 @@ int cmCPackIFWPackage::ConfigureFromPrefix(const std::string& prefix)
}
// QtIFW dependencies
- std::vector<std::string> deps;
+ cmList deps;
option = prefix + "DEPENDS";
if (cmValue value = this->GetOption(option)) {
- cmExpandList(value, deps);
+ deps.assign(value);
}
option = prefix + "DEPENDENCIES";
if (cmValue value = this->GetOption(option)) {
- cmExpandList(value, deps);
+ deps.append(value);
}
- for (std::string const& d : deps) {
+ for (auto const& d : deps) {
DependenceStruct dep(d);
if (this->Generator->Packages.count(dep.Name)) {
cmCPackIFWPackage& depPkg = this->Generator->Packages[dep.Name];
@@ -455,7 +456,7 @@ int cmCPackIFWPackage::ConfigureFromPrefix(const std::string& prefix)
if (this->IsSetToEmpty(option)) {
this->AlienAutoDependOn.clear();
} else if (cmValue value = this->GetOption(option)) {
- std::vector<std::string> depsOn = cmExpandedList(value);
+ cmList depsOn{ value };
for (std::string const& d : depsOn) {
DependenceStruct dep(d);
if (this->Generator->Packages.count(dep.Name)) {
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
index aeb3db3539..1ea78fdc3d 100644
--- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx
+++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
@@ -18,6 +18,7 @@
#include "cmCryptoHash.h"
#include "cmGeneratedFileStream.h"
#include "cmInstalledFile.h"
+#include "cmList.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmUuid.h"
@@ -239,7 +240,7 @@ bool cmCPackWIXGenerator::InitializeWiXConfiguration()
cmValue patchFilePath = GetOption("CPACK_WIX_PATCH_FILE");
if (patchFilePath) {
- std::vector<std::string> patchFilePaths = cmExpandedList(patchFilePath);
+ cmList patchFilePaths{ patchFilePath };
for (std::string const& p : patchFilePaths) {
if (!this->Patch->LoadFragments(p)) {
@@ -322,8 +323,7 @@ void cmCPackWIXGenerator::AppendUserSuppliedExtraObjects(std::ostream& stream)
if (!cpackWixExtraObjects)
return;
- std::vector<std::string> expandedExtraObjects =
- cmExpandedList(cpackWixExtraObjects);
+ cmList expandedExtraObjects{ cpackWixExtraObjects };
for (std::string const& obj : expandedExtraObjects) {
stream << " " << QuotePath(obj);
@@ -681,10 +681,10 @@ bool cmCPackWIXGenerator::AddComponentsToFeature(
featureDefinitions.BeginElement("FeatureRef");
featureDefinitions.AddAttribute("Id", featureId);
- std::vector<std::string> cpackPackageExecutablesList;
+ cmList cpackPackageExecutablesList;
cmValue cpackPackageExecutables = GetOption("CPACK_PACKAGE_EXECUTABLES");
if (cpackPackageExecutables) {
- cmExpandList(cpackPackageExecutables, cpackPackageExecutablesList);
+ cpackPackageExecutablesList.assign(cpackPackageExecutables);
if (cpackPackageExecutablesList.size() % 2 != 0) {
cmCPackLogger(
cmCPackLog::LOG_ERROR,
@@ -695,10 +695,10 @@ bool cmCPackWIXGenerator::AddComponentsToFeature(
}
}
- std::vector<std::string> cpackPackageDesktopLinksList;
+ cmList cpackPackageDesktopLinksList;
cmValue cpackPackageDesktopLinks = GetOption("CPACK_CREATE_DESKTOP_LINKS");
if (cpackPackageDesktopLinks) {
- cmExpandList(cpackPackageDesktopLinks, cpackPackageDesktopLinksList);
+ cpackPackageDesktopLinksList.assign(cpackPackageDesktopLinks);
}
AddDirectoryAndFileDefinitions(
@@ -1160,7 +1160,7 @@ void cmCPackWIXGenerator::CollectExtensions(std::string const& variableName,
if (!variableContent)
return;
- std::vector<std::string> list = cmExpandedList(variableContent);
+ cmList list{ variableContent };
extensions.insert(list.begin(), list.end());
}
@@ -1172,7 +1172,7 @@ void cmCPackWIXGenerator::CollectXmlNamespaces(std::string const& variableName,
return;
}
- std::vector<std::string> list = cmExpandedList(variableContent);
+ cmList list{ variableContent };
for (std::string const& str : list) {
auto pos = str.find('=');
if (pos != std::string::npos) {
@@ -1200,7 +1200,7 @@ void cmCPackWIXGenerator::AddCustomFlags(std::string const& variableName,
if (!variableContent)
return;
- std::vector<std::string> list = cmExpandedList(variableContent);
+ cmList list{ variableContent };
for (std::string const& i : list) {
stream << " " << QuotePath(i);
diff --git a/Source/CPack/WiX/cmWIXAccessControlList.cxx b/Source/CPack/WiX/cmWIXAccessControlList.cxx
index 9685a7f495..2261a66e0f 100644
--- a/Source/CPack/WiX/cmWIXAccessControlList.cxx
+++ b/Source/CPack/WiX/cmWIXAccessControlList.cxx
@@ -19,10 +19,9 @@ cmWIXAccessControlList::cmWIXAccessControlList(
bool cmWIXAccessControlList::Apply()
{
- std::vector<std::string> entries;
- this->InstalledFile.GetPropertyAsList("CPACK_WIX_ACL", entries);
+ auto entries = this->InstalledFile.GetPropertyAsList("CPACK_WIX_ACL");
- for (std::string const& entry : entries) {
+ for (auto const& entry : entries) {
this->CreatePermissionElement(entry);
}
diff --git a/Source/CPack/WiX/cmWIXShortcut.cxx b/Source/CPack/WiX/cmWIXShortcut.cxx
index cd1988a1cb..c3eb219a9d 100644
--- a/Source/CPack/WiX/cmWIXShortcut.cxx
+++ b/Source/CPack/WiX/cmWIXShortcut.cxx
@@ -91,10 +91,9 @@ void cmWIXShortcuts::CreateFromProperty(std::string const& propertyName,
std::string const& directoryId,
cmInstalledFile const& installedFile)
{
- std::vector<std::string> list;
- installedFile.GetPropertyAsList(propertyName, list);
+ auto list = installedFile.GetPropertyAsList(propertyName);
- for (std::string const& label : list) {
+ for (auto const& label : list) {
cmWIXShortcut shortcut;
shortcut.label = label;
shortcut.workingDirectoryId = directoryId;
diff --git a/Source/CPack/cmCPackBundleGenerator.cxx b/Source/CPack/cmCPackBundleGenerator.cxx
index b3d425aa51..7e6e4737dd 100644
--- a/Source/CPack/cmCPackBundleGenerator.cxx
+++ b/Source/CPack/cmCPackBundleGenerator.cxx
@@ -6,6 +6,7 @@
#include <vector>
#include "cmCPackLog.h"
+#include "cmList.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"
@@ -191,7 +192,7 @@ int cmCPackBundleGenerator::SignBundle(const std::string& src_dir)
cmValue sign_files = this->GetOption("CPACK_BUNDLE_APPLE_CODESIGN_FILES");
- std::vector<std::string> relFiles = cmExpandedList(sign_files);
+ cmList relFiles{ sign_files };
// sign the files supplied by the user, ie. frameworks.
for (auto const& file : relFiles) {
diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx
index 6ba28d166c..34c56c9993 100644
--- a/Source/CPack/cmCPackDebGenerator.cxx
+++ b/Source/CPack/cmCPackDebGenerator.cxx
@@ -20,6 +20,7 @@
#include "cmCPackLog.h"
#include "cmCryptoHash.h"
#include "cmGeneratedFileStream.h"
+#include "cmList.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"
@@ -427,8 +428,7 @@ bool DebGenerator::generateControlTar(std::string const& md5Filename) const
// default
control_tar.ClearPermissions();
- std::vector<std::string> controlExtraList =
- cmExpandedList(this->ControlExtra);
+ cmList controlExtraList{ this->ControlExtra };
for (std::string const& i : controlExtraList) {
std::string filenamename = cmsys::SystemTools::GetFilenameName(i);
std::string localcopy = this->WorkDir + "/" + filenamename;
diff --git a/Source/CPack/cmCPackDragNDropGenerator.cxx b/Source/CPack/cmCPackDragNDropGenerator.cxx
index 68e7ba3651..768bfbe08d 100644
--- a/Source/CPack/cmCPackDragNDropGenerator.cxx
+++ b/Source/CPack/cmCPackDragNDropGenerator.cxx
@@ -19,6 +19,7 @@
#include "cmCPackLog.h"
#include "cmDuration.h"
#include "cmGeneratedFileStream.h"
+#include "cmList.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"
@@ -128,8 +129,7 @@ int cmCPackDragNDropGenerator::InitializeInternal()
return 0;
}
- std::vector<std::string> languages =
- cmExpandedList(this->GetOption("CPACK_DMG_SLA_LANGUAGES"));
+ cmList languages{ this->GetOption("CPACK_DMG_SLA_LANGUAGES") };
if (languages.empty()) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"CPACK_DMG_SLA_LANGUAGES set but empty" << std::endl);
@@ -543,9 +543,9 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
std::string sla_xml =
cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), "/sla.xml");
- std::vector<std::string> languages;
+ cmList languages;
if (!oldStyle) {
- cmExpandList(cpack_dmg_languages, languages);
+ languages.assign(cpack_dmg_languages);
}
std::vector<uint16_t> header_data;
@@ -574,7 +574,7 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
header_data.push_back(0);
header_data.push_back(languages.size());
- for (size_t i = 0; i < languages.size(); ++i) {
+ for (cmList::size_type i = 0; i < languages.size(); ++i) {
CFStringRef language_cfstring = CFStringCreateWithCString(
nullptr, languages[i].c_str(), kCFStringEncodingUTF8);
CFStringRef iso_language =
diff --git a/Source/CPack/cmCPackExternalGenerator.cxx b/Source/CPack/cmCPackExternalGenerator.cxx
index 4c92592d03..8ba015c8a6 100644
--- a/Source/CPack/cmCPackExternalGenerator.cxx
+++ b/Source/CPack/cmCPackExternalGenerator.cxx
@@ -15,8 +15,8 @@
#include "cmCPackComponentGroup.h"
#include "cmCPackLog.h"
+#include "cmList.h"
#include "cmMakefile.h"
-#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"
@@ -79,7 +79,7 @@ int cmCPackExternalGenerator::PackageFiles()
cmValue builtPackages = this->GetOption("CPACK_EXTERNAL_BUILT_PACKAGES");
if (builtPackages) {
- cmExpandList(builtPackages, this->packageFileNames, false);
+ cmExpandList(builtPackages, this->packageFileNames);
}
}
diff --git a/Source/CPack/cmCPackFreeBSDGenerator.cxx b/Source/CPack/cmCPackFreeBSDGenerator.cxx
index ea7b24b488..0840e33cc8 100644
--- a/Source/CPack/cmCPackFreeBSDGenerator.cxx
+++ b/Source/CPack/cmCPackFreeBSDGenerator.cxx
@@ -2,15 +2,6 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCPackFreeBSDGenerator.h"
-#include "cmArchiveWrite.h"
-#include "cmCPackArchiveGenerator.h"
-#include "cmCPackLog.h"
-#include "cmGeneratedFileStream.h"
-#include "cmStringAlgorithms.h"
-#include "cmSystemTools.h"
-#include "cmWorkingDirectory.h"
-
-// Needed for ::open() and ::stat()
#include <algorithm>
#include <ostream>
#include <utility>
@@ -21,6 +12,15 @@
#include <sys/stat.h>
+#include "cmArchiveWrite.h"
+#include "cmCPackArchiveGenerator.h"
+#include "cmCPackLog.h"
+#include "cmGeneratedFileStream.h"
+#include "cmList.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+#include "cmWorkingDirectory.h"
+
// Suffix used to tell libpkg what compression to use
static const char FreeBSDPackageCompression[] = "txz";
static const char FreeBSDPackageSuffix_17[] = ".pkg";
@@ -292,8 +292,7 @@ void cmCPackFreeBSDGenerator::write_manifest_fields(
manifest << ManifestKeyValue(
"desc", var_lookup("CPACK_FREEBSD_PACKAGE_DESCRIPTION"));
manifest << ManifestKeyValue("www", var_lookup("CPACK_FREEBSD_PACKAGE_WWW"));
- std::vector<std::string> licenses =
- cmExpandedList(var_lookup("CPACK_FREEBSD_PACKAGE_LICENSE"));
+ cmList licenses{ var_lookup("CPACK_FREEBSD_PACKAGE_LICENSE") };
std::string licenselogic("single");
if (licenses.empty()) {
cmSystemTools::SetFatalErrorOccurred();
@@ -302,12 +301,10 @@ void cmCPackFreeBSDGenerator::write_manifest_fields(
}
manifest << ManifestKeyValue("licenselogic", licenselogic);
manifest << (ManifestKeyListValue("licenses") << licenses);
- std::vector<std::string> categories =
- cmExpandedList(var_lookup("CPACK_FREEBSD_PACKAGE_CATEGORIES"));
+ cmList categories{ var_lookup("CPACK_FREEBSD_PACKAGE_CATEGORIES") };
manifest << (ManifestKeyListValue("categories") << categories);
manifest << ManifestKeyValue("prefix", var_lookup("CMAKE_INSTALL_PREFIX"));
- std::vector<std::string> deps =
- cmExpandedList(var_lookup("CPACK_FREEBSD_PACKAGE_DEPS"));
+ cmList deps{ var_lookup("CPACK_FREEBSD_PACKAGE_DEPS") };
if (!deps.empty()) {
manifest << (ManifestKeyDepsValue("deps") << deps);
}
diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx
index 2ac5b3dc77..afd85cda75 100644
--- a/Source/CPack/cmCPackGenerator.cxx
+++ b/Source/CPack/cmCPackGenerator.cxx
@@ -19,6 +19,7 @@
#include "cmFileTimes.h"
#include "cmGeneratedFileStream.h"
#include "cmGlobalGenerator.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmState.h"
#include "cmStateSnapshot.h"
@@ -216,8 +217,7 @@ int cmCPackGenerator::InstallProject()
cmValue default_dir_install_permissions =
this->GetOption("CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS");
if (cmNonempty(default_dir_install_permissions)) {
- std::vector<std::string> items =
- cmExpandedList(default_dir_install_permissions);
+ cmList items{ default_dir_install_permissions };
for (const auto& arg : items) {
if (!cmFSPermissions::stringToModeT(arg, default_dir_mode_v)) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
@@ -266,7 +266,7 @@ int cmCPackGenerator::InstallProject()
// Run pre-build actions
cmValue preBuildScripts = this->GetOption("CPACK_PRE_BUILD_SCRIPTS");
if (preBuildScripts) {
- const auto scripts = cmExpandedList(preBuildScripts, false);
+ const cmList scripts{ preBuildScripts };
for (const auto& script : scripts) {
cmCPackLogger(cmCPackLog::LOG_OUTPUT,
"Executing pre-build script: " << script << std::endl);
@@ -296,8 +296,7 @@ int cmCPackGenerator::InstallProjectViaInstallCommands(
std::string tempInstallDirectoryEnv =
cmStrCat("CMAKE_INSTALL_PREFIX=", tempInstallDirectory);
cmSystemTools::PutEnv(tempInstallDirectoryEnv);
- std::vector<std::string> installCommandsVector =
- cmExpandedList(installCommands);
+ cmList installCommandsVector{ installCommands };
for (std::string const& ic : installCommandsVector) {
cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << ic << std::endl);
std::string output;
@@ -333,8 +332,7 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories(
std::vector<cmsys::RegularExpression> ignoreFilesRegex;
cmValue cpackIgnoreFiles = this->GetOption("CPACK_IGNORE_FILES");
if (cpackIgnoreFiles) {
- std::vector<std::string> ignoreFilesRegexString =
- cmExpandedList(cpackIgnoreFiles);
+ cmList ignoreFilesRegexString{ cpackIgnoreFiles };
for (std::string const& ifr : ignoreFilesRegexString) {
cmCPackLogger(cmCPackLog::LOG_VERBOSE,
"Create ignore files regex for: " << ifr << std::endl);
@@ -343,9 +341,8 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories(
}
cmValue installDirectories = this->GetOption("CPACK_INSTALLED_DIRECTORIES");
if (cmNonempty(installDirectories)) {
- std::vector<std::string> installDirectoriesVector =
- cmExpandedList(installDirectories);
- if (installDirectoriesVector.size() % 2 != 0) {
+ cmList installDirectoriesList{ installDirectories };
+ if (installDirectoriesList.size() % 2 != 0) {
cmCPackLogger(
cmCPackLog::LOG_ERROR,
"CPACK_INSTALLED_DIRECTORIES should contain pairs of <directory> "
@@ -355,10 +352,10 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories(
<< std::endl);
return 0;
}
- std::vector<std::string>::iterator it;
+ cmList::iterator it;
const std::string& tempDir = tempInstallDirectory;
- for (it = installDirectoriesVector.begin();
- it != installDirectoriesVector.end(); ++it) {
+ for (it = installDirectoriesList.begin();
+ it != installDirectoriesList.end(); ++it) {
std::vector<std::pair<std::string, std::string>> symlinkedFiles;
cmCPackLogger(cmCPackLog::LOG_DEBUG, "Find files" << std::endl);
cmsys::Glob gl;
@@ -485,7 +482,7 @@ int cmCPackGenerator::InstallProjectViaInstallScript(
if (cmakeScripts && !cmakeScripts->empty()) {
cmCPackLogger(cmCPackLog::LOG_OUTPUT,
"- Install scripts: " << cmakeScripts << std::endl);
- std::vector<std::string> cmakeScriptsVector = cmExpandedList(cmakeScripts);
+ cmList cmakeScriptsVector{ cmakeScripts };
for (std::string const& installScript : cmakeScriptsVector) {
cmCPackLogger(cmCPackLog::LOG_OUTPUT,
@@ -549,14 +546,12 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
<< std::endl);
return 0;
}
- std::vector<std::string> cmakeProjectsVector =
- cmExpandedList(cmakeProjects);
- std::vector<std::string>::iterator it;
- for (it = cmakeProjectsVector.begin(); it != cmakeProjectsVector.end();
- ++it) {
- if (it + 1 == cmakeProjectsVector.end() ||
- it + 2 == cmakeProjectsVector.end() ||
- it + 3 == cmakeProjectsVector.end()) {
+ cmList cmakeProjectsList{ cmakeProjects };
+ cmList::iterator it;
+ for (it = cmakeProjectsList.begin(); it != cmakeProjectsList.end(); ++it) {
+ if (it + 1 == cmakeProjectsList.end() ||
+ it + 2 == cmakeProjectsList.end() ||
+ it + 3 == cmakeProjectsList.end()) {
cmCPackLogger(
cmCPackLog::LOG_ERROR,
"Not enough items on list: CPACK_INSTALL_CMAKE_PROJECTS. "
@@ -578,7 +573,7 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
++it;
project.SubDirectory = *it;
- std::vector<std::string> componentsVector;
+ cmList componentsList;
bool componentInstall = false;
/*
@@ -593,10 +588,9 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
std::string installTypesVar = "CPACK_" +
cmSystemTools::UpperCase(project.Component) + "_INSTALL_TYPES";
cmValue installTypes = this->GetOption(installTypesVar);
- if (cmNonempty(installTypes)) {
- std::vector<std::string> installTypesVector =
- cmExpandedList(installTypes);
- for (std::string const& installType : installTypesVector) {
+ if (!installTypes.IsEmpty()) {
+ cmList installTypesList{ installTypes };
+ for (std::string const& installType : installTypesList) {
project.InstallationTypes.push_back(
this->GetInstallationType(project.ProjectName, installType));
}
@@ -606,23 +600,23 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
std::string componentsVar =
"CPACK_COMPONENTS_" + cmSystemTools::UpperCase(project.Component);
cmValue components = this->GetOption(componentsVar);
- if (cmNonempty(components)) {
- cmExpandList(components, componentsVector);
- for (std::string const& comp : componentsVector) {
+ if (!components.IsEmpty()) {
+ componentsList.assign(components);
+ for (auto const& comp : componentsList) {
project.Components.push_back(
this->GetComponent(project.ProjectName, comp));
}
componentInstall = true;
}
}
- if (componentsVector.empty()) {
- componentsVector.push_back(project.Component);
+ if (componentsList.empty()) {
+ componentsList.push_back(project.Component);
}
- std::vector<std::string> buildConfigs;
+ cmList buildConfigs;
// Try get configuration names given via `-C` CLI option
- cmExpandList(this->GetOption("CPACK_BUILD_CONFIG"), buildConfigs);
+ buildConfigs.assign(this->GetOption("CPACK_BUILD_CONFIG"));
// Remove duplicates
std::sort(buildConfigs.begin(), buildConfigs.end());
@@ -661,7 +655,7 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
<< buildConfig << ']'
<< std::endl);
// Run the installation for each component
- for (std::string const& component : componentsVector) {
+ for (std::string const& component : componentsList) {
if (!this->InstallCMakeProject(
setDestDir, project.Directory, baseTempInstallDirectory,
default_dir_mode, component, componentInstall,
@@ -894,9 +888,8 @@ int cmCPackGenerator::InstallCMakeProject(
mf.AddDefinition("CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION", "1");
}
- std::vector<std::string> custom_variables;
- this->MakefileMap->GetDefExpandList("CPACK_CUSTOM_INSTALL_VARIABLES",
- custom_variables);
+ cmList custom_variables{ this->MakefileMap->GetDefinition(
+ "CPACK_CUSTOM_INSTALL_VARIABLES") };
for (auto const& custom_variable : custom_variables) {
std::string value;
@@ -1129,7 +1122,7 @@ int cmCPackGenerator::DoPackage()
this->MakefileMap->AddDefinition("CPACK_PACKAGE_FILES",
cmJoin(this->packageFileNames, ";"));
- const auto scripts = cmExpandedList(postBuildScripts, false);
+ const cmList scripts{ postBuildScripts };
for (const auto& script : scripts) {
cmCPackLogger(cmCPackLog::LOG_OUTPUT,
"Executing post-build script: " << script << std::endl);
@@ -1595,9 +1588,8 @@ cmCPackComponent* cmCPackGenerator::GetComponent(
// Determine the installation types.
cmValue installTypes = this->GetOption(macroPrefix + "_INSTALL_TYPES");
if (cmNonempty(installTypes)) {
- std::vector<std::string> installTypesVector =
- cmExpandedList(installTypes);
- for (std::string const& installType : installTypesVector) {
+ cmList installTypesList{ installTypes };
+ for (auto const& installType : installTypesList) {
component->InstallationTypes.push_back(
this->GetInstallationType(projectName, installType));
}
@@ -1606,8 +1598,8 @@ cmCPackComponent* cmCPackGenerator::GetComponent(
// Determine the component dependencies.
cmValue depends = this->GetOption(macroPrefix + "_DEPENDS");
if (cmNonempty(depends)) {
- std::vector<std::string> dependsVector = cmExpandedList(depends);
- for (std::string const& depend : dependsVector) {
+ cmList dependsList{ depends };
+ for (auto const& depend : dependsList) {
cmCPackComponent* child = this->GetComponent(projectName, depend);
component->Dependencies.push_back(child);
child->ReverseDependencies.push_back(component);
diff --git a/Source/CPack/cmCPackGeneratorFactory.cxx b/Source/CPack/cmCPackGeneratorFactory.cxx
index efb94b9d8f..6ca48bf938 100644
--- a/Source/CPack/cmCPackGeneratorFactory.cxx
+++ b/Source/CPack/cmCPackGeneratorFactory.cxx
@@ -13,6 +13,7 @@
#include "cmCPackDebGenerator.h"
#include "cmCPackExternalGenerator.h"
#include "cmCPackGenerator.h"
+#include "cmCPackInnoSetupGenerator.h"
#include "cmCPackLog.h"
#include "cmCPackNSISGenerator.h"
#include "cmCPackNuGetGenerator.h"
@@ -60,6 +61,10 @@ cmCPackGeneratorFactory::cmCPackGeneratorFactory()
this->RegisterGenerator("STGZ", "Self extracting Tar GZip compression",
cmCPackSTGZGenerator::CreateGenerator);
}
+ if (cmCPackInnoSetupGenerator::CanGenerate()) {
+ this->RegisterGenerator("INNOSETUP", "Inno Setup packages",
+ cmCPackInnoSetupGenerator::CreateGenerator);
+ }
if (cmCPackNSISGenerator::CanGenerate()) {
this->RegisterGenerator("NSIS", "Null Soft Installer",
cmCPackNSISGenerator::CreateGenerator);
diff --git a/Source/CPack/cmCPackInnoSetupGenerator.cxx b/Source/CPack/cmCPackInnoSetupGenerator.cxx
new file mode 100644
index 0000000000..d8825d46b5
--- /dev/null
+++ b/Source/CPack/cmCPackInnoSetupGenerator.cxx
@@ -0,0 +1,1159 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+file Copyright.txt or https://cmake.org/licensing for details. */
+
+#include "cmCPackInnoSetupGenerator.h"
+
+#include <algorithm>
+#include <cctype>
+#include <cstdlib>
+#include <ostream>
+#include <stack>
+#include <utility>
+
+#include "cmsys/RegularExpression.hxx"
+
+#include "cmCPackComponentGroup.h"
+#include "cmCPackLog.h"
+#include "cmDuration.h"
+#include "cmGeneratedFileStream.h"
+#include "cmList.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+
+cmCPackInnoSetupGenerator::cmCPackInnoSetupGenerator() = default;
+cmCPackInnoSetupGenerator::~cmCPackInnoSetupGenerator() = default;
+
+bool cmCPackInnoSetupGenerator::CanGenerate()
+{
+ // Inno Setup is only available for Windows
+#ifdef _WIN32
+ return true;
+#else
+ return false;
+#endif
+}
+
+int cmCPackInnoSetupGenerator::InitializeInternal()
+{
+ if (cmIsOn(GetOption("CPACK_INCLUDE_TOPLEVEL_DIRECTORY"))) {
+ cmCPackLogger(cmCPackLog::LOG_WARNING,
+ "Inno Setup Generator cannot work with "
+ "CPACK_INCLUDE_TOPLEVEL_DIRECTORY set. "
+ "This option will be reset to 0 (for this generator only)."
+ << std::endl);
+ SetOption("CPACK_INCLUDE_TOPLEVEL_DIRECTORY", nullptr);
+ }
+
+ std::vector<std::string> path;
+
+#ifdef _WIN32
+ path.push_back("C:\\Program Files (x86)\\Inno Setup 5");
+ path.push_back("C:\\Program Files (x86)\\Inno Setup 6");
+#endif
+
+ SetOptionIfNotSet("CPACK_INNOSETUP_EXECUTABLE", "ISCC");
+ const std::string& isccPath = cmSystemTools::FindProgram(
+ GetOption("CPACK_INNOSETUP_EXECUTABLE"), path, false);
+
+ if (isccPath.empty()) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Cannot find Inno Setup compiler ISCC: "
+ "likely it is not installed, or not in your PATH"
+ << std::endl);
+
+ return 0;
+ }
+
+ const std::string isccCmd = cmStrCat(QuotePath(isccPath), "/?");
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE,
+ "Test Inno Setup version: " << isccCmd << std::endl);
+ std::string output;
+ cmSystemTools::RunSingleCommand(isccCmd, &output, &output, nullptr, nullptr,
+ this->GeneratorVerbose, cmDuration::zero());
+ cmsys::RegularExpression vRex("Inno Setup ([0-9]+)");
+ if (!vRex.find(output)) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Problem checking Inno Setup version with command: "
+ << isccCmd << std::endl
+ << "Have you downloaded Inno Setup from "
+ "https://jrsoftware.org/isinfo.php?"
+ << std::endl);
+ return 0;
+ }
+
+ const int isccVersion = atoi(vRex.match(1).c_str());
+ const int minIsccVersion = 6;
+ cmCPackLogger(cmCPackLog::LOG_DEBUG,
+ "Inno Setup Version: " << isccVersion << std::endl);
+
+ if (isccVersion < minIsccVersion) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "CPack requires Inno Setup Version 6 or greater. "
+ "Inno Setup found on the system was: "
+ << isccVersion << std::endl);
+ return 0;
+ }
+
+ SetOption("CPACK_INSTALLER_PROGRAM", isccPath);
+
+ return this->Superclass::InitializeInternal();
+}
+
+int cmCPackInnoSetupGenerator::PackageFiles()
+{
+ // Includes
+ if (IsSet("CPACK_INNOSETUP_EXTRA_SCRIPTS")) {
+ const cmList extraScripts(GetOption("CPACK_INNOSETUP_EXTRA_SCRIPTS"));
+
+ for (const std::string& i : extraScripts) {
+ includeDirectives.push_back(cmStrCat(
+ "#include ", QuotePath(cmSystemTools::CollapseFullPath(i, toplevel))));
+ }
+ }
+
+ // [Languages] section
+ SetOptionIfNotSet("CPACK_INNOSETUP_LANGUAGES", "english");
+ const cmList languages(GetOption("CPACK_INNOSETUP_LANGUAGES"));
+ for (std::string i : languages) {
+ cmCPackInnoSetupKeyValuePairs params;
+
+ params["Name"] = Quote(i);
+
+ if (cmSystemTools::LowerCase(i) == "english") {
+ params["MessagesFile"] = "\"compiler:Default.isl\"";
+ } else {
+ i[0] = static_cast<char>(std::toupper(i[0]));
+ params["MessagesFile"] = cmStrCat("\"compiler:Languages\\", i, ".isl\"");
+ }
+
+ languageInstructions.push_back(ISKeyValueLine(params));
+ }
+
+ if (!Components.empty() && !ProcessComponents()) {
+ return false;
+ }
+
+ if (!(ProcessSetupSection() && ProcessFiles())) {
+ return false;
+ }
+
+ // [Code] section
+ if (IsSet("CPACK_INNOSETUP_CODE_FILES")) {
+ const cmList codeFiles(GetOption("CPACK_INNOSETUP_CODE_FILES"));
+
+ for (const std::string& i : codeFiles) {
+ codeIncludes.push_back(cmStrCat(
+ "#include ", QuotePath(cmSystemTools::CollapseFullPath(i, toplevel))));
+ }
+ }
+
+ return ConfigureISScript() && Compile();
+}
+
+bool cmCPackInnoSetupGenerator::ProcessSetupSection()
+{
+ if (!RequireOption("CPACK_PACKAGE_INSTALL_REGISTRY_KEY")) {
+ return false;
+ }
+ setupDirectives["AppId"] = GetOption("CPACK_PACKAGE_INSTALL_REGISTRY_KEY");
+
+ if (!RequireOption("CPACK_PACKAGE_NAME")) {
+ return false;
+ }
+ setupDirectives["AppName"] = GetOption("CPACK_PACKAGE_NAME");
+ setupDirectives["UninstallDisplayName"] = GetOption("CPACK_PACKAGE_NAME");
+
+ if (!RequireOption("CPACK_PACKAGE_VERSION")) {
+ return false;
+ }
+ setupDirectives["AppVersion"] = GetOption("CPACK_PACKAGE_VERSION");
+
+ if (!RequireOption("CPACK_PACKAGE_VENDOR")) {
+ return false;
+ }
+ setupDirectives["AppPublisher"] = GetOption("CPACK_PACKAGE_VENDOR");
+
+ if (IsSet("CPACK_PACKAGE_HOMEPAGE_URL")) {
+ setupDirectives["AppPublisherURL"] =
+ GetOption("CPACK_PACKAGE_HOMEPAGE_URL");
+ setupDirectives["AppSupportURL"] = GetOption("CPACK_PACKAGE_HOMEPAGE_URL");
+ setupDirectives["AppUpdatesURL"] = GetOption("CPACK_PACKAGE_HOMEPAGE_URL");
+ }
+
+ SetOptionIfNotSet("CPACK_INNOSETUP_IGNORE_LICENSE_PAGE", "OFF");
+ if (IsSet("CPACK_RESOURCE_FILE_LICENSE") &&
+ !GetOption("CPACK_INNOSETUP_IGNORE_LICENSE_PAGE").IsOn()) {
+ setupDirectives["LicenseFile"] = cmSystemTools::ConvertToWindowsOutputPath(
+ GetOption("CPACK_RESOURCE_FILE_LICENSE"));
+ }
+
+ SetOptionIfNotSet("CPACK_INNOSETUP_IGNORE_README_PAGE", "ON");
+ if (IsSet("CPACK_RESOURCE_FILE_README") &&
+ !GetOption("CPACK_INNOSETUP_IGNORE_README_PAGE").IsOn()) {
+ setupDirectives["InfoBeforeFile"] =
+ cmSystemTools::ConvertToWindowsOutputPath(
+ GetOption("CPACK_RESOURCE_FILE_README"));
+ }
+
+ SetOptionIfNotSet("CPACK_INNOSETUP_USE_MODERN_WIZARD", "OFF");
+ if (GetOption("CPACK_INNOSETUP_USE_MODERN_WIZARD").IsOn()) {
+ setupDirectives["WizardStyle"] = "modern";
+ } else {
+ setupDirectives["WizardStyle"] = "classic";
+ setupDirectives["WizardSmallImageFile"] =
+ "compiler:WizClassicSmallImage.bmp";
+ setupDirectives["WizardImageFile"] = "compiler:WizClassicImage.bmp";
+ setupDirectives["SetupIconFile"] = "compiler:SetupClassicIcon.ico";
+ }
+
+ if (IsSet("CPACK_INNOSETUP_ICON_FILE")) {
+ setupDirectives["SetupIconFile"] =
+ cmSystemTools::ConvertToWindowsOutputPath(
+ GetOption("CPACK_INNOSETUP_ICON_FILE"));
+ }
+
+ if (IsSet("CPACK_PACKAGE_ICON")) {
+ setupDirectives["WizardSmallImageFile"] =
+ cmSystemTools::ConvertToWindowsOutputPath(
+ GetOption("CPACK_PACKAGE_ICON"));
+ }
+
+ if (!RequireOption("CPACK_PACKAGE_INSTALL_DIRECTORY")) {
+ return false;
+ }
+ SetOptionIfNotSet("CPACK_INNOSETUP_INSTALL_ROOT", "{autopf}");
+ setupDirectives["DefaultDirName"] =
+ cmSystemTools::ConvertToWindowsOutputPath(
+ cmStrCat(GetOption("CPACK_INNOSETUP_INSTALL_ROOT"), '\\',
+ GetOption("CPACK_PACKAGE_INSTALL_DIRECTORY")));
+
+ SetOptionIfNotSet("CPACK_INNOSETUP_ALLOW_CUSTOM_DIRECTORY", "ON");
+ if (GetOption("CPACK_INNOSETUP_ALLOW_CUSTOM_DIRECTORY").IsOff()) {
+ setupDirectives["DisableDirPage"] = "yes";
+ }
+
+ SetOptionIfNotSet("CPACK_INNOSETUP_PROGRAM_MENU_FOLDER",
+ GetOption("CPACK_PACKAGE_NAME"));
+ if (GetOption("CPACK_INNOSETUP_PROGRAM_MENU_FOLDER") == ".") {
+ setupDirectives["DisableProgramGroupPage"] = "yes";
+ toplevelProgramFolder = true;
+ } else {
+ setupDirectives["DefaultGroupName"] =
+ GetOption("CPACK_INNOSETUP_PROGRAM_MENU_FOLDER");
+ toplevelProgramFolder = false;
+ }
+
+ if (IsSet("CPACK_INNOSETUP_PASSWORD")) {
+ setupDirectives["Password"] = GetOption("CPACK_INNOSETUP_PASSWORD");
+ setupDirectives["Encryption"] = "yes";
+ }
+
+ /*
+ * These directives can only be modified using the
+ * CPACK_INNOSETUP_SETUP_<directive> variables
+ */
+ setupDirectives["ShowLanguageDialog"] = "auto";
+ setupDirectives["AllowNoIcons"] = "yes";
+ setupDirectives["Compression"] = "lzma";
+ setupDirectives["SolidCompression"] = "yes";
+
+ // Output file and directory
+ if (!RequireOption("CPACK_PACKAGE_FILE_NAME")) {
+ return false;
+ }
+ setupDirectives["OutputBaseFilename"] = GetOption("CPACK_PACKAGE_FILE_NAME");
+
+ if (!RequireOption("CPACK_TOPLEVEL_DIRECTORY")) {
+ return false;
+ }
+ setupDirectives["OutputDir"] = cmSystemTools::ConvertToWindowsOutputPath(
+ GetOption("CPACK_TOPLEVEL_DIRECTORY"));
+
+ setupDirectives["SourceDir"] =
+ cmSystemTools::ConvertToWindowsOutputPath(toplevel);
+
+ // Target architecture
+ if (!RequireOption("CPACK_INNOSETUP_ARCHITECTURE")) {
+ return false;
+ }
+
+ const std::string& architecture = GetOption("CPACK_INNOSETUP_ARCHITECTURE");
+ if (architecture != "x86" && architecture != "x64" &&
+ architecture != "arm64" && architecture != "ia64") {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "CPACK_INNOSETUP_ARCHITECTURE must be either x86, x64, "
+ "arm64 or ia64"
+ << std::endl);
+ return false;
+ }
+
+ // The following directives must not be set to target x86
+ if (architecture != "x86") {
+ setupDirectives["ArchitecturesAllowed"] = architecture;
+ setupDirectives["ArchitecturesInstallIn64BitMode"] = architecture;
+ }
+
+ /*
+ * Handle custom directives (they have higher priority than other variables,
+ * so they have to be processed after all other variables)
+ */
+ for (const std::string& i : GetOptions()) {
+ if (cmHasPrefix(i, "CPACK_INNOSETUP_SETUP_")) {
+ const std::string& directive =
+ i.substr(cmStrLen("CPACK_INNOSETUP_SETUP_"));
+ setupDirectives[directive] = GetOption(i);
+ }
+ }
+
+ return true;
+}
+
+bool cmCPackInnoSetupGenerator::ProcessFiles()
+{
+ std::map<std::string, std::string> customFileInstructions;
+ if (IsSet("CPACK_INNOSETUP_CUSTOM_INSTALL_INSTRUCTIONS")) {
+ const cmList instructions(
+ GetOption("CPACK_INNOSETUP_CUSTOM_INSTALL_INSTRUCTIONS"));
+ if (instructions.size() % 2 != 0) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "CPACK_INNOSETUP_CUSTOM_INSTALL_INSTRUCTIONS should "
+ "contain pairs of <path> and <instruction>"
+ << std::endl);
+ return false;
+ }
+
+ for (auto it = instructions.begin(); it != instructions.end(); ++it) {
+ const std::string& key =
+ QuotePath(cmSystemTools::CollapseFullPath(*it, toplevel));
+ customFileInstructions[key] = *(++it);
+ }
+ }
+
+ const std::string& iconsPrefix =
+ toplevelProgramFolder ? "{autoprograms}\\" : "{group}\\";
+
+ std::map<std::string, std::string> icons;
+ if (IsSet("CPACK_PACKAGE_EXECUTABLES")) {
+ const cmList executables(GetOption("CPACK_PACKAGE_EXECUTABLES"));
+ if (executables.size() % 2 != 0) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "CPACK_PACKAGE_EXECUTABLES should should contain pairs of "
+ "<executable> and <text label>"
+ << std::endl);
+ return false;
+ }
+
+ for (auto it = executables.begin(); it != executables.end(); ++it) {
+ const std::string& key = *it;
+ icons[key] = *(++it);
+ }
+ }
+
+ std::vector<std::string> desktopIcons;
+ if (IsSet("CPACK_CREATE_DESKTOP_LINKS")) {
+ cmExpandList(GetOption("CPACK_CREATE_DESKTOP_LINKS"), desktopIcons);
+ }
+
+ std::vector<std::string> runExecutables;
+ if (IsSet("CPACK_INNOSETUP_RUN_EXECUTABLES")) {
+ cmExpandList(GetOption("CPACK_INNOSETUP_RUN_EXECUTABLES"), runExecutables);
+ }
+
+ for (const std::string& i : files) {
+ cmCPackInnoSetupKeyValuePairs params;
+
+ std::string toplevelDirectory;
+ std::string outputDir;
+ cmCPackComponent* component = nullptr;
+ std::string componentParam;
+ if (!Components.empty()) {
+ const std::string& fileName = cmSystemTools::RelativePath(toplevel, i);
+ const std::string::size_type pos = fileName.find('/');
+
+ // Use the custom component install directory if we have one
+ if (pos != std::string::npos) {
+ const std::string& componentName = fileName.substr(0, pos);
+ component = &Components[componentName];
+
+ toplevelDirectory =
+ cmSystemTools::CollapseFullPath(componentName, toplevel);
+ outputDir = CustomComponentInstallDirectory(component);
+ componentParam =
+ CreateRecursiveComponentPath(component->Group, component->Name);
+
+ if (component->IsHidden && component->IsDisabledByDefault) {
+ continue;
+ }
+
+ if (component->IsHidden) {
+ componentParam.clear();
+ }
+ } else {
+ // Don't install component directories
+ continue;
+ }
+ } else {
+ toplevelDirectory = toplevel;
+ outputDir = "{app}";
+ }
+
+ if (!componentParam.empty()) {
+ params["Components"] = componentParam;
+ }
+
+ if (cmSystemTools::FileIsDirectory(i)) {
+ // Custom instructions replace the automatic generated instructions
+ if (customFileInstructions.count(QuotePath(i))) {
+ dirInstructions.push_back(customFileInstructions[QuotePath(i)]);
+ } else {
+ std::string destDir = cmSystemTools::ConvertToWindowsOutputPath(
+ cmStrCat(outputDir, '\\',
+ cmSystemTools::RelativePath(toplevelDirectory, i)));
+ cmStripSuffixIfExists(destDir, '\\');
+
+ params["Name"] = QuotePath(destDir);
+
+ dirInstructions.push_back(ISKeyValueLine(params));
+ }
+ } else {
+ // Custom instructions replace the automatic generated instructions
+ if (customFileInstructions.count(QuotePath(i))) {
+ fileInstructions.push_back(customFileInstructions[QuotePath(i)]);
+ } else {
+ std::string destDir = cmSystemTools::ConvertToWindowsOutputPath(
+ cmStrCat(outputDir, '\\',
+ cmSystemTools::GetParentDirectory(
+ cmSystemTools::RelativePath(toplevelDirectory, i))));
+ cmStripSuffixIfExists(destDir, '\\');
+
+ params["DestDir"] = QuotePath(destDir);
+
+ if (component != nullptr && component->IsDownloaded) {
+ const std::string& archiveName =
+ cmSystemTools::GetFilenameWithoutLastExtension(
+ component->ArchiveFile);
+ const std::string& relativePath =
+ cmSystemTools::RelativePath(toplevelDirectory, i);
+
+ params["Source"] =
+ QuotePath(cmStrCat("{tmp}\\", archiveName, '\\', relativePath));
+ params["ExternalSize"] =
+ std::to_string(cmSystemTools::FileLength(i));
+ params["Flags"] = "external ignoreversion";
+ params["BeforeInstall"] =
+ cmStrCat("CPackExtractFile('", archiveName, "', '",
+ cmRemoveQuotes(cmSystemTools::ConvertToWindowsOutputPath(
+ relativePath)),
+ "')");
+ } else {
+ params["Source"] = QuotePath(i);
+ params["Flags"] = "ignoreversion";
+ }
+
+ fileInstructions.push_back(ISKeyValueLine(params));
+
+ // Icon
+ const std::string& name =
+ cmSystemTools::GetFilenameWithoutLastExtension(i);
+ const std::string& extension =
+ cmSystemTools::GetFilenameLastExtension(i);
+ if ((extension == ".exe" || extension == ".com") && // only .exe, .com
+ icons.count(name)) {
+ cmCPackInnoSetupKeyValuePairs iconParams;
+
+ iconParams["Name"] = QuotePath(cmStrCat(iconsPrefix, icons[name]));
+ iconParams["Filename"] =
+ QuotePath(cmStrCat(destDir, '\\', name, extension));
+
+ if (!componentParam.empty()) {
+ iconParams["Components"] = componentParam;
+ }
+
+ iconInstructions.push_back(ISKeyValueLine(iconParams));
+
+ // Desktop icon
+ if (std::find(desktopIcons.begin(), desktopIcons.end(), name) !=
+ desktopIcons.end()) {
+ iconParams["Name"] =
+ QuotePath(cmStrCat("{autodesktop}\\", icons[name]));
+ iconParams["Tasks"] = "desktopicon";
+
+ if (!componentParam.empty() &&
+ std::find(desktopIconComponents.begin(),
+ desktopIconComponents.end(),
+ componentParam) == desktopIconComponents.end()) {
+ desktopIconComponents.push_back(componentParam);
+ }
+ iconInstructions.push_back(ISKeyValueLine(iconParams));
+ }
+
+ // [Run] section
+ if (std::find(runExecutables.begin(), runExecutables.end(), name) !=
+ runExecutables.end()) {
+ cmCPackInnoSetupKeyValuePairs runParams;
+
+ runParams["Filename"] = iconParams["Filename"];
+ runParams["Description"] = cmStrCat(
+ "\"{cm:LaunchProgram,", PrepareForConstant(icons[name]), "}\"");
+ runParams["Flags"] = "nowait postinstall skipifsilent";
+
+ if (!componentParam.empty()) {
+ runParams["Components"] = componentParam;
+ }
+
+ runInstructions.push_back(ISKeyValueLine(runParams));
+ }
+ }
+ }
+ }
+ }
+
+ // Additional icons
+ static cmsys::RegularExpression urlRegex(
+ "^(mailto:|(ftps?|https?|news)://).*$");
+
+ if (IsSet("CPACK_INNOSETUP_MENU_LINKS")) {
+ const cmList menuIcons(GetOption("CPACK_INNOSETUP_MENU_LINKS"));
+ if (menuIcons.size() % 2 != 0) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "CPACK_INNOSETUP_MENU_LINKS should "
+ "contain pairs of <shortcut target> and <shortcut label>"
+ << std::endl);
+ return false;
+ }
+
+ for (auto it = menuIcons.begin(); it != menuIcons.end(); ++it) {
+ const std::string& target = *it;
+ const std::string& label = *(++it);
+ cmCPackInnoSetupKeyValuePairs params;
+
+ params["Name"] = QuotePath(cmStrCat(iconsPrefix, label));
+ if (urlRegex.find(target)) {
+ params["Filename"] = Quote(target);
+ } else {
+ std::string dir = "{app}";
+ std::string componentName;
+ for (const auto& i : Components) {
+ if (cmSystemTools::FileExists(cmSystemTools::CollapseFullPath(
+ cmStrCat(i.second.Name, '\\', target), toplevel))) {
+ dir = CustomComponentInstallDirectory(&i.second);
+ componentName =
+ CreateRecursiveComponentPath(i.second.Group, i.second.Name);
+
+ if (i.second.IsHidden && i.second.IsDisabledByDefault) {
+ goto continueOuterLoop;
+ } else if (i.second.IsHidden) {
+ componentName.clear();
+ }
+
+ break;
+ }
+ }
+
+ params["Filename"] = QuotePath(cmStrCat(dir, '\\', target));
+
+ if (!componentName.empty()) {
+ params["Components"] = componentName;
+ }
+ }
+
+ iconInstructions.push_back(ISKeyValueLine(params));
+ continueOuterLoop:;
+ }
+ }
+
+ SetOptionIfNotSet("CPACK_INNOSETUP_CREATE_UNINSTALL_LINK", "OFF");
+ if (GetOption("CPACK_INNOSETUP_CREATE_UNINSTALL_LINK").IsOn()) {
+ cmCPackInnoSetupKeyValuePairs params;
+
+ params["Name"] = QuotePath(
+ cmStrCat(iconsPrefix, "{cm:UninstallProgram,",
+ PrepareForConstant(GetOption("CPACK_PACKAGE_NAME")), '}'));
+ params["Filename"] = "\"{uninstallexe}\"";
+
+ iconInstructions.push_back(ISKeyValueLine(params));
+ }
+
+ return true;
+}
+
+bool cmCPackInnoSetupGenerator::ProcessComponents()
+{
+ codeIncludes.push_back("{ The following lines are required by CPack because "
+ "this script uses components }");
+
+ // Installation types
+ bool noTypes = true;
+ std::vector<cmCPackInstallationType*> types(InstallationTypes.size());
+ for (auto& i : InstallationTypes) {
+ noTypes = false;
+ types[i.second.Index - 1] = &i.second;
+ }
+
+ std::vector<std::string> allTypes; // For required components
+ for (cmCPackInstallationType* i : types) {
+ cmCPackInnoSetupKeyValuePairs params;
+
+ params["Name"] = Quote(i->Name);
+ params["Description"] = Quote(i->DisplayName);
+
+ allTypes.push_back(i->Name);
+ typeInstructions.push_back(ISKeyValueLine(params));
+ }
+
+ if (!noTypes) {
+ // Inno Setup requires the "custom" type
+ cmCPackInnoSetupKeyValuePairs params;
+
+ params["Name"] = "\"custom\"";
+ params["Description"] = "\"{code:CPackGetCustomInstallationMessage}\"";
+ params["Flags"] = "iscustom";
+
+ allTypes.push_back("custom");
+ typeInstructions.push_back(ISKeyValueLine(params));
+ }
+
+ // Components
+ std::vector<cmCPackComponent*> downloadedComponents;
+ std::stack<cmCPackComponentGroup*> groups;
+ for (auto& i : Components) {
+ cmCPackInnoSetupKeyValuePairs params;
+ cmCPackComponent* component = &i.second;
+
+ if (component->IsHidden) {
+ continue;
+ }
+
+ CreateRecursiveComponentGroups(component->Group);
+
+ params["Name"] =
+ Quote(CreateRecursiveComponentPath(component->Group, component->Name));
+ params["Description"] = Quote(component->DisplayName);
+
+ if (component->IsRequired) {
+ params["Types"] = cmJoin(allTypes, " ");
+ params["Flags"] = "fixed";
+ } else if (!component->InstallationTypes.empty()) {
+ std::vector<std::string> installationTypes;
+
+ for (cmCPackInstallationType* j : component->InstallationTypes) {
+ installationTypes.push_back(j->Name);
+ }
+
+ params["Types"] = cmJoin(installationTypes, " ");
+ }
+
+ componentInstructions.push_back(ISKeyValueLine(params));
+
+ if (component->IsDownloaded) {
+ downloadedComponents.push_back(component);
+
+ if (component->ArchiveFile.empty()) {
+ // Compute the name of the archive.
+ if (!RequireOption("CPACK_TEMPORARY_DIRECTORY")) {
+ return false;
+ }
+
+ std::string packagesDir =
+ cmStrCat(GetOption("CPACK_TEMPORARY_DIRECTORY"), ".dummy");
+ component->ArchiveFile =
+ cmStrCat(cmSystemTools::GetFilenameWithoutLastExtension(packagesDir),
+ '-', component->Name, ".zip");
+ } else if (!cmHasSuffix(component->ArchiveFile, ".zip")) {
+ component->ArchiveFile = cmStrCat(component->ArchiveFile, ".zip");
+ }
+ }
+ }
+
+ // Downloaded components
+ if (!downloadedComponents.empty()) {
+ // Create the directory for the upload area
+ cmValue userUploadDirectory = GetOption("CPACK_UPLOAD_DIRECTORY");
+ std::string uploadDirectory;
+ if (cmNonempty(userUploadDirectory)) {
+ uploadDirectory = *userUploadDirectory;
+ } else {
+ if (!RequireOption("CPACK_PACKAGE_DIRECTORY")) {
+ return false;
+ }
+
+ uploadDirectory =
+ cmStrCat(GetOption("CPACK_PACKAGE_DIRECTORY"), "/CPackUploads");
+ }
+
+ if (!cmSystemTools::FileExists(uploadDirectory)) {
+ if (!cmSystemTools::MakeDirectory(uploadDirectory)) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Unable to create Inno Setup upload directory "
+ << uploadDirectory << std::endl);
+ return false;
+ }
+ }
+
+ if (!RequireOption("CPACK_DOWNLOAD_SITE")) {
+ return false;
+ }
+
+ SetOptionIfNotSet("CPACK_INNOSETUP_VERIFY_DOWNLOADS", "ON");
+ const bool verifyDownloads =
+ GetOption("CPACK_INNOSETUP_VERIFY_DOWNLOADS").IsOn();
+
+ const std::string& urlPrefix =
+ cmHasSuffix(GetOption("CPACK_DOWNLOAD_SITE").GetCStr(), '/')
+ ? GetOption("CPACK_DOWNLOAD_SITE")
+ : cmStrCat(GetOption("CPACK_DOWNLOAD_SITE"), '/');
+
+ std::vector<std::string> archiveUrls;
+ std::vector<std::string> archiveFiles;
+ std::vector<std::string> archiveHashes;
+ std::vector<std::string> archiveComponents;
+ for (cmCPackComponent* i : downloadedComponents) {
+ std::string hash;
+ if (!BuildDownloadedComponentArchive(
+ i, uploadDirectory, (verifyDownloads ? &hash : nullptr))) {
+ return false;
+ }
+
+ archiveUrls.push_back(Quote(cmStrCat(urlPrefix, i->ArchiveFile)));
+ archiveFiles.push_back(
+ Quote(cmSystemTools::GetFilenameWithoutLastExtension(i->ArchiveFile)));
+ archiveHashes.push_back(Quote(hash));
+ archiveComponents.push_back(
+ Quote(CreateRecursiveComponentPath(i->Group, i->Name)));
+ }
+
+ SetOption("CPACK_INNOSETUP_DOWNLOAD_COUNT_INTERNAL",
+ std::to_string(archiveFiles.size()));
+ SetOption("CPACK_INNOSETUP_DOWNLOAD_URLS_INTERNAL",
+ cmJoin(archiveUrls, ", "));
+ SetOption("CPACK_INNOSETUP_DOWNLOAD_ARCHIVES_INTERNAL",
+ cmJoin(archiveFiles, ", "));
+ SetOption("CPACK_INNOSETUP_DOWNLOAD_HASHES_INTERNAL",
+ cmJoin(archiveHashes, ", "));
+ SetOption("CPACK_INNOSETUP_DOWNLOAD_COMPONENTS_INTERNAL",
+ cmJoin(archiveComponents, ", "));
+
+ static const std::string& downloadLines =
+ "#define protected CPackDownloadCount "
+ "@CPACK_INNOSETUP_DOWNLOAD_COUNT_INTERNAL@\n"
+ "#dim protected CPackDownloadUrls[CPackDownloadCount] "
+ "{@CPACK_INNOSETUP_DOWNLOAD_URLS_INTERNAL@}\n"
+ "#dim protected CPackDownloadArchives[CPackDownloadCount] "
+ "{@CPACK_INNOSETUP_DOWNLOAD_ARCHIVES_INTERNAL@}\n"
+ "#dim protected CPackDownloadHashes[CPackDownloadCount] "
+ "{@CPACK_INNOSETUP_DOWNLOAD_HASHES_INTERNAL@}\n"
+ "#dim protected CPackDownloadComponents[CPackDownloadCount] "
+ "{@CPACK_INNOSETUP_DOWNLOAD_COMPONENTS_INTERNAL@}";
+
+ std::string output;
+ if (!ConfigureString(downloadLines, output)) {
+ return false;
+ }
+ codeIncludes.push_back(output);
+ }
+
+ // Add the required script
+ const std::string& componentsScriptTemplate =
+ FindTemplate("ISComponents.pas");
+ if (componentsScriptTemplate.empty()) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Could not find additional Inno Setup script file."
+ << std::endl);
+ return false;
+ }
+
+ codeIncludes.push_back("#include " + QuotePath(componentsScriptTemplate) +
+ "\n");
+
+ return true;
+}
+
+bool cmCPackInnoSetupGenerator::ConfigureISScript()
+{
+ const std::string& isScriptTemplate = FindTemplate("ISScript.template.in");
+ const std::string& isScriptFile =
+ cmStrCat(GetOption("CPACK_TOPLEVEL_DIRECTORY"), "/ISScript.iss");
+
+ if (isScriptTemplate.empty()) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Could not find Inno Setup installer template file."
+ << std::endl);
+ return false;
+ }
+
+ // Create internal variables
+ std::vector<std::string> setupSection;
+ for (const auto& i : setupDirectives) {
+ setupSection.push_back(cmStrCat(i.first, '=', TranslateBool(i.second)));
+ }
+
+ // Also create comments if the sections are empty
+ const std::string& defaultMessage =
+ "; CPack didn't find any entries for this section";
+
+ if (IsSet("CPACK_CREATE_DESKTOP_LINKS") &&
+ !GetOption("CPACK_CREATE_DESKTOP_LINKS").Get()->empty()) {
+ cmCPackInnoSetupKeyValuePairs tasks;
+ tasks["Name"] = "\"desktopicon\"";
+ tasks["Description"] = "\"{cm:CreateDesktopIcon}\"";
+ tasks["GroupDescription"] = "\"{cm:AdditionalIcons}\"";
+ tasks["Flags"] = "unchecked";
+
+ if (!desktopIconComponents.empty()) {
+ tasks["Components"] = cmJoin(desktopIconComponents, " ");
+ }
+
+ SetOption("CPACK_INNOSETUP_TASKS_INTERNAL", ISKeyValueLine(tasks));
+ } else {
+ SetOption("CPACK_INNOSETUP_TASKS_INTERNAL", defaultMessage);
+ }
+
+ SetOption("CPACK_INNOSETUP_INCLUDES_INTERNAL",
+ includeDirectives.empty() ? "; No extra script files specified"
+ : cmJoin(includeDirectives, "\n"));
+ SetOption("CPACK_INNOSETUP_SETUP_INTERNAL",
+ setupSection.empty() ? defaultMessage
+ : cmJoin(setupSection, "\n"));
+ SetOption("CPACK_INNOSETUP_LANGUAGES_INTERNAL",
+ languageInstructions.empty() ? defaultMessage
+ : cmJoin(languageInstructions, "\n"));
+ SetOption("CPACK_INNOSETUP_DIRS_INTERNAL",
+ dirInstructions.empty() ? defaultMessage
+ : cmJoin(dirInstructions, "\n"));
+ SetOption("CPACK_INNOSETUP_FILES_INTERNAL",
+ fileInstructions.empty() ? defaultMessage
+ : cmJoin(fileInstructions, "\n"));
+ SetOption("CPACK_INNOSETUP_TYPES_INTERNAL",
+ typeInstructions.empty() ? defaultMessage
+ : cmJoin(typeInstructions, "\n"));
+ SetOption("CPACK_INNOSETUP_COMPONENTS_INTERNAL",
+ componentInstructions.empty()
+ ? defaultMessage
+ : cmJoin(componentInstructions, "\n"));
+ SetOption("CPACK_INNOSETUP_ICONS_INTERNAL",
+ iconInstructions.empty() ? defaultMessage
+ : cmJoin(iconInstructions, "\n"));
+ SetOption("CPACK_INNOSETUP_RUN_INTERNAL",
+ runInstructions.empty() ? defaultMessage
+ : cmJoin(runInstructions, "\n"));
+ SetOption("CPACK_INNOSETUP_CODE_INTERNAL",
+ codeIncludes.empty() ? "{ No extra code files specified }"
+ : cmJoin(codeIncludes, "\n"));
+
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE,
+ "Configure file: " << isScriptTemplate << " to "
+ << isScriptFile << std::endl);
+
+ return ConfigureFile(isScriptTemplate, isScriptFile);
+}
+
+bool cmCPackInnoSetupGenerator::Compile()
+{
+ const std::string& isScriptFile =
+ cmStrCat(GetOption("CPACK_TOPLEVEL_DIRECTORY"), "/ISScript.iss");
+ const std::string& isccLogFile =
+ cmStrCat(GetOption("CPACK_TOPLEVEL_DIRECTORY"), "/ISCCOutput.log");
+
+ std::vector<std::string> isccArgs;
+
+ // Custom defines
+ for (const std::string& i : GetOptions()) {
+ if (cmHasPrefix(i, "CPACK_INNOSETUP_DEFINE_")) {
+ const std::string& name = i.substr(cmStrLen("CPACK_INNOSETUP_DEFINE_"));
+ isccArgs.push_back(
+ cmStrCat("\"/D", name, '=', TranslateBool(GetOption(i)), '"'));
+ }
+ }
+
+ if (IsSet("CPACK_INNOSETUP_EXECUTABLE_ARGUMENTS")) {
+ const cmList args(GetOption("CPACK_INNOSETUP_EXECUTABLE_ARGUMENTS"));
+
+ isccArgs.insert(isccArgs.end(), args.begin(), args.end());
+ }
+
+ const std::string& isccCmd =
+ cmStrCat(QuotePath(GetOption("CPACK_INSTALLER_PROGRAM")), ' ',
+ cmJoin(isccArgs, " "), ' ', QuotePath(isScriptFile));
+
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << isccCmd << std::endl);
+
+ std::string output;
+ int retVal = 1;
+ const bool res = cmSystemTools::RunSingleCommand(
+ isccCmd, &output, &output, &retVal, nullptr, this->GeneratorVerbose,
+ cmDuration::zero());
+
+ if (!res || retVal) {
+ cmGeneratedFileStream ofs(isccLogFile);
+ ofs << "# Run command: " << isccCmd << std::endl
+ << "# Output:" << std::endl
+ << output << std::endl;
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Problem running ISCC. Please check "
+ << isccLogFile << " for errors." << std::endl);
+ return false;
+ }
+
+ return true;
+}
+
+bool cmCPackInnoSetupGenerator::BuildDownloadedComponentArchive(
+ cmCPackComponent* component, const std::string& uploadDirectory,
+ std::string* hash)
+{
+ // Remove the old archive, if one exists
+ const std::string& archiveFile =
+ uploadDirectory + '/' + component->ArchiveFile;
+ cmCPackLogger(cmCPackLog::LOG_OUTPUT,
+ "- Building downloaded component archive: " << archiveFile
+ << std::endl);
+ if (cmSystemTools::FileExists(archiveFile, true)) {
+ if (!cmSystemTools::RemoveFile(archiveFile)) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Unable to remove archive file " << archiveFile
+ << std::endl);
+ return false;
+ }
+ }
+
+ // Find a ZIP program
+ if (!IsSet("ZIP_EXECUTABLE")) {
+ ReadListFile("Internal/CPack/CPackZIP.cmake");
+
+ if (!IsSet("ZIP_EXECUTABLE")) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Unable to find ZIP program" << std::endl);
+ return false;
+ }
+ }
+
+ if (!RequireOption("CPACK_TOPLEVEL_DIRECTORY") ||
+ !RequireOption("CPACK_TEMPORARY_DIRECTORY") ||
+ !RequireOption("CPACK_ZIP_NEED_QUOTES") ||
+ !RequireOption("CPACK_ZIP_COMMAND")) {
+ return false;
+ }
+
+ // The directory where this component's files reside
+ const std::string& dirName =
+ cmStrCat(GetOption("CPACK_TEMPORARY_DIRECTORY"), '/', component->Name);
+
+ // Build the list of files to go into this archive
+ const std::string& zipListFileName =
+ cmStrCat(GetOption("CPACK_TEMPORARY_DIRECTORY"), "/winZip.filelist");
+ const bool needQuotesInFile = cmIsOn(GetOption("CPACK_ZIP_NEED_QUOTES"));
+ { // the scope is needed for cmGeneratedFileStream
+ cmGeneratedFileStream out(zipListFileName);
+ for (const std::string& i : component->Files) {
+ out << (needQuotesInFile ? Quote(i) : i) << std::endl;
+ }
+ }
+
+ // Build the archive in the upload area
+ std::string cmd = GetOption("CPACK_ZIP_COMMAND");
+ cmsys::SystemTools::ReplaceString(cmd, "<ARCHIVE>", archiveFile.c_str());
+ cmsys::SystemTools::ReplaceString(cmd, "<FILELIST>",
+ zipListFileName.c_str());
+ std::string output;
+ int retVal = -1;
+ const bool res = cmSystemTools::RunSingleCommand(
+ cmd, &output, &output, &retVal, dirName.c_str(), this->GeneratorVerbose,
+ cmDuration::zero());
+ if (!res || retVal) {
+ std::string tmpFile =
+ cmStrCat(GetOption("CPACK_TOPLEVEL_DIRECTORY"), "/CompressZip.log");
+ cmGeneratedFileStream ofs(tmpFile);
+ ofs << "# Run command: " << cmd << std::endl
+ << "# Output:" << std::endl
+ << output << std::endl;
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Problem running zip command: " << cmd << std::endl
+ << "Please check " << tmpFile
+ << " for errors"
+ << std::endl);
+ return false;
+ }
+
+ // Try to get the SHA256 hash of the archive file
+ if (hash == nullptr) {
+ return true;
+ }
+
+#ifdef _WIN32
+ const std::string& hashCmd =
+ cmStrCat("certutil -hashfile ", QuotePath(archiveFile), " SHA256");
+
+ std::string hashOutput;
+ int hashRetVal = -1;
+ const bool hashRes = cmSystemTools::RunSingleCommand(
+ hashCmd, &hashOutput, &hashOutput, &hashRetVal, nullptr,
+ this->GeneratorVerbose, cmDuration::zero());
+ if (!hashRes || hashRetVal) {
+ cmCPackLogger(cmCPackLog::LOG_WARNING,
+ "Problem running certutil command: " << hashCmd
+ << std::endl);
+ }
+ *hash = cmTrimWhitespace(cmTokenize(hashOutput, "\n").at(1));
+
+ if (hash->length() != 64) {
+ cmCPackLogger(cmCPackLog::LOG_WARNING,
+ "Problem parsing certutil output of command: " << hashCmd
+ << std::endl);
+ hash->clear();
+ }
+#endif
+
+ return true;
+}
+
+cmValue cmCPackInnoSetupGenerator::RequireOption(const std::string& key)
+{
+ cmValue value = GetOption(key);
+
+ if (!value) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Required variable " << key << " not set" << std::endl);
+ }
+
+ return value;
+}
+
+std::string cmCPackInnoSetupGenerator::CustomComponentInstallDirectory(
+ const cmCPackComponent* component)
+{
+ cmValue outputDir = GetOption(
+ cmStrCat("CPACK_INNOSETUP_", component->Name, "_INSTALL_DIRECTORY"));
+ if (outputDir) {
+ std::string destDir = cmSystemTools::ConvertToWindowsOutputPath(outputDir);
+ cmStripSuffixIfExists(destDir, '\\');
+
+ /*
+ * Add a dir instruction for the custom directory
+ * (only once and not for Inno Setup constants ending with '}')
+ */
+ static std::vector<std::string> customDirectories;
+ if (!cmHasSuffix(destDir, '}') &&
+ std::find(customDirectories.begin(), customDirectories.end(),
+ component->Name) == customDirectories.end()) {
+ cmCPackInnoSetupKeyValuePairs params;
+ params["Name"] = QuotePath(destDir);
+ params["Components"] =
+ CreateRecursiveComponentPath(component->Group, component->Name);
+
+ dirInstructions.push_back(ISKeyValueLine(params));
+ customDirectories.push_back(component->Name);
+ }
+ return destDir;
+ }
+
+ return "{app}";
+}
+
+std::string cmCPackInnoSetupGenerator::TranslateBool(const std::string& value)
+{
+ if (value.empty()) {
+ return value;
+ }
+
+ SetOptionIfNotSet("CPACK_INNOSETUP_USE_CMAKE_BOOL_FORMAT", "ON");
+ if (GetOption("CPACK_INNOSETUP_USE_CMAKE_BOOL_FORMAT").IsOn()) {
+ if (cmIsOn(value)) {
+ return "yes";
+ }
+ if (cmIsOff(value)) {
+ return "no";
+ }
+ }
+
+ return value;
+}
+
+std::string cmCPackInnoSetupGenerator::ISKeyValueLine(
+ const cmCPackInnoSetupKeyValuePairs& params)
+{
+ /*
+ * To simplify readability of the generated code, the keys are sorted.
+ * Unknown keys are ignored to avoid errors during compilation.
+ */
+ static const char* const availableKeys[] = {
+ "Source", "DestDir", "Name", "Filename",
+ "Description", "GroupDescription", "MessagesFile", "Types",
+ "ExternalSize", "BeforeInstall", "Flags", "Components",
+ "Tasks"
+ };
+
+ std::vector<std::string> keys;
+ for (const char* i : availableKeys) {
+ if (params.count(i)) {
+ keys.push_back(cmStrCat(i, ": ", params.at(i)));
+ }
+ }
+
+ return cmJoin(keys, "; ");
+}
+
+std::string cmCPackInnoSetupGenerator::CreateRecursiveComponentPath(
+ cmCPackComponentGroup* group, const std::string& path)
+{
+ if (group == nullptr) {
+ return path;
+ }
+
+ const std::string& newPath =
+ path.empty() ? group->Name : cmStrCat(group->Name, '\\', path);
+ return CreateRecursiveComponentPath(group->ParentGroup, newPath);
+}
+
+void cmCPackInnoSetupGenerator::CreateRecursiveComponentGroups(
+ cmCPackComponentGroup* group)
+{
+ if (group == nullptr) {
+ return;
+ }
+
+ CreateRecursiveComponentGroups(group->ParentGroup);
+
+ static std::vector<cmCPackComponentGroup*> processedGroups;
+ if (std::find(processedGroups.begin(), processedGroups.end(), group) ==
+ processedGroups.end()) {
+ processedGroups.push_back(group);
+
+ cmCPackInnoSetupKeyValuePairs params;
+
+ params["Name"] = Quote(CreateRecursiveComponentPath(group));
+ params["Description"] = Quote(group->DisplayName);
+
+ componentInstructions.push_back(ISKeyValueLine(params));
+ }
+}
+
+std::string cmCPackInnoSetupGenerator::Quote(const std::string& string)
+{
+ if (cmHasPrefix(string, '"') && cmHasSuffix(string, '"')) {
+ return Quote(string.substr(1, string.length() - 2));
+ }
+
+ // Double quote syntax
+ std::string nString = string;
+ cmSystemTools::ReplaceString(nString, "\"", "\"\"");
+ return cmStrCat('"', nString, '"');
+}
+
+std::string cmCPackInnoSetupGenerator::QuotePath(const std::string& path)
+{
+ return Quote(cmSystemTools::ConvertToWindowsOutputPath(path));
+}
+
+std::string cmCPackInnoSetupGenerator::PrepareForConstant(
+ const std::string& string)
+{
+ std::string nString = string;
+
+ cmSystemTools::ReplaceString(nString, "%", "%25"); // First replacement!
+ cmSystemTools::ReplaceString(nString, "\"", "%22");
+ cmSystemTools::ReplaceString(nString, ",", "%2c");
+ cmSystemTools::ReplaceString(nString, "|", "%7c");
+ cmSystemTools::ReplaceString(nString, "}", "%7d");
+
+ return nString;
+}
diff --git a/Source/CPack/cmCPackInnoSetupGenerator.h b/Source/CPack/cmCPackInnoSetupGenerator.h
new file mode 100644
index 0000000000..342f227e00
--- /dev/null
+++ b/Source/CPack/cmCPackInnoSetupGenerator.h
@@ -0,0 +1,116 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+file Copyright.txt or https://cmake.org/licensing for details. */
+
+#pragma once
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "cmCPackGenerator.h"
+#include "cmValue.h"
+
+using cmCPackInnoSetupKeyValuePairs = std::map<std::string, std::string>;
+
+class cmCPackComponentGroup;
+class cmCPackComponent;
+
+/** \class cmCPackInnoSetupGenerator
+ * \brief A generator for Inno Setup
+ *
+ * https://jrsoftware.org/isinfo.php
+ */
+class cmCPackInnoSetupGenerator : public cmCPackGenerator
+{
+public:
+ cmCPackTypeMacro(cmCPackInnoSetupGenerator, cmCPackGenerator);
+
+ /**
+ * Construct generator
+ */
+ cmCPackInnoSetupGenerator();
+ ~cmCPackInnoSetupGenerator() override;
+
+ static bool CanGenerate();
+
+protected:
+ int InitializeInternal() override;
+ int PackageFiles() override;
+
+ inline const char* GetOutputExtension() override { return ".exe"; }
+
+ inline cmCPackGenerator::CPackSetDestdirSupport SupportsSetDestdir()
+ const override
+ {
+ return cmCPackGenerator::SETDESTDIR_UNSUPPORTED;
+ }
+
+ inline bool SupportsAbsoluteDestination() const override { return false; }
+ inline bool SupportsComponentInstallation() const override { return true; }
+
+private:
+ bool ProcessSetupSection();
+ bool ProcessFiles();
+ bool ProcessComponents();
+
+ bool ConfigureISScript();
+ bool Compile();
+
+ bool BuildDownloadedComponentArchive(cmCPackComponent* component,
+ const std::string& uploadDirectory,
+ std::string* hash);
+
+ /**
+ * Returns the option's value or an empty string if the option isn't set.
+ */
+ cmValue RequireOption(const std::string& key);
+
+ std::string CustomComponentInstallDirectory(
+ const cmCPackComponent* component);
+
+ /**
+ * Translates boolean expressions into "yes" or "no", as required in
+ * Inno Setup (only if "CPACK_INNOSETUP_USE_CMAKE_BOOL_FORMAT" is on).
+ */
+ std::string TranslateBool(const std::string& value);
+
+ /**
+ * Creates a typical line of key and value pairs using the given map.
+ *
+ * (e.g.: Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}";
+ * GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked)
+ */
+ std::string ISKeyValueLine(const cmCPackInnoSetupKeyValuePairs& params);
+
+ std::string CreateRecursiveComponentPath(cmCPackComponentGroup* group,
+ const std::string& path = "");
+
+ void CreateRecursiveComponentGroups(cmCPackComponentGroup* group);
+
+ /**
+ * These functions add quotes if the given value hasn't already quotes.
+ * Paths are converted into the format used by Windows before.
+ */
+ std::string Quote(const std::string& string);
+ std::string QuotePath(const std::string& path);
+
+ /**
+ * This function replaces the following 5 characters with their %-encoding:
+ * '|' '}' ',' '%' '"'
+ * Required for Inno Setup constants like {cm:...}
+ */
+ std::string PrepareForConstant(const std::string& string);
+
+ std::vector<std::string> includeDirectives;
+ cmCPackInnoSetupKeyValuePairs setupDirectives;
+ bool toplevelProgramFolder;
+ std::vector<std::string> languageInstructions;
+ std::vector<std::string> fileInstructions;
+ std::vector<std::string> dirInstructions;
+ std::vector<std::string> typeInstructions;
+ std::vector<std::string> componentInstructions;
+ std::vector<std::string> iconInstructions;
+ std::vector<std::string> desktopIconComponents;
+ std::vector<std::string> runInstructions;
+ std::vector<std::string> codeIncludes;
+};
diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx
index d7119c5223..7749b29303 100644
--- a/Source/CPack/cmCPackNSISGenerator.cxx
+++ b/Source/CPack/cmCPackNSISGenerator.cxx
@@ -19,6 +19,7 @@
#include "cmCPackLog.h"
#include "cmDuration.h"
#include "cmGeneratedFileStream.h"
+#include "cmList.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"
@@ -245,8 +246,7 @@ int cmCPackNSISGenerator::PackageFiles()
std::string nsisPreArguments;
if (cmValue nsisArguments =
this->GetOption("CPACK_NSIS_EXECUTABLE_PRE_ARGUMENTS")) {
- std::vector<std::string> expandedArguments;
- cmExpandList(nsisArguments, expandedArguments);
+ cmList expandedArguments{ nsisArguments };
for (auto& arg : expandedArguments) {
if (!cmHasPrefix(arg, NSIS_OPT)) {
@@ -259,8 +259,7 @@ int cmCPackNSISGenerator::PackageFiles()
std::string nsisPostArguments;
if (cmValue nsisArguments =
this->GetOption("CPACK_NSIS_EXECUTABLE_POST_ARGUMENTS")) {
- std::vector<std::string> expandedArguments;
- cmExpandList(nsisArguments, expandedArguments);
+ cmList expandedArguments{ nsisArguments };
for (auto& arg : expandedArguments) {
if (!cmHasPrefix(arg, NSIS_OPT)) {
nsisPostArguments = cmStrCat(nsisPostArguments, NSIS_OPT);
@@ -545,14 +544,14 @@ int cmCPackNSISGenerator::InitializeInternal()
this->GetOption("CPACK_CREATE_DESKTOP_LINKS");
cmValue cpackNsisExecutablesDirectory =
this->GetOption("CPACK_NSIS_EXECUTABLES_DIRECTORY");
- std::vector<std::string> cpackPackageDesktopLinksVector;
+ cmList cpackPackageDesktopLinksList;
if (cpackPackageDeskTopLinks) {
cmCPackLogger(cmCPackLog::LOG_DEBUG,
"CPACK_CREATE_DESKTOP_LINKS: " << cpackPackageDeskTopLinks
<< std::endl);
- cmExpandList(cpackPackageDeskTopLinks, cpackPackageDesktopLinksVector);
- for (std::string const& cpdl : cpackPackageDesktopLinksVector) {
+ cpackPackageDesktopLinksList.assign(cpackPackageDeskTopLinks);
+ for (std::string const& cpdl : cpackPackageDesktopLinksList) {
cmCPackLogger(cmCPackLog::LOG_DEBUG,
"CPACK_CREATE_DESKTOP_LINKS: " << cpdl << std::endl);
}
@@ -569,9 +568,8 @@ int cmCPackNSISGenerator::InitializeInternal()
cmCPackLogger(cmCPackLog::LOG_DEBUG,
"The cpackPackageExecutables: " << cpackPackageExecutables
<< "." << std::endl);
- std::vector<std::string> cpackPackageExecutablesVector =
- cmExpandedList(cpackPackageExecutables);
- if (cpackPackageExecutablesVector.size() % 2 != 0) {
+ cmList cpackPackageExecutablesList{ cpackPackageExecutables };
+ if (cpackPackageExecutablesList.size() % 2 != 0) {
cmCPackLogger(
cmCPackLog::LOG_ERROR,
"CPACK_PACKAGE_EXECUTABLES should contain pairs of <executable> and "
@@ -579,9 +577,9 @@ int cmCPackNSISGenerator::InitializeInternal()
<< std::endl);
return 0;
}
- std::vector<std::string>::iterator it;
- for (it = cpackPackageExecutablesVector.begin();
- it != cpackPackageExecutablesVector.end(); ++it) {
+ cmList::iterator it;
+ for (it = cpackPackageExecutablesList.begin();
+ it != cpackPackageExecutablesList.end(); ++it) {
std::string execName = *it;
++it;
std::string linkName = *it;
@@ -592,7 +590,7 @@ int cmCPackNSISGenerator::InitializeInternal()
<< ".lnk\"" << std::endl;
// see if CPACK_CREATE_DESKTOP_LINK_ExeName is on
// if so add a desktop link
- if (cm::contains(cpackPackageDesktopLinksVector, execName)) {
+ if (cm::contains(cpackPackageDesktopLinksList, execName)) {
str << " StrCmp \"$INSTALL_DESKTOP\" \"1\" 0 +2\n";
str << " CreateShortCut \"$DESKTOP\\" << linkName
<< R"(.lnk" "$INSTDIR\)" << cpackNsisExecutablesDirectory << "\\"
@@ -622,9 +620,8 @@ void cmCPackNSISGenerator::CreateMenuLinks(std::ostream& str,
}
cmCPackLogger(cmCPackLog::LOG_DEBUG,
"The cpackMenuLinks: " << cpackMenuLinks << "." << std::endl);
- std::vector<std::string> cpackMenuLinksVector =
- cmExpandedList(cpackMenuLinks);
- if (cpackMenuLinksVector.size() % 2 != 0) {
+ cmList cpackMenuLinksList{ cpackMenuLinks };
+ if (cpackMenuLinksList.size() % 2 != 0) {
cmCPackLogger(
cmCPackLog::LOG_ERROR,
"CPACK_NSIS_MENU_LINKS should contain pairs of <shortcut target> and "
@@ -636,9 +633,8 @@ void cmCPackNSISGenerator::CreateMenuLinks(std::ostream& str,
static cmsys::RegularExpression urlRegex(
"^(mailto:|(ftps?|https?|news)://).*$");
- std::vector<std::string>::iterator it;
- for (it = cpackMenuLinksVector.begin(); it != cpackMenuLinksVector.end();
- ++it) {
+ cmList::iterator it;
+ for (it = cpackMenuLinksList.begin(); it != cpackMenuLinksList.end(); ++it) {
std::string sourceName = *it;
const bool url = urlRegex.find(sourceName);
diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx
index 234bc59352..90716e6e0d 100644
--- a/Source/CPack/cpack.cxx
+++ b/Source/CPack/cpack.cxx
@@ -29,6 +29,7 @@
#include "cmDocumentationEntry.h"
#include "cmGlobalGenerator.h"
#include "cmJSONState.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmState.h"
#include "cmStateSnapshot.h"
@@ -509,8 +510,8 @@ int main(int argc, char const* const* argv)
cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
"CPack generator not specified\n");
} else {
- std::vector<std::string> generatorsVector = cmExpandedList(*genList);
- for (std::string const& gen : generatorsVector) {
+ cmList generatorsList{ *genList };
+ for (std::string const& gen : generatorsList) {
cmMakefile::ScopePushPop raii(&globalMF);
cmMakefile* mf = &globalMF;
cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE,
diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx
index c6387ab353..882b579fff 100644
--- a/Source/CTest/cmCTestBuildHandler.cxx
+++ b/Source/CTest/cmCTestBuildHandler.cxx
@@ -17,6 +17,7 @@
#include "cmDuration.h"
#include "cmFileTimeCache.h"
#include "cmGeneratedFileStream.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmProcessOutput.h"
#include "cmStringAlgorithms.h"
diff --git a/Source/CTest/cmCTestConfigureCommand.cxx b/Source/CTest/cmCTestConfigureCommand.cxx
index 1f3633de5b..bae1f54011 100644
--- a/Source/CTest/cmCTestConfigureCommand.cxx
+++ b/Source/CTest/cmCTestConfigureCommand.cxx
@@ -4,13 +4,13 @@
#include <cstring>
#include <sstream>
-#include <vector>
#include <cmext/string_view>
#include "cmCTest.h"
#include "cmCTestConfigureHandler.h"
#include "cmGlobalGenerator.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -25,10 +25,10 @@ void cmCTestConfigureCommand::BindArguments()
cmCTestGenericHandler* cmCTestConfigureCommand::InitializeHandler()
{
- std::vector<std::string> options;
+ cmList options;
if (!this->Options.empty()) {
- cmExpandList(this->Options, options);
+ options.assign(this->Options);
}
if (this->CTest->GetCTestConfiguration("BuildDirectory").empty()) {
diff --git a/Source/CTest/cmCTestGIT.cxx b/Source/CTest/cmCTestGIT.cxx
index b2fb069fd5..a6e7ac52c8 100644
--- a/Source/CTest/cmCTestGIT.cxx
+++ b/Source/CTest/cmCTestGIT.cxx
@@ -14,6 +14,7 @@
#include "cmCTest.h"
#include "cmCTestVC.h"
+#include "cmList.h"
#include "cmProcessOutput.h"
#include "cmProcessTools.h"
#include "cmStringAlgorithms.h"
@@ -215,7 +216,7 @@ bool cmCTestGIT::UpdateByFetchAndReset()
bool cmCTestGIT::UpdateByCustom(std::string const& custom)
{
- std::vector<std::string> git_custom_command = cmExpandedList(custom, true);
+ cmList git_custom_command{ custom, cmList::EmptyElements::Yes };
std::vector<char const*> git_custom;
git_custom.reserve(git_custom_command.size() + 1);
for (std::string const& i : git_custom_command) {
diff --git a/Source/CTest/cmCTestP4.cxx b/Source/CTest/cmCTestP4.cxx
index 0e67c4122e..e22ec4b556 100644
--- a/Source/CTest/cmCTestP4.cxx
+++ b/Source/CTest/cmCTestP4.cxx
@@ -13,9 +13,9 @@
#include "cmCTest.h"
#include "cmCTestVC.h"
+#include "cmList.h"
#include "cmProcessTools.h"
#include "cmRange.h"
-#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
cmCTestP4::cmCTestP4(cmCTest* ct, std::ostream& log)
@@ -460,7 +460,7 @@ bool cmCTestP4::LoadModifications()
bool cmCTestP4::UpdateCustom(const std::string& custom)
{
- std::vector<std::string> p4_custom_command = cmExpandedList(custom, true);
+ cmList p4_custom_command{ custom, cmList::EmptyElements::Yes };
std::vector<char const*> p4_custom;
p4_custom.reserve(p4_custom_command.size() + 1);
diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx
index ee06b29c67..461ad1a947 100644
--- a/Source/CTest/cmCTestScriptHandler.cxx
+++ b/Source/CTest/cmCTestScriptHandler.cxx
@@ -33,6 +33,7 @@
#include "cmDuration.h"
#include "cmGeneratedFileStream.h"
#include "cmGlobalGenerator.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmState.h"
#include "cmStateDirectory.h"
@@ -521,7 +522,7 @@ int cmCTestScriptHandler::RunCurrentScript()
// set any environment variables
if (!this->CTestEnv.empty()) {
- std::vector<std::string> envArgs = cmExpandedList(this->CTestEnv);
+ cmList envArgs{ this->CTestEnv };
cmSystemTools::AppendEnv(envArgs);
}
@@ -625,7 +626,7 @@ int cmCTestScriptHandler::PerformExtraUpdates()
// do an initial cvs update as required
command = this->UpdateCmd;
for (std::string const& eu : this->ExtraUpdates) {
- std::vector<std::string> cvsArgs = cmExpandedList(eu);
+ cmList cvsArgs{ eu };
if (cvsArgs.size() == 2) {
std::string fullCommand = cmStrCat(command, " update ", cvsArgs[1]);
output.clear();
@@ -764,7 +765,7 @@ int cmCTestScriptHandler::RunConfigurationDashboard()
}
// run ctest, it may be more than one command in here
- std::vector<std::string> ctestCommands = cmExpandedList(this->CTestCmd);
+ cmList ctestCommands{ this->CTestCmd };
// for each variable/argument do a putenv
for (std::string const& ctestCommand : ctestCommands) {
command = ctestCommand;
diff --git a/Source/CTest/cmCTestSubmitCommand.cxx b/Source/CTest/cmCTestSubmitCommand.cxx
index a1933cccb1..a92f9f28ec 100644
--- a/Source/CTest/cmCTestSubmitCommand.cxx
+++ b/Source/CTest/cmCTestSubmitCommand.cxx
@@ -13,10 +13,10 @@
#include "cmCTest.h"
#include "cmCTestSubmitHandler.h"
#include "cmCommand.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmRange.h"
-#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"
@@ -64,14 +64,14 @@ cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler()
cmValue notesFilesVariable =
this->Makefile->GetDefinition("CTEST_NOTES_FILES");
if (notesFilesVariable) {
- std::vector<std::string> notesFiles = cmExpandedList(*notesFilesVariable);
+ cmList notesFiles{ *notesFilesVariable };
this->CTest->GenerateNotesFile(notesFiles);
}
cmValue extraFilesVariable =
this->Makefile->GetDefinition("CTEST_EXTRA_SUBMIT_FILES");
if (extraFilesVariable) {
- std::vector<std::string> extraFiles = cmExpandedList(*extraFilesVariable);
+ cmList extraFiles{ *extraFilesVariable };
if (!this->CTest->SubmitExtraFiles(extraFiles)) {
this->SetError("problem submitting extra files.");
return nullptr;
diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx
index 3ff8c8f280..a095e5dc63 100644
--- a/Source/CTest/cmCTestSubmitHandler.cxx
+++ b/Source/CTest/cmCTestSubmitHandler.cxx
@@ -22,6 +22,7 @@
#include "cmCurl.h"
#include "cmDuration.h"
#include "cmGeneratedFileStream.h"
+#include "cmList.h"
#include "cmState.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -160,7 +161,7 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(
/* In windows, this will init the winsock stuff */
::curl_global_init(CURL_GLOBAL_ALL);
std::string curlopt(this->CTest->GetCTestConfiguration("CurlOptions"));
- std::vector<std::string> args = cmExpandedList(curlopt);
+ cmList args{ curlopt };
bool verifyPeerOff = false;
bool verifyHostOff = false;
for (std::string const& arg : args) {
@@ -499,7 +500,7 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file,
cmCTestCurl curl(this->CTest);
curl.SetQuiet(this->Quiet);
std::string curlopt(this->CTest->GetCTestConfiguration("CurlOptions"));
- std::vector<std::string> args = cmExpandedList(curlopt);
+ cmList args{ curlopt };
curl.SetCurlOptions(args);
auto submitInactivityTimeout = this->GetSubmitInactivityTimeout();
if (submitInactivityTimeout != 0) {
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index f693ace4b5..3a1cb64708 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -38,6 +38,7 @@
#include "cmGeneratedFileStream.h"
#include "cmGlobalGenerator.h"
#include "cmJSONState.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmState.h"
#include "cmStateSnapshot.h"
@@ -2203,9 +2204,8 @@ bool cmCTestTestHandler::SetTestsProperties(
for (cmCTestTestProperties& rt : this->TestList) {
if (t == rt.Name) {
if (key == "_BACKTRACE_TRIPLES"_s) {
- std::vector<std::string> triples;
// allow empty args in the triples
- cmExpandList(val, triples, true);
+ cmList triples{ val, cmList::EmptyElements::Yes };
// Ensure we have complete triples otherwise the data is corrupt.
if (triples.size() % 3 == 0) {
@@ -2214,7 +2214,7 @@ bool cmCTestTestHandler::SetTestsProperties(
// the first entry represents the top of the trace so we need to
// reconstruct the backtrace in reverse
- for (size_t i = triples.size(); i >= 3; i -= 3) {
+ for (auto i = triples.size(); i >= 3; i -= 3) {
cmListFileContext fc;
fc.FilePath = triples[i - 3];
long line = 0;
@@ -2235,19 +2235,19 @@ bool cmCTestTestHandler::SetTestsProperties(
} else if (key == "ATTACHED_FILES_ON_FAIL"_s) {
cmExpandList(val, rt.AttachOnFail);
} else if (key == "RESOURCE_LOCK"_s) {
- std::vector<std::string> lval = cmExpandedList(val);
+ cmList lval{ val };
rt.LockedResources.insert(lval.begin(), lval.end());
} else if (key == "FIXTURES_SETUP"_s) {
- std::vector<std::string> lval = cmExpandedList(val);
+ cmList lval{ val };
rt.FixturesSetup.insert(lval.begin(), lval.end());
} else if (key == "FIXTURES_CLEANUP"_s) {
- std::vector<std::string> lval = cmExpandedList(val);
+ cmList lval{ val };
rt.FixturesCleanup.insert(lval.begin(), lval.end());
} else if (key == "FIXTURES_REQUIRED"_s) {
- std::vector<std::string> lval = cmExpandedList(val);
+ cmList lval{ val };
rt.FixturesRequired.insert(lval.begin(), lval.end());
} else if (key == "TIMEOUT"_s) {
@@ -2260,12 +2260,12 @@ bool cmCTestTestHandler::SetTestsProperties(
} else if (key == "RUN_SERIAL"_s) {
rt.RunSerial = cmIsOn(val);
} else if (key == "FAIL_REGULAR_EXPRESSION"_s) {
- std::vector<std::string> lval = cmExpandedList(val);
+ cmList lval{ val };
for (std::string const& cr : lval) {
rt.ErrorRegularExpressions.emplace_back(cr, cr);
}
} else if (key == "SKIP_REGULAR_EXPRESSION"_s) {
- std::vector<std::string> lval = cmExpandedList(val);
+ cmList lval{ val };
for (std::string const& cr : lval) {
rt.SkipRegularExpressions.emplace_back(cr, cr);
}
@@ -2292,7 +2292,7 @@ bool cmCTestTestHandler::SetTestsProperties(
} else if (key == "ENVIRONMENT_MODIFICATION"_s) {
cmExpandList(val, rt.EnvironmentModification);
} else if (key == "LABELS"_s) {
- std::vector<std::string> Labels = cmExpandedList(val);
+ cmList Labels{ val };
rt.Labels.insert(rt.Labels.end(), Labels.begin(), Labels.end());
// sort the array
std::sort(rt.Labels.begin(), rt.Labels.end());
@@ -2309,21 +2309,21 @@ bool cmCTestTestHandler::SetTestsProperties(
rt.Measurements[val] = "1";
}
} else if (key == "PASS_REGULAR_EXPRESSION"_s) {
- std::vector<std::string> lval = cmExpandedList(val);
+ cmList lval{ val };
for (std::string const& cr : lval) {
rt.RequiredRegularExpressions.emplace_back(cr, cr);
}
} else if (key == "WORKING_DIRECTORY"_s) {
rt.Directory = val;
} else if (key == "TIMEOUT_AFTER_MATCH"_s) {
- std::vector<std::string> propArgs = cmExpandedList(val);
+ cmList propArgs{ val };
if (propArgs.size() != 2) {
cmCTestLog(this->CTest, WARNING,
"TIMEOUT_AFTER_MATCH expects two arguments, found "
<< propArgs.size() << std::endl);
} else {
rt.AlternateTimeout = cmDuration(atof(propArgs[0].c_str()));
- std::vector<std::string> lval = cmExpandedList(propArgs[1]);
+ cmList lval{ propArgs[1] };
for (std::string const& cr : lval) {
rt.TimeoutRegularExpressions.emplace_back(cr, cr);
}
@@ -2365,7 +2365,7 @@ bool cmCTestTestHandler::SetDirectoryProperties(
std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
if (cwd == rt.Directory) {
if (key == "LABELS"_s) {
- std::vector<std::string> DirectoryLabels = cmExpandedList(val);
+ cmList DirectoryLabels{ val };
rt.Labels.insert(rt.Labels.end(), DirectoryLabels.begin(),
DirectoryLabels.end());
diff --git a/Source/CursesDialog/cmCursesCacheEntryComposite.cxx b/Source/CursesDialog/cmCursesCacheEntryComposite.cxx
index e9ec09ee28..fc5450ef2b 100644
--- a/Source/CursesDialog/cmCursesCacheEntryComposite.cxx
+++ b/Source/CursesDialog/cmCursesCacheEntryComposite.cxx
@@ -4,7 +4,6 @@
#include <cassert>
#include <utility>
-#include <vector>
#include <cm/memory>
@@ -15,9 +14,9 @@
#include "cmCursesPathWidget.h"
#include "cmCursesStringWidget.h"
#include "cmCursesWidget.h"
+#include "cmList.h"
#include "cmState.h"
#include "cmStateTypes.h"
-#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"
@@ -76,7 +75,7 @@ cmCursesCacheEntryComposite::cmCursesCacheEntryComposite(
if (stringsProp) {
auto ow =
cm::make_unique<cmCursesOptionsWidget>(this->EntryWidth, 1, 1, 1);
- for (std::string const& opt : cmExpandedList(*stringsProp)) {
+ for (auto const& opt : cmList{ *stringsProp }) {
ow->AddOption(opt);
}
ow->SetOption(*value);
diff --git a/Source/Modules/CMakeBuildUtilities.cmake b/Source/Modules/CMakeBuildUtilities.cmake
index 3dc099f7c8..d6e3e884dc 100644
--- a/Source/Modules/CMakeBuildUtilities.cmake
+++ b/Source/Modules/CMakeBuildUtilities.cmake
@@ -279,7 +279,7 @@ else()
set(ENABLE_LIBXML2 OFF)
set(ENABLE_EXPAT OFF)
set(ENABLE_PCREPOSIX OFF)
- set(ENABLE_LibGCC OFF)
+ set(ENABLE_LIBGCC OFF)
set(ENABLE_CNG OFF)
set(ENABLE_TAR OFF)
set(ENABLE_TAR_SHARED OFF)
diff --git a/Source/cmCMakeHostSystemInformationCommand.cxx b/Source/cmCMakeHostSystemInformationCommand.cxx
index 58129a06b6..8bfd7c87c7 100644
--- a/Source/cmCMakeHostSystemInformationCommand.cxx
+++ b/Source/cmCMakeHostSystemInformationCommand.cxx
@@ -21,10 +21,12 @@
#include "cmArgumentParser.h"
#include "cmExecutionStatus.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmRange.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+#include "cmValue.h"
#include "cmWindowsRegistry.h"
#ifdef _WIN32
@@ -303,7 +305,8 @@ std::map<std::string, std::string> GetOSReleaseVariables(
}
// 2. User provided (append to the CMake prvided)
- makefile.GetDefExpandList("CMAKE_GET_OS_RELEASE_FALLBACK_SCRIPTS", scripts);
+ cmList::append(
+ scripts, makefile.GetDefinition("CMAKE_GET_OS_RELEASE_FALLBACK_SCRIPTS"));
// Filter out files that are not in format `NNN-name.cmake`
auto checkName = [](std::string const& filepath) -> bool {
@@ -330,11 +333,11 @@ std::map<std::string, std::string> GetOSReleaseVariables(
});
// Name of the variable to put the results
- auto const result_variable = "CMAKE_GET_OS_RELEASE_FALLBACK_RESULT"_s;
+ std::string const result_variable{ "CMAKE_GET_OS_RELEASE_FALLBACK_RESULT" };
for (auto const& script : scripts) {
// Unset the result variable
- makefile.RemoveDefinition(result_variable.data());
+ makefile.RemoveDefinition(result_variable);
// include FATAL_ERROR and ERROR in the return status
if (!makefile.ReadListFile(script) ||
@@ -343,8 +346,8 @@ std::map<std::string, std::string> GetOSReleaseVariables(
continue;
}
- std::vector<std::string> variables;
- if (!makefile.GetDefExpandList(result_variable.data(), variables)) {
+ cmList variables{ makefile.GetDefinition(result_variable) };
+ if (variables.empty()) {
// Heh, this script didn't found anything... go try the next one.
continue;
}
@@ -370,7 +373,7 @@ std::map<std::string, std::string> GetOSReleaseVariables(
}
}
- makefile.RemoveDefinition(result_variable.data());
+ makefile.RemoveDefinition(result_variable);
return data;
}
diff --git a/Source/cmCMakePathCommand.cxx b/Source/cmCMakePathCommand.cxx
index 7755082236..0c8f53781a 100644
--- a/Source/cmCMakePathCommand.cxx
+++ b/Source/cmCMakePathCommand.cxx
@@ -18,6 +18,7 @@
#include "cmArgumentParserTypes.h"
#include "cmCMakePath.h"
#include "cmExecutionStatus.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmRange.h"
#include "cmStringAlgorithms.h"
@@ -626,12 +627,12 @@ bool HandleConvertCommand(std::vector<std::string> const& args,
return false;
}
- std::vector<std::string> paths;
+ cmList paths;
if (action == cmakePath) {
paths = cmSystemTools::SplitString(args[1], pathSep.front());
} else {
- cmExpandList(args[1], paths);
+ paths.assign(args[1]);
}
for (auto& path : paths) {
@@ -648,7 +649,7 @@ bool HandleConvertCommand(std::vector<std::string> const& args,
}
}
- auto value = cmJoin(paths, action == cmakePath ? ";"_s : pathSep);
+ auto value = action == cmakePath ? paths.to_string() : paths.join(pathSep);
status.GetMakefile().AddDefinition(args[3], value);
return true;
diff --git a/Source/cmCMakePresetsGraph.cxx b/Source/cmCMakePresetsGraph.cxx
index 13e8bad1f1..13eddbe24f 100644
--- a/Source/cmCMakePresetsGraph.cxx
+++ b/Source/cmCMakePresetsGraph.cxx
@@ -4,7 +4,6 @@
#include <algorithm>
#include <cassert>
-#include <cstdlib>
#include <functional>
#include <iostream>
#include <iterator>
@@ -49,6 +48,7 @@ template <typename T>
using PresetPair = cmCMakePresetsGraph::PresetPair<T>;
using ExpandMacroResult = cmCMakePresetsGraphInternal::ExpandMacroResult;
using MacroExpander = cmCMakePresetsGraphInternal::MacroExpander;
+using cmCMakePresetsGraphInternal::ExpandMacros;
void InheritString(std::string& child, const std::string& parent)
{
@@ -204,14 +204,6 @@ bool IsValidMacroNamespace(const std::string& str)
ExpandMacroResult VisitEnv(std::string& value, CycleStatus& status,
const std::vector<MacroExpander>& macroExpanders,
int version);
-ExpandMacroResult ExpandMacros(
- std::string& out, const std::vector<MacroExpander>& macroExpanders,
- int version);
-ExpandMacroResult ExpandMacro(std::string& out,
- const std::string& macroNamespace,
- const std::string& macroName,
- const std::vector<MacroExpander>& macroExpanders,
- int version);
bool ExpandMacros(const cmCMakePresetsGraph& graph,
const ConfigurePreset& preset,
@@ -448,9 +440,9 @@ bool ExpandMacros(cmCMakePresetsGraph& graph, const T& preset,
if (macroName.empty()) {
return ExpandMacroResult::Error;
}
- const char* value = std::getenv(macroName.c_str());
- if (value) {
- result += value;
+ if (cm::optional<std::string> value =
+ cmSystemTools::GetEnvVar(macroName)) {
+ result += *value;
}
return ExpandMacroResult::Ok;
}
@@ -515,8 +507,9 @@ ExpandMacroResult VisitEnv(std::string& value, CycleStatus& status,
status = CycleStatus::Verified;
return ExpandMacroResult::Ok;
}
+}
-ExpandMacroResult ExpandMacros(
+ExpandMacroResult cmCMakePresetsGraphInternal::ExpandMacros(
std::string& out, const std::vector<MacroExpander>& macroExpanders,
int version)
{
@@ -595,11 +588,10 @@ ExpandMacroResult ExpandMacros(
return ExpandMacroResult::Ok;
}
-ExpandMacroResult ExpandMacro(std::string& out,
- const std::string& macroNamespace,
- const std::string& macroName,
- const std::vector<MacroExpander>& macroExpanders,
- int version)
+ExpandMacroResult cmCMakePresetsGraphInternal::ExpandMacro(
+ std::string& out, const std::string& macroNamespace,
+ const std::string& macroName,
+ const std::vector<MacroExpander>& macroExpanders, int version)
{
for (auto const& macroExpander : macroExpanders) {
auto result = macroExpander(macroNamespace, macroName, out, version);
@@ -615,6 +607,7 @@ ExpandMacroResult ExpandMacro(std::string& out,
return ExpandMacroResult::Error;
}
+namespace {
template <typename T>
bool SetupWorkflowConfigurePreset(const T& preset,
const ConfigurePreset*& configurePreset,
diff --git a/Source/cmCMakePresetsGraphInternal.h b/Source/cmCMakePresetsGraphInternal.h
index db784c341a..f133efb124 100644
--- a/Source/cmCMakePresetsGraphInternal.h
+++ b/Source/cmCMakePresetsGraphInternal.h
@@ -28,6 +28,16 @@ enum class ExpandMacroResult
using MacroExpander = std::function<ExpandMacroResult(
const std::string&, const std::string&, std::string&, int version)>;
+
+ExpandMacroResult ExpandMacros(
+ std::string& out, const std::vector<MacroExpander>& macroExpanders,
+ int version);
+
+ExpandMacroResult ExpandMacro(std::string& out,
+ const std::string& macroNamespace,
+ const std::string& macroName,
+ const std::vector<MacroExpander>& macroExpanders,
+ int version);
}
class cmCMakePresetsGraph::Condition
diff --git a/Source/cmCMakePresetsGraphReadJSON.cxx b/Source/cmCMakePresetsGraphReadJSON.cxx
index bc829f3e44..54fea409c4 100644
--- a/Source/cmCMakePresetsGraphReadJSON.cxx
+++ b/Source/cmCMakePresetsGraphReadJSON.cxx
@@ -33,6 +33,9 @@ using PackagePreset = cmCMakePresetsGraph::PackagePreset;
using WorkflowPreset = cmCMakePresetsGraph::WorkflowPreset;
using ArchToolsetStrategy = cmCMakePresetsGraph::ArchToolsetStrategy;
using JSONHelperBuilder = cmJSONHelperBuilder;
+using ExpandMacroResult = cmCMakePresetsGraphInternal::ExpandMacroResult;
+using MacroExpander = cmCMakePresetsGraphInternal::MacroExpander;
+using cmCMakePresetsGraphInternal::ExpandMacros;
constexpr int MIN_VERSION = 1;
constexpr int MAX_VERSION = 7;
@@ -688,7 +691,39 @@ bool cmCMakePresetsGraph::ReadJSONFile(const std::string& filename,
return true;
};
- for (auto include : presets.Include) {
+ std::vector<MacroExpander> macroExpanders;
+
+ MacroExpander environmentMacroExpander =
+ [](const std::string& macroNamespace, const std::string& macroName,
+ std::string& expanded, int /*version*/) -> ExpandMacroResult {
+ if (macroNamespace == "penv") {
+ if (macroName.empty()) {
+ return ExpandMacroResult::Error;
+ }
+ if (cm::optional<std::string> value =
+ cmSystemTools::GetEnvVar(macroName)) {
+ expanded += *value;
+ }
+ return ExpandMacroResult::Ok;
+ }
+
+ return ExpandMacroResult::Ignore;
+ };
+
+ macroExpanders.push_back(environmentMacroExpander);
+
+ for (Json::ArrayIndex i = 0; i < presets.Include.size(); ++i) {
+ auto include = presets.Include[i];
+
+ // Support for macro expansion in includes added in version 7
+ if (v >= 7) {
+ if (ExpandMacros(include, macroExpanders, v) != ExpandMacroResult::Ok) {
+ cmCMakePresetErrors::INVALID_INCLUDE(&root["include"][i],
+ &this->parseState);
+ return false;
+ }
+ }
+
if (!cmSystemTools::FileIsFullPath(include)) {
auto directory = cmSystemTools::GetFilenamePath(filename);
include = cmStrCat(directory, '/', include);
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index c8eea38b75..a3110413f8 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -55,6 +55,7 @@
#include "cmGeneratedFileStream.h"
#include "cmGlobalGenerator.h"
#include "cmJSONState.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmProcessOutput.h"
#include "cmState.h"
@@ -1468,7 +1469,7 @@ void cmCTest::AddSiteProperties(cmXMLWriter& xml)
ch->GetCMake()->GetState()->GetGlobalProperty("SubProjectLabels");
if (labels) {
xml.StartElement("Labels");
- std::vector<std::string> args = cmExpandedList(*labels);
+ cmList args{ *labels };
for (std::string const& i : args) {
xml.Element("Label", i);
}
@@ -1500,7 +1501,7 @@ std::vector<std::string> cmCTest::GetLabelsForSubprojects()
{
std::string labelsForSubprojects =
this->GetCTestConfiguration("LabelsForSubprojects");
- std::vector<std::string> subprojects = cmExpandedList(labelsForSubprojects);
+ cmList subprojects{ labelsForSubprojects };
// sort the array
std::sort(subprojects.begin(), subprojects.end());
@@ -1508,7 +1509,7 @@ std::vector<std::string> cmCTest::GetLabelsForSubprojects()
auto new_end = std::unique(subprojects.begin(), subprojects.end());
subprojects.erase(new_end, subprojects.end());
- return subprojects;
+ return std::move(subprojects.data());
}
void cmCTest::EndXML(cmXMLWriter& xml)
@@ -3098,8 +3099,7 @@ void cmCTest::PopulateCustomVector(cmMakefile* mf, const std::string& def,
}
cmCTestLog(this, DEBUG, "PopulateCustomVector: " << def << std::endl);
- vec.clear();
- cmExpandList(*dval, vec);
+ cmList::assign(vec, *dval);
for (std::string const& it : vec) {
cmCTestLog(this, DEBUG, " -- " << it << std::endl);
diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx
index b9d1f66d2a..d95dcc44ce 100644
--- a/Source/cmCacheManager.cxx
+++ b/Source/cmCacheManager.cxx
@@ -12,6 +12,7 @@
#include "cmsys/Glob.hxx"
#include "cmGeneratedFileStream.h"
+#include "cmList.h"
#include "cmMessageType.h"
#include "cmMessenger.h"
#include "cmState.h"
@@ -531,15 +532,11 @@ void cmCacheManager::AddCacheEntry(const std::string& key, cmValue value,
// make sure we only use unix style paths
if (type == cmStateEnums::FILEPATH || type == cmStateEnums::PATH) {
if (e.Value.find(';') != std::string::npos) {
- std::vector<std::string> paths = cmExpandedList(e.Value);
- const char* sep = "";
- e.Value = "";
+ cmList paths{ e.Value };
for (std::string& i : paths) {
cmSystemTools::ConvertToUnixSlashes(i);
- e.Value += sep;
- e.Value += i;
- sep = ";";
}
+ e.Value = paths.to_string();
} else {
cmSystemTools::ConvertToUnixSlashes(e.Value);
}
diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx
index f6fdd48969..1cb62b39d8 100644
--- a/Source/cmCommonTargetGenerator.cxx
+++ b/Source/cmCommonTargetGenerator.cxx
@@ -15,6 +15,7 @@
#include "cmGeneratorTarget.h"
#include "cmGlobalCommonGenerator.h"
#include "cmGlobalGenerator.h"
+#include "cmList.h"
#include "cmLocalCommonGenerator.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
@@ -303,8 +304,7 @@ std::string cmCommonTargetGenerator::GetLinkerLauncher(
*launcherProp, this->LocalCommonGenerator, config, this->GeneratorTarget,
&dagChecker, this->GeneratorTarget, lang);
// Convert ;-delimited list to single string
- std::vector<std::string> args =
- cmExpandedList(evaluatedLinklauncher, true);
+ cmList args{ evaluatedLinklauncher, cmList::EmptyElements::Yes };
if (!args.empty()) {
args[0] = this->LocalCommonGenerator->ConvertToOutputFormat(
args[0], cmOutputConverter::SHELL);
diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index 5f408d0c65..f51a1c895c 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -20,6 +20,7 @@
#include "cmGeneratorExpressionDAGChecker.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
@@ -627,7 +628,7 @@ void cmComputeLinkDepends::AddVarLinkEntries(size_t depender_index,
// This is called to add the dependencies named by
// <item>_LIB_DEPENDS. The variable contains a semicolon-separated
// list. The list contains link-type;item pairs and just items.
- std::vector<std::string> deplist = cmExpandedList(value);
+ cmList deplist{ value };
// Look for entries meant for this configuration.
std::vector<cmLinkItem> actual_libs;
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index a93477b924..5d44a6ae70 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -15,6 +15,7 @@
#include "cmComputeLinkDepends.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
@@ -858,8 +859,8 @@ bool cmComputeLinkInformation::AddLibraryFeature(std::string const& feature)
return false;
}
- auto items = cmExpandListWithBacktrace(*langFeature,
- this->Target->GetBacktrace(), true);
+ auto items = cmExpandListWithBacktrace(
+ *langFeature, this->Target->GetBacktrace(), cmList::EmptyElements::Yes);
if ((items.size() == 1 && !IsValidFeatureFormat(items.front().Value)) ||
(items.size() == 3 && !IsValidFeatureFormat(items[1].Value))) {
@@ -1016,8 +1017,8 @@ cmComputeLinkInformation::GetGroupFeature(std::string const& feature)
.first->second;
}
- auto items = cmExpandListWithBacktrace(*langFeature,
- this->Target->GetBacktrace(), true);
+ auto items = cmExpandListWithBacktrace(
+ *langFeature, this->Target->GetBacktrace(), cmList::EmptyElements::Yes);
// replace LINKER: pattern
this->Target->ResolveLinkerWrapper(items, this->LinkLanguage, true);
@@ -1072,8 +1073,8 @@ void cmComputeLinkInformation::AddRuntimeLinkLibrary(std::string const& lang)
}
if (cmValue runtimeLinkOptions = this->Makefile->GetDefinition(cmStrCat(
"CMAKE_", lang, "_RUNTIME_LIBRARY_LINK_OPTIONS_", runtimeLibrary))) {
- std::vector<std::string> libsVec = cmExpandedList(*runtimeLinkOptions);
- for (std::string const& i : libsVec) {
+ cmList libs{ *runtimeLinkOptions };
+ for (auto const& i : libs) {
if (!cm::contains(this->ImplicitLinkLibs, i)) {
this->AddItem({ i });
}
@@ -1087,8 +1088,8 @@ void cmComputeLinkInformation::AddImplicitLinkInfo(std::string const& lang)
// linker language.
std::string libVar = cmStrCat("CMAKE_", lang, "_IMPLICIT_LINK_LIBRARIES");
if (cmValue libs = this->Makefile->GetDefinition(libVar)) {
- std::vector<std::string> libsVec = cmExpandedList(*libs);
- for (std::string const& i : libsVec) {
+ cmList libsList{ *libs };
+ for (auto const& i : libsList) {
if (!cm::contains(this->ImplicitLinkLibs, i)) {
this->AddItem({ i });
}
@@ -1099,8 +1100,8 @@ void cmComputeLinkInformation::AddImplicitLinkInfo(std::string const& lang)
// implied by the linker language.
std::string dirVar = cmStrCat("CMAKE_", lang, "_IMPLICIT_LINK_DIRECTORIES");
if (cmValue dirs = this->Makefile->GetDefinition(dirVar)) {
- std::vector<std::string> dirsVec = cmExpandedList(*dirs);
- this->OrderLinkerSearchPath->AddLanguageDirectories(dirsVec);
+ cmList dirsList{ *dirs };
+ this->OrderLinkerSearchPath->AddLanguageDirectories(dirsList);
}
}
@@ -1370,15 +1371,15 @@ void cmComputeLinkInformation::ComputeItemParserInfo()
LinkUnknown);
if (cmValue linkSuffixes =
mf->GetDefinition("CMAKE_EXTRA_LINK_EXTENSIONS")) {
- std::vector<std::string> linkSuffixVec = cmExpandedList(*linkSuffixes);
- for (std::string const& i : linkSuffixVec) {
+ cmList linkSuffixList{ *linkSuffixes };
+ for (auto const& i : linkSuffixList) {
this->AddLinkExtension(i, LinkUnknown);
}
}
if (cmValue sharedSuffixes =
mf->GetDefinition("CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES")) {
- std::vector<std::string> sharedSuffixVec = cmExpandedList(*sharedSuffixes);
- for (std::string const& i : sharedSuffixVec) {
+ cmList sharedSuffixList{ *sharedSuffixes };
+ for (std::string const& i : sharedSuffixList) {
this->AddLinkExtension(i, LinkShared);
}
}
@@ -1916,19 +1917,18 @@ void cmComputeLinkInformation::DropDirectoryItem(BT<std::string> const& item)
void cmComputeLinkInformation::ComputeFrameworkInfo()
{
// Avoid adding implicit framework paths.
- std::vector<std::string> implicitDirVec;
+ cmList implicitDirs;
// Get platform-wide implicit directories.
- this->Makefile->GetDefExpandList(
- "CMAKE_PLATFORM_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES", implicitDirVec);
+ implicitDirs.assign(this->Makefile->GetDefinition(
+ "CMAKE_PLATFORM_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES"));
// Get language-specific implicit directories.
std::string implicitDirVar = cmStrCat(
"CMAKE_", this->LinkLanguage, "_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES");
- this->Makefile->GetDefExpandList(implicitDirVar, implicitDirVec);
+ implicitDirs.append(this->Makefile->GetDefinition(implicitDirVar));
- this->FrameworkPathsEmitted.insert(implicitDirVec.begin(),
- implicitDirVec.end());
+ this->FrameworkPathsEmitted.insert(implicitDirs.begin(), implicitDirs.end());
}
void cmComputeLinkInformation::AddFrameworkPath(std::string const& p)
@@ -2138,17 +2138,15 @@ void cmComputeLinkInformation::PrintLinkPolicyDiagnosis(std::ostream& os)
void cmComputeLinkInformation::LoadImplicitLinkInfo()
{
- std::vector<std::string> implicitDirVec;
-
// Get platform-wide implicit directories.
- this->Makefile->GetDefExpandList("CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES",
- implicitDirVec);
+ cmList implicitDirs{ this->Makefile->GetDefinition(
+ "CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES") };
// Append library architecture to all implicit platform directories
// and add them to the set
if (cmValue libraryArch =
this->Makefile->GetDefinition("CMAKE_LIBRARY_ARCHITECTURE")) {
- for (std::string const& i : implicitDirVec) {
+ for (auto const& i : implicitDirs) {
this->ImplicitLinkDirs.insert(cmStrCat(i, '/', *libraryArch));
}
}
@@ -2156,19 +2154,18 @@ void cmComputeLinkInformation::LoadImplicitLinkInfo()
// Get language-specific implicit directories.
std::string implicitDirVar =
cmStrCat("CMAKE_", this->LinkLanguage, "_IMPLICIT_LINK_DIRECTORIES");
- this->Makefile->GetDefExpandList(implicitDirVar, implicitDirVec);
+ implicitDirs.append(this->Makefile->GetDefinition(implicitDirVar));
// Store implicit link directories.
- this->ImplicitLinkDirs.insert(implicitDirVec.begin(), implicitDirVec.end());
+ this->ImplicitLinkDirs.insert(implicitDirs.begin(), implicitDirs.end());
// Get language-specific implicit libraries.
- std::vector<std::string> implicitLibVec;
std::string implicitLibVar =
cmStrCat("CMAKE_", this->LinkLanguage, "_IMPLICIT_LINK_LIBRARIES");
- this->Makefile->GetDefExpandList(implicitLibVar, implicitLibVec);
+ cmList implicitLibs{ this->Makefile->GetDefinition(implicitLibVar) };
// Store implicit link libraries.
- for (std::string const& item : implicitLibVec) {
+ for (auto const& item : implicitLibs) {
// Items starting in '-' but not '-l' are flags, not libraries,
// and should not be filtered by this implicit list.
if (item[0] != '-' || item[1] == 'l') {
@@ -2177,8 +2174,8 @@ void cmComputeLinkInformation::LoadImplicitLinkInfo()
}
// Get platform specific rpath link directories
- this->Makefile->GetDefExpandList("CMAKE_PLATFORM_RUNTIME_PATH",
- this->RuntimeLinkDirs);
+ cmList::append(this->RuntimeLinkDirs,
+ this->Makefile->GetDefinition("CMAKE_PLATFORM_RUNTIME_PATH"));
}
std::vector<std::string> const&
@@ -2279,7 +2276,7 @@ static void cmCLI_ExpandListUnique(std::string const& str,
std::vector<std::string>& out,
std::set<std::string>& emitted)
{
- std::vector<std::string> tmp = cmExpandedList(str);
+ cmList tmp{ str };
for (std::string const& i : tmp) {
if (emitted.insert(i).second) {
out.push_back(i);
diff --git a/Source/cmConditionEvaluator.cxx b/Source/cmConditionEvaluator.cxx
index 5de012a7fa..288e107d0a 100644
--- a/Source/cmConditionEvaluator.cxx
+++ b/Source/cmConditionEvaluator.cxx
@@ -18,6 +18,7 @@
#include "cmCMakePath.h"
#include "cmExpandedCommandArgument.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmState.h"
@@ -764,7 +765,9 @@ bool cmConditionEvaluator::HandleLevel2(cmArgumentList& newArgs,
cmValue rhs = this->Makefile.GetDefinition(args.nextnext->GetValue());
newArgs.ReduceTwoArgs(
- rhs && cm::contains(cmExpandedList(*rhs, true), *lhs), args);
+ rhs &&
+ cm::contains(cmList{ *rhs, cmList::EmptyElements::Yes }, *lhs),
+ args);
}
else if (this->Policy57Status == cmPolicies::WARN) {
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index 3149ccfa9c..7d4ab50967 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -20,6 +20,7 @@
#include "cmConfigureLog.h"
#include "cmExportTryCompileFileGenerator.h"
#include "cmGlobalGenerator.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmOutputConverter.h"
@@ -125,7 +126,7 @@ ArgumentParser::Continue TryCompileLangProp(Arguments& args,
ArgumentParser::Continue TryCompileCompileDefs(Arguments& args,
cm::string_view val)
{
- cmExpandList(val, args.CompileDefs);
+ args.CompileDefs.append(val);
return ArgumentParser::Continue::Yes;
}
@@ -788,7 +789,7 @@ cm::optional<cmTryCompileResult> cmCoreTryCompile::TryCompileCode(
if (!arguments.CompileDefs.empty()) {
// Pass using bracket arguments to preserve content.
fprintf(fout, "add_definitions([==[%s]==])\n",
- cmJoin(arguments.CompileDefs, "]==] [==[").c_str());
+ arguments.CompileDefs.join("]==] [==[").c_str());
}
if (!targets.empty()) {
@@ -1024,7 +1025,7 @@ cm::optional<cmTryCompileResult> cmCoreTryCompile::TryCompileCode(
if (cmValue varListStr = this->Makefile->GetDefinition(
kCMAKE_TRY_COMPILE_PLATFORM_VARIABLES)) {
- std::vector<std::string> varList = cmExpandedList(*varListStr);
+ cmList varList{ *varListStr };
vars.insert(varList.begin(), varList.end());
}
diff --git a/Source/cmCoreTryCompile.h b/Source/cmCoreTryCompile.h
index ba38c196b8..c185c68feb 100644
--- a/Source/cmCoreTryCompile.h
+++ b/Source/cmCoreTryCompile.h
@@ -12,6 +12,7 @@
#include "cmArgumentParser.h"
#include "cmArgumentParserTypes.h"
+#include "cmList.h"
#include "cmStateTypes.h"
class cmConfigureLog;
@@ -65,7 +66,7 @@ public:
ArgumentParser::MaybeEmpty<std::vector<std::string>> CMakeFlags{
1, "CMAKE_FLAGS"
}; // fake argv[0]
- std::vector<std::string> CompileDefs;
+ cmList CompileDefs;
cm::optional<ArgumentParser::MaybeEmpty<std::vector<std::string>>>
LinkLibraries;
ArgumentParser::MaybeEmpty<std::vector<std::string>> LinkOptions;
diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx
index 14c22e3a45..7623ccfd18 100644
--- a/Source/cmCustomCommandGenerator.cxx
+++ b/Source/cmCustomCommandGenerator.cxx
@@ -17,6 +17,7 @@
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
+#include "cmList.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmStateTypes.h"
@@ -116,7 +117,7 @@ std::vector<std::string> EvaluateDepends(std::vector<std::string> const& paths,
/*outputConfig=*/outputConfig,
/*commandConfig=*/commandConfig,
/*target=*/nullptr);
- cm::append(depends, cmExpandedList(ep));
+ cm::append(depends, cmList{ ep });
}
for (std::string& p : depends) {
if (cmSystemTools::FileIsFullPath(p)) {
@@ -196,7 +197,7 @@ cmCustomCommandGenerator::cmCustomCommandGenerator(
clarg, ge, this->LG, useOutputConfig, this->OutputConfig,
this->CommandConfig, target, &this->Utilities);
if (this->CC->GetCommandExpandLists()) {
- cm::append(argv, cmExpandedList(parsed_arg));
+ cm::append(argv, cmList{ parsed_arg });
} else {
argv.push_back(std::move(parsed_arg));
}
diff --git a/Source/cmDepends.cxx b/Source/cmDepends.cxx
index eca1abdaae..04bccce5e7 100644
--- a/Source/cmDepends.cxx
+++ b/Source/cmDepends.cxx
@@ -9,6 +9,7 @@
#include "cmFileTime.h"
#include "cmFileTimeCache.h"
#include "cmGeneratedFileStream.h"
+#include "cmList.h"
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
#include "cmStringAlgorithms.h"
@@ -28,11 +29,11 @@ bool cmDepends::Write(std::ostream& makeDepends, std::ostream& internalDepends)
std::map<std::string, std::set<std::string>> dependencies;
{
// Lookup the set of sources to scan.
- std::vector<std::string> pairs;
+ cmList pairs;
{
std::string const srcLang = "CMAKE_DEPENDS_CHECK_" + this->Language;
cmMakefile* mf = this->LocalGenerator->GetMakefile();
- cmExpandList(mf->GetSafeDefinition(srcLang), pairs);
+ pairs.assign(mf->GetSafeDefinition(srcLang));
}
for (auto si = pairs.begin(); si != pairs.end();) {
// Get the source and object file.
diff --git a/Source/cmDependsC.cxx b/Source/cmDependsC.cxx
index 25278090a4..408a85b325 100644
--- a/Source/cmDependsC.cxx
+++ b/Source/cmDependsC.cxx
@@ -8,6 +8,7 @@
#include "cmFileTime.h"
#include "cmGlobalUnixMakefileGenerator3.h"
+#include "cmList.h"
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
#include "cmStringAlgorithms.h"
@@ -393,10 +394,10 @@ void cmDependsC::Scan(std::istream& is, const std::string& directory,
void cmDependsC::SetupTransforms()
{
// Get the transformation rules.
- std::vector<std::string> transformRules;
cmMakefile* mf = this->LocalGenerator->GetMakefile();
- mf->GetDefExpandList("CMAKE_INCLUDE_TRANSFORMS", transformRules, true);
- for (std::string const& tr : transformRules) {
+ cmList transformRules{ mf->GetDefinition("CMAKE_INCLUDE_TRANSFORMS"),
+ cmList::EmptyElements::Yes };
+ for (auto const& tr : transformRules) {
this->ParseTransform(tr);
}
diff --git a/Source/cmDependsCompiler.cxx b/Source/cmDependsCompiler.cxx
index 0cc4946e48..c8061c36ee 100644
--- a/Source/cmDependsCompiler.cxx
+++ b/Source/cmDependsCompiler.cxx
@@ -128,7 +128,7 @@ bool cmDependsCompiler::CheckDependencies(
}
std::string line;
- if (!isValidPath) {
+ if (!isValidPath && !source.empty()) {
// insert source as first dependency
depends.push_back(source);
}
@@ -158,14 +158,16 @@ bool cmDependsCompiler::CheckDependencies(
}
// ensure source file is the first dependency
- if (depends.front() != source) {
- cm::erase(depends, source);
- if (!isValidPath) {
- depends.insert(depends.begin(), source);
+ if (!source.empty()) {
+ if (depends.front() != source) {
+ cm::erase(depends, source);
+ if (!isValidPath) {
+ depends.insert(depends.begin(), source);
+ }
+ } else if (isValidPath) {
+ // remove first dependency because it must not be filtered out
+ depends.erase(depends.begin());
}
- } else if (isValidPath) {
- // remove first dependency because it must not be filtered out
- depends.erase(depends.begin());
}
} else {
// unknown format, ignore it
@@ -174,8 +176,10 @@ bool cmDependsCompiler::CheckDependencies(
if (isValidPath) {
cm::erase_if(depends, isValidPath);
- // insert source as first dependency
- depends.insert(depends.begin(), source);
+ if (!source.empty()) {
+ // insert source as first dependency
+ depends.insert(depends.begin(), source);
+ }
}
dependencies[target] = std::move(depends);
diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx
index 718097f0be..aede3fecff 100644
--- a/Source/cmDependsFortran.cxx
+++ b/Source/cmDependsFortran.cxx
@@ -13,6 +13,7 @@
#include "cmFortranParser.h" /* Interface to parser object. */
#include "cmGeneratedFileStream.h"
#include "cmGlobalUnixMakefileGenerator3.h"
+#include "cmList.h"
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
#include "cmOutputConverter.h"
@@ -78,9 +79,8 @@ cmDependsFortran::cmDependsFortran(cmLocalUnixMakefileGenerator3* lg)
this->SetIncludePathFromLanguage("Fortran");
// Get the list of definitions.
- std::vector<std::string> definitions;
cmMakefile* mf = this->LocalGenerator->GetMakefile();
- mf->GetDefExpandList("CMAKE_TARGET_DEFINITIONS_Fortran", definitions);
+ cmList definitions{ mf->GetDefinition("CMAKE_TARGET_DEFINITIONS_Fortran") };
// translate i.e. FOO=BAR to FOO and add it to the list of defined
// preprocessor symbols
@@ -244,9 +244,9 @@ bool cmDependsFortran::LocateModules()
// Load information about other targets.
cmMakefile* mf = this->LocalGenerator->GetMakefile();
- std::vector<std::string> infoFiles;
- mf->GetDefExpandList("CMAKE_Fortran_TARGET_LINKED_INFO_FILES", infoFiles);
- for (std::string const& i : infoFiles) {
+ cmList infoFiles{ mf->GetDefinition(
+ "CMAKE_Fortran_TARGET_LINKED_INFO_FILES") };
+ for (auto const& i : infoFiles) {
std::string targetDir = cmSystemTools::GetFilenamePath(i);
std::string fname = targetDir + "/fortran.internal";
cmsys::ifstream fin(fname.c_str());
diff --git a/Source/cmEvaluatedTargetProperty.cxx b/Source/cmEvaluatedTargetProperty.cxx
index 1173690318..b82c29b75c 100644
--- a/Source/cmEvaluatedTargetProperty.cxx
+++ b/Source/cmEvaluatedTargetProperty.cxx
@@ -8,7 +8,7 @@
#include "cmGeneratorExpressionContext.h"
#include "cmGeneratorTarget.h"
#include "cmLinkItem.h"
-#include "cmStringAlgorithms.h"
+#include "cmList.h"
struct cmGeneratorExpressionDAGChecker;
diff --git a/Source/cmExportBuildAndroidMKGenerator.cxx b/Source/cmExportBuildAndroidMKGenerator.cxx
index 5d0b208931..5e7008b957 100644
--- a/Source/cmExportBuildAndroidMKGenerator.cxx
+++ b/Source/cmExportBuildAndroidMKGenerator.cxx
@@ -10,6 +10,7 @@
#include "cmGeneratorTarget.h"
#include "cmLinkItem.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
@@ -148,7 +149,7 @@ void cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties(
}
} else if (property.first == "INTERFACE_INCLUDE_DIRECTORIES") {
std::string includes = property.second;
- std::vector<std::string> includeList = cmExpandedList(includes);
+ cmList includeList{ includes };
os << "LOCAL_EXPORT_C_INCLUDES := ";
std::string end;
for (std::string const& i : includeList) {
@@ -158,9 +159,8 @@ void cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties(
os << "\n";
} else if (property.first == "INTERFACE_LINK_OPTIONS") {
os << "LOCAL_EXPORT_LDFLAGS := ";
- std::vector<std::string> linkFlagsList =
- cmExpandedList(property.second);
- os << cmJoin(linkFlagsList, " ") << "\n";
+ cmList linkFlagsList{ property.second };
+ os << linkFlagsList.join(" ") << "\n";
} else {
os << "# " << property.first << " " << (property.second) << "\n";
}
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index e997158c3e..22276ae508 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -17,6 +17,7 @@
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
#include "cmLinkItem.h"
+#include "cmList.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -507,7 +508,7 @@ static void getPropertyContents(cmGeneratorTarget const* tgt,
if (!p) {
return;
}
- std::vector<std::string> content = cmExpandedList(*p);
+ cmList content{ *p };
ifaceProperties.insert(content.begin(), content.end());
}
@@ -1261,7 +1262,7 @@ bool cmExportFileGenerator::PopulateExportProperties(
const auto& targetProperties = gte->Target->GetProperties();
if (cmValue exportProperties =
targetProperties.GetPropertyValue("EXPORT_PROPERTIES")) {
- for (auto& prop : cmExpandedList(*exportProperties)) {
+ for (auto& prop : cmList{ *exportProperties }) {
/* Black list reserved properties */
if (cmHasLiteralPrefix(prop, "IMPORTED_") ||
cmHasLiteralPrefix(prop, "INTERFACE_")) {
@@ -1325,7 +1326,22 @@ void cmExportFileGenerator::GenerateTargetFileSets(cmGeneratorTarget* gte,
<< this->GetFileSetFiles(gte, fileSet, te) << "\n";
}
- os << " )\nendif()\n\n";
+ os << " )\nelse()\n set_property(TARGET " << targetName
+ << "\n APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES";
+ for (auto const& name : interfaceFileSets) {
+ auto* fileSet = gte->Target->GetFileSet(name);
+ if (!fileSet) {
+ gte->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("File set \"", name,
+ "\" is listed in interface file sets of ", gte->GetName(),
+ " but has not been created"));
+ return;
+ }
+
+ os << "\n " << this->GetFileSetDirectories(gte, fileSet, te);
+ }
+ os << "\n )\nendif()\n\n";
}
}
diff --git a/Source/cmExportTryCompileFileGenerator.cxx b/Source/cmExportTryCompileFileGenerator.cxx
index c6ebad5c2d..f30c3c3ba4 100644
--- a/Source/cmExportTryCompileFileGenerator.cxx
+++ b/Source/cmExportTryCompileFileGenerator.cxx
@@ -12,6 +12,7 @@
#include "cmGeneratorExpressionDAGChecker.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
@@ -126,7 +127,7 @@ void cmExportTryCompileFileGenerator::PopulateProperties(
std::string evalResult =
this->FindTargets(p, target, std::string(), emitted);
- std::vector<std::string> depends = cmExpandedList(evalResult);
+ cmList depends{ evalResult };
for (std::string const& li : depends) {
cmGeneratorTarget* tgt =
target->GetLocalGenerator()->FindGeneratorTargetToUse(li);
diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx
index e9e2921316..8d7f33e7ef 100644
--- a/Source/cmExtraCodeBlocksGenerator.cxx
+++ b/Source/cmExtraCodeBlocksGenerator.cxx
@@ -14,6 +14,7 @@
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
+#include "cmList.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmRange.h"
@@ -567,13 +568,13 @@ void cmExtraCodeBlocksGenerator::AppendTarget(
std::string systemIncludeDirs = makefile->GetSafeDefinition(
"CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_INCLUDE_DIRS");
if (!systemIncludeDirs.empty()) {
- cm::append(allIncludeDirs, cmExpandedList(systemIncludeDirs));
+ cm::append(allIncludeDirs, cmList{ systemIncludeDirs });
}
systemIncludeDirs = makefile->GetSafeDefinition(
"CMAKE_EXTRA_GENERATOR_C_SYSTEM_INCLUDE_DIRS");
if (!systemIncludeDirs.empty()) {
- cm::append(allIncludeDirs, cmExpandedList(systemIncludeDirs));
+ cm::append(allIncludeDirs, cmList{ systemIncludeDirs });
}
auto end = cmRemoveDuplicates(allIncludeDirs);
diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx
index 6201889f22..c7ce5b0676 100644
--- a/Source/cmExtraEclipseCDT4Generator.cxx
+++ b/Source/cmExtraEclipseCDT4Generator.cxx
@@ -16,6 +16,7 @@
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
+#include "cmList.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -418,7 +419,7 @@ void cmExtraEclipseCDT4Generator::CreateProjectFile()
if (cmValue extraNaturesProp =
mf->GetState()->GetGlobalProperty("ECLIPSE_EXTRA_NATURES")) {
- std::vector<std::string> extraNatures = cmExpandedList(*extraNaturesProp);
+ cmList extraNatures{ *extraNaturesProp };
for (std::string const& n : extraNatures) {
xml.Element("nature", n);
}
@@ -798,7 +799,7 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
mf->GetDefinition("CMAKE_EXTRA_GENERATOR_C_SYSTEM_DEFINED_MACROS");
if (this->CEnabled && cDefs) {
// Expand the list.
- std::vector<std::string> defs = cmExpandedList(*cDefs, true);
+ cmList defs{ *cDefs, cmList::EmptyElements::Yes };
// the list must contain only definition-value pairs:
if ((defs.size() % 2) == 0) {
@@ -830,7 +831,7 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
mf->GetDefinition("CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_DEFINED_MACROS");
if (this->CXXEnabled && cxxDefs) {
// Expand the list.
- std::vector<std::string> defs = cmExpandedList(*cxxDefs, true);
+ cmList defs{ *cxxDefs, cmList::EmptyElements::Yes };
// the list must contain only definition-value pairs:
if ((defs.size() % 2) == 0) {
@@ -879,14 +880,14 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
if (this->CEnabled && !compiler.empty()) {
std::string systemIncludeDirs =
mf->GetSafeDefinition("CMAKE_EXTRA_GENERATOR_C_SYSTEM_INCLUDE_DIRS");
- std::vector<std::string> dirs = cmExpandedList(systemIncludeDirs);
+ cmList dirs{ systemIncludeDirs };
this->AppendIncludeDirectories(xml, dirs, emitted);
}
compiler = mf->GetSafeDefinition("CMAKE_CXX_COMPILER");
if (this->CXXEnabled && !compiler.empty()) {
std::string systemIncludeDirs =
mf->GetSafeDefinition("CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_INCLUDE_DIRS");
- std::vector<std::string> dirs = cmExpandedList(systemIncludeDirs);
+ cmList dirs{ systemIncludeDirs };
this->AppendIncludeDirectories(xml, dirs, emitted);
}
diff --git a/Source/cmExtraSublimeTextGenerator.cxx b/Source/cmExtraSublimeTextGenerator.cxx
index 33901ac594..205a691f21 100644
--- a/Source/cmExtraSublimeTextGenerator.cxx
+++ b/Source/cmExtraSublimeTextGenerator.cxx
@@ -14,6 +14,7 @@
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
+#include "cmList.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -138,7 +139,7 @@ void cmExtraSublimeTextGenerator::CreateNewProjectFile(
// End of build_systems
fout << "\n\t]";
std::string systemName = mf->GetSafeDefinition("CMAKE_SYSTEM_NAME");
- std::vector<std::string> tokens = cmExpandedList(this->EnvSettings);
+ cmList tokens{ this->EnvSettings };
if (!this->EnvSettings.empty()) {
fout << ",";
diff --git a/Source/cmFileAPIToolchains.cxx b/Source/cmFileAPIToolchains.cxx
index fe2972fabf..a51ae2048e 100644
--- a/Source/cmFileAPIToolchains.cxx
+++ b/Source/cmFileAPIToolchains.cxx
@@ -10,6 +10,7 @@
#include "cmFileAPI.h"
#include "cmGlobalGenerator.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmState.h"
#include "cmStringAlgorithms.h"
@@ -124,10 +125,11 @@ void Toolchains::DumpToolchainVariable(cmMakefile const* mf,
cmStrCat("CMAKE_", lang, "_", variable.VariableSuffix);
if (variable.IsList) {
- std::vector<std::string> values;
- if (mf->GetDefExpandList(variableName, values)) {
+ cmValue data = mf->GetDefinition(variableName);
+ if (data) {
+ cmList values(data);
Json::Value jsonArray = Json::arrayValue;
- for (std::string const& value : values) {
+ for (auto const& value : values) {
jsonArray.append(value);
}
object[variable.ObjectKey] = jsonArray;
diff --git a/Source/cmFileCopier.cxx b/Source/cmFileCopier.cxx
index ef55abfd14..663bddcece 100644
--- a/Source/cmFileCopier.cxx
+++ b/Source/cmFileCopier.cxx
@@ -9,6 +9,7 @@
#include "cmExecutionStatus.h"
#include "cmFSPermissions.h"
#include "cmFileTimes.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -169,8 +170,7 @@ bool cmFileCopier::GetDefaultDirectoryPermissions(mode_t** mode)
cmValue default_dir_install_permissions = this->Makefile->GetDefinition(
"CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS");
if (cmNonempty(default_dir_install_permissions)) {
- std::vector<std::string> items =
- cmExpandedList(*default_dir_install_permissions);
+ cmList items{ *default_dir_install_permissions };
for (const auto& arg : items) {
if (!this->CheckPermissions(arg, **mode)) {
this->Status.SetError(
diff --git a/Source/cmFileSet.cxx b/Source/cmFileSet.cxx
index b96ba6e886..48a2570d56 100644
--- a/Source/cmFileSet.cxx
+++ b/Source/cmFileSet.cxx
@@ -12,6 +12,7 @@
#include "cmsys/RegularExpression.hxx"
#include "cmGeneratorExpression.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
@@ -113,7 +114,7 @@ cmFileSet::CompileFileEntries() const
std::vector<std::unique_ptr<cmCompiledGeneratorExpression>> result;
for (auto const& entry : this->FileEntries) {
- for (auto const& ex : cmExpandedList(entry.Value)) {
+ for (auto const& ex : cmList{ entry.Value }) {
cmGeneratorExpression ge(this->CMakeInstance, entry.Backtrace);
auto cge = ge.Parse(ex);
result.push_back(std::move(cge));
@@ -129,7 +130,7 @@ cmFileSet::CompileDirectoryEntries() const
std::vector<std::unique_ptr<cmCompiledGeneratorExpression>> result;
for (auto const& entry : this->DirectoryEntries) {
- for (auto const& ex : cmExpandedList(entry.Value)) {
+ for (auto const& ex : cmList{ entry.Value }) {
cmGeneratorExpression ge(this->CMakeInstance, entry.Backtrace);
auto cge = ge.Parse(ex);
result.push_back(std::move(cge));
@@ -148,7 +149,7 @@ std::vector<std::string> cmFileSet::EvaluateDirectoryEntries(
std::vector<std::string> result;
for (auto const& cge : cges) {
auto entry = cge->Evaluate(lg, config, target, dagChecker);
- auto dirs = cmExpandedList(entry);
+ cmList dirs{ entry };
for (std::string dir : dirs) {
if (!cmSystemTools::FileIsFullPath(dir)) {
dir = cmStrCat(lg->GetCurrentSourceDirectory(), '/', dir);
@@ -184,7 +185,7 @@ void cmFileSet::EvaluateFileEntry(
cmGeneratorExpressionDAGChecker* dagChecker) const
{
auto files = cge->Evaluate(lg, config, target, dagChecker);
- for (std::string file : cmExpandedList(files)) {
+ for (std::string file : cmList{ files }) {
if (!cmSystemTools::FileIsFullPath(file)) {
file = cmStrCat(lg->GetCurrentSourceDirectory(), '/', file);
}
diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx
index 4df81d5773..929c6c1c82 100644
--- a/Source/cmFindBase.cxx
+++ b/Source/cmFindBase.cxx
@@ -15,6 +15,7 @@
#include "cmCMakePath.h"
#include "cmExecutionStatus.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -154,7 +155,7 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn)
}
// ensure a macro is not specified as validator
const auto& validatorName = args[j];
- auto macros = cmExpandedList(this->Makefile->GetProperty("MACROS"));
+ cmList macros{ this->Makefile->GetProperty("MACROS") };
if (std::find_if(macros.begin(), macros.end(),
[&validatorName](const std::string& item) {
return cmSystemTools::Strucmp(validatorName.c_str(),
@@ -403,7 +404,7 @@ void cmFindBase::FillCMakeSystemVariablePath()
this->Makefile->GetDefinition("CMAKE_SYSTEM_PREFIX_PATH");
// remove entries from CMAKE_SYSTEM_PREFIX_PATH
- std::vector<std::string> expanded = cmExpandedList(*prefix_paths);
+ cmList expanded{ *prefix_paths };
install_entry.remove_self(expanded);
staging_entry.remove_self(expanded);
diff --git a/Source/cmFindCommon.cxx b/Source/cmFindCommon.cxx
index c3fb9077da..bec6369211 100644
--- a/Source/cmFindCommon.cxx
+++ b/Source/cmFindCommon.cxx
@@ -9,6 +9,7 @@
#include <cmext/algorithm>
#include "cmExecutionStatus.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
@@ -238,9 +239,9 @@ void cmFindCommon::RerootPaths(std::vector<std::string>& paths)
}
// Construct the list of path roots with no trailing slashes.
- std::vector<std::string> roots;
+ cmList roots;
if (rootPath) {
- cmExpandList(*rootPath, roots);
+ roots.assign(*rootPath);
}
if (sysrootCompile) {
roots.emplace_back(*sysrootCompile);
@@ -251,14 +252,14 @@ void cmFindCommon::RerootPaths(std::vector<std::string>& paths)
if (sysroot) {
roots.emplace_back(*sysroot);
}
- for (std::string& r : roots) {
+ for (auto& r : roots) {
cmSystemTools::ConvertToUnixSlashes(r);
}
cmValue stagePrefix = this->Makefile->GetDefinition("CMAKE_STAGING_PREFIX");
// Copy the original set of unrooted paths.
- std::vector<std::string> unrootedPaths = paths;
+ auto unrootedPaths = paths;
paths.clear();
auto isSameDirectoryOrSubDirectory = [](std::string const& l,
@@ -267,8 +268,8 @@ void cmFindCommon::RerootPaths(std::vector<std::string>& paths)
cmSystemTools::IsSubDirectory(l, r);
};
- for (std::string const& r : roots) {
- for (std::string const& up : unrootedPaths) {
+ for (auto const& r : roots) {
+ for (auto const& up : unrootedPaths) {
// Place the unrooted path under the current root if it is not
// already inside. Skip the unrooted path if it is relative to
// a user home directory or is empty.
@@ -308,7 +309,7 @@ void cmFindCommon::GetIgnoredPaths(std::vector<std::string>& ignore)
// Construct the list of path roots with no trailing slashes.
for (const char* pathName : paths) {
// Get the list of paths to ignore from the variable.
- this->Makefile->GetDefExpandList(pathName, ignore);
+ cmList::append(ignore, this->Makefile->GetDefinition(pathName));
}
for (std::string& i : ignore) {
@@ -333,7 +334,7 @@ void cmFindCommon::GetIgnoredPrefixPaths(std::vector<std::string>& ignore)
// Construct the list of path roots with no trailing slashes.
for (const char* pathName : paths) {
// Get the list of paths to ignore from the variable.
- this->Makefile->GetDefExpandList(pathName, ignore);
+ cmList::append(ignore, this->Makefile->GetDefinition(pathName));
}
for (std::string& i : ignore) {
diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx
index 6296a60aeb..9eb060357a 100644
--- a/Source/cmFindLibraryCommand.cxx
+++ b/Source/cmFindLibraryCommand.cxx
@@ -11,6 +11,7 @@
#include "cmsys/RegularExpression.hxx"
#include "cmGlobalGenerator.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmState.h"
#include "cmStateTypes.h"
@@ -196,8 +197,8 @@ struct cmFindLibraryHelper
cmGlobalGenerator* GG;
// List of valid prefixes and suffixes.
- std::vector<std::string> Prefixes;
- std::vector<std::string> Suffixes;
+ cmList Prefixes;
+ cmList Suffixes;
std::string PrefixRegexStr;
std::string SuffixRegexStr;
@@ -223,7 +224,7 @@ struct cmFindLibraryHelper
std::string TestPath;
void RegexFromLiteral(std::string& out, std::string const& in);
- void RegexFromList(std::string& out, std::vector<std::string> const& in);
+ void RegexFromList(std::string& out, cmList const& in);
size_type GetPrefixIndex(std::string const& prefix)
{
return std::find(this->Prefixes.begin(), this->Prefixes.end(), prefix) -
@@ -307,8 +308,8 @@ cmFindLibraryHelper::cmFindLibraryHelper(std::string debugName, cmMakefile* mf,
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->Prefixes.assign(prefixes_list, cmList::EmptyElements::Yes);
+ this->Suffixes.assign(suffixes_list, cmList::EmptyElements::Yes);
this->RegexFromList(this->PrefixRegexStr, this->Prefixes);
this->RegexFromList(this->SuffixRegexStr, this->Suffixes);
@@ -334,14 +335,13 @@ void cmFindLibraryHelper::RegexFromLiteral(std::string& out,
}
}
-void cmFindLibraryHelper::RegexFromList(std::string& out,
- std::vector<std::string> const& in)
+void cmFindLibraryHelper::RegexFromList(std::string& out, cmList const& in)
{
// Surround the list in parens so the '|' does not apply to anything
// else and the result can be checked after matching.
out += "(";
const char* sep = "";
- for (std::string const& s : in) {
+ for (auto const& s : in) {
// Separate from previous item.
out += sep;
sep = "|";
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index b1029e62c8..98b085cdc0 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -23,6 +23,7 @@
#include "cmAlgorithms.h"
#include "cmDependencyProvider.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -1781,28 +1782,20 @@ bool cmFindPackageCommand::ReadListFile(const std::string& f,
void cmFindPackageCommand::AppendToFoundProperty(const bool found)
{
- std::vector<std::string> foundContents;
+ cmList foundContents;
cmValue foundProp =
this->Makefile->GetState()->GetGlobalProperty("PACKAGES_FOUND");
- if (cmNonempty(foundProp)) {
- cmExpandList(*foundProp, foundContents, false);
- auto nameIt =
- std::find(foundContents.begin(), foundContents.end(), this->Name);
- if (nameIt != foundContents.end()) {
- foundContents.erase(nameIt);
- }
+ if (!foundProp.IsEmpty()) {
+ foundContents.assign(*foundProp);
+ foundContents.remove_items({ this->Name });
}
- std::vector<std::string> notFoundContents;
+ cmList notFoundContents;
cmValue notFoundProp =
this->Makefile->GetState()->GetGlobalProperty("PACKAGES_NOT_FOUND");
- if (cmNonempty(notFoundProp)) {
- cmExpandList(*notFoundProp, notFoundContents, false);
- auto nameIt =
- std::find(notFoundContents.begin(), notFoundContents.end(), this->Name);
- if (nameIt != notFoundContents.end()) {
- notFoundContents.erase(nameIt);
- }
+ if (!notFoundProp.IsEmpty()) {
+ notFoundContents.assign(*notFoundProp);
+ notFoundContents.remove_items({ this->Name });
}
if (found) {
@@ -1811,12 +1804,11 @@ void cmFindPackageCommand::AppendToFoundProperty(const bool found)
notFoundContents.push_back(this->Name);
}
- std::string tmp = cmJoin(foundContents, ";");
- this->Makefile->GetState()->SetGlobalProperty("PACKAGES_FOUND", tmp.c_str());
+ this->Makefile->GetState()->SetGlobalProperty(
+ "PACKAGES_FOUND", foundContents.to_string().c_str());
- tmp = cmJoin(notFoundContents, ";");
- this->Makefile->GetState()->SetGlobalProperty("PACKAGES_NOT_FOUND",
- tmp.c_str());
+ this->Makefile->GetState()->SetGlobalProperty(
+ "PACKAGES_NOT_FOUND", notFoundContents.to_string().c_str());
}
void cmFindPackageCommand::AppendSuccessInformation()
@@ -2338,7 +2330,7 @@ void cmFindPackageCommand::FillPrefixesCMakeSystemVariable()
cmValue prefix_paths =
this->Makefile->GetDefinition("CMAKE_SYSTEM_PREFIX_PATH");
// remove entry from CMAKE_SYSTEM_PREFIX_PATH
- std::vector<std::string> expanded = cmExpandedList(*prefix_paths);
+ cmList expanded{ *prefix_paths };
long count = 0;
for (const auto& path : expanded) {
bool const to_add =
diff --git a/Source/cmForEachCommand.cxx b/Source/cmForEachCommand.cxx
index 3465c230f8..21a140d02c 100644
--- a/Source/cmForEachCommand.cxx
+++ b/Source/cmForEachCommand.cxx
@@ -23,6 +23,7 @@
#include "cmExecutionStatus.h"
#include "cmFunctionBlocker.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -156,16 +157,16 @@ bool cmForEachFunctionBlocker::ReplayZipLists(
auto& mf = inStatus.GetMakefile();
// Expand the list of list-variables into a list of lists of strings
- std::vector<std::vector<std::string>> values;
+ std::vector<cmList> values;
values.reserve(this->Args.size() - this->IterationVarsCount);
// Also track the longest list size
std::size_t maxItems = 0u;
for (auto const& var :
cmMakeRange(this->Args).advance(this->IterationVarsCount)) {
- std::vector<std::string> items;
+ cmList items;
auto const& value = mf.GetSafeDefinition(var);
if (!value.empty()) {
- cmExpandList(value, items, true);
+ items.assign(value, cmList::EmptyElements::Yes);
}
maxItems = std::max(maxItems, items.size());
values.emplace_back(std::move(items));
@@ -344,7 +345,7 @@ bool HandleInMode(std::vector<std::string> const& args,
} else if (doing == DoingLists) {
auto const& value = makefile.GetSafeDefinition(arg);
if (!value.empty()) {
- cmExpandList(value, fb->Args, true);
+ cmExpandList(value, fb->Args, cmList::EmptyElements::Yes);
}
} else if (doing == DoingItems || doing == DoingZipLists) {
diff --git a/Source/cmGccDepfileLexerHelper.cxx b/Source/cmGccDepfileLexerHelper.cxx
index 34c88248a0..87377de401 100644
--- a/Source/cmGccDepfileLexerHelper.cxx
+++ b/Source/cmGccDepfileLexerHelper.cxx
@@ -2,6 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGccDepfileLexerHelper.h"
+#include <algorithm>
#include <cstdio>
#include <memory>
#include <string>
@@ -113,6 +114,11 @@ void cmGccDepfileLexerHelper::addToCurrentPath(const char* s)
void cmGccDepfileLexerHelper::sanitizeContent()
{
for (auto it = this->Content.begin(); it != this->Content.end();) {
+ // remove duplicate path entries
+ std::sort(it->paths.begin(), it->paths.end());
+ auto last = std::unique(it->paths.begin(), it->paths.end());
+ it->paths.erase(last, it->paths.end());
+
// Remove empty paths and normalize windows paths
for (auto pit = it->paths.begin(); pit != it->paths.end();) {
if (pit->empty()) {
diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx
index c5ae31bd38..04decd239c 100644
--- a/Source/cmGeneratorExpression.cxx
+++ b/Source/cmGeneratorExpression.cxx
@@ -14,6 +14,7 @@
#include "cmGeneratorExpressionEvaluator.h"
#include "cmGeneratorExpressionLexer.h"
#include "cmGeneratorExpressionParser.h"
+#include "cmList.h"
#include "cmLocalGenerator.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index ca61f75ffa..bb4fc7e271 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -19,7 +19,6 @@
#include <cm/iterator>
#include <cm/optional>
#include <cm/string_view>
-#include <cm/vector>
#include <cmext/algorithm>
#include <cmext/string_view>
@@ -635,22 +634,48 @@ public:
using Arguments = Range<std::vector<std::string>>;
-bool CheckPathParametersEx(cmGeneratorExpressionContext* ctx,
- const GeneratorExpressionContent* cnt,
- cm::string_view option, std::size_t count,
- int required = 1, bool exactly = true)
+bool CheckGenExParameters(cmGeneratorExpressionContext* ctx,
+ const GeneratorExpressionContent* cnt,
+ cm::string_view genex, cm::string_view option,
+ std::size_t count, int required = 1,
+ bool exactly = true)
{
if (static_cast<int>(count) < required ||
(exactly && static_cast<int>(count) > required)) {
+ std::string nbParameters;
+ switch (required) {
+ case 1:
+ nbParameters = "one parameter";
+ break;
+ case 2:
+ nbParameters = "two parameters";
+ break;
+ case 3:
+ nbParameters = "three parameters";
+ break;
+ case 4:
+ nbParameters = "four parameters";
+ break;
+ default:
+ nbParameters = cmStrCat(std::to_string(required), " parameters");
+ }
reportError(ctx, cnt->GetOriginalExpression(),
- cmStrCat("$<PATH:", option, "> expression requires ",
- (exactly ? "exactly" : "at least"), ' ',
- (required == 1 ? "one parameter" : "two parameters"),
+ cmStrCat("$<", genex, ':', option, "> expression requires ",
+ (exactly ? "exactly" : "at least"), ' ', nbParameters,
'.'));
return false;
}
return true;
};
+
+bool CheckPathParametersEx(cmGeneratorExpressionContext* ctx,
+ const GeneratorExpressionContent* cnt,
+ cm::string_view option, std::size_t count,
+ int required = 1, bool exactly = true)
+{
+ return CheckGenExParameters(ctx, cnt, "PATH"_s, option, count, required,
+ exactly);
+}
bool CheckPathParameters(cmGeneratorExpressionContext* ctx,
const GeneratorExpressionContent* cnt,
cm::string_view option, const Arguments& args,
@@ -658,6 +683,7 @@ bool CheckPathParameters(cmGeneratorExpressionContext* ctx,
{
return CheckPathParametersEx(ctx, cnt, option, args.size(), required);
};
+
std::string ToString(bool isTrue)
{
return isTrue ? "1" : "0";
@@ -681,9 +707,9 @@ static const struct PathNode : public cmGeneratorExpressionNode
static auto processList =
[](std::string const& arg,
std::function<void(std::string&)> transform) -> std::string {
- auto list = cmExpandedList(arg);
+ cmList list{ arg };
std::for_each(list.begin(), list.end(), std::move(transform));
- return cmJoin(list, ";");
+ return list.to_string();
};
static std::unordered_map<
@@ -1108,6 +1134,675 @@ static const struct PathEqualNode : public cmGeneratorExpressionNode
}
} pathEqualNode;
+namespace {
+inline bool CheckListParametersEx(cmGeneratorExpressionContext* ctx,
+ const GeneratorExpressionContent* cnt,
+ cm::string_view option, std::size_t count,
+ int required = 1, bool exactly = true)
+{
+ return CheckGenExParameters(ctx, cnt, "LIST"_s, option, count, required,
+ exactly);
+}
+inline bool CheckListParameters(cmGeneratorExpressionContext* ctx,
+ const GeneratorExpressionContent* cnt,
+ cm::string_view option, const Arguments& args,
+ int required = 1)
+{
+ return CheckListParametersEx(ctx, cnt, option, args.size(), required);
+};
+
+inline cmList GetList(std::string const& list)
+{
+ return list.empty() ? cmList{} : cmList{ list, cmList::EmptyElements::Yes };
+}
+
+bool GetNumericArgument(const std::string& arg, cmList::index_type& value)
+{
+ try {
+ std::size_t pos;
+
+ if (sizeof(cmList::index_type) == sizeof(long)) {
+ value = std::stol(arg, &pos);
+ } else {
+ value = std::stoll(arg, &pos);
+ }
+
+ if (pos != arg.length()) {
+ // this is not a number
+ return false;
+ }
+ } catch (const std::invalid_argument&) {
+ return false;
+ }
+
+ return true;
+}
+
+bool GetNumericArguments(
+ cmGeneratorExpressionContext* ctx, const GeneratorExpressionContent* cnt,
+ Arguments const& args, std::vector<cmList::index_type>& indexes,
+ cmList::ExpandElements expandElements = cmList::ExpandElements::No)
+{
+ using IndexRange = cmRange<Arguments::const_iterator>;
+ IndexRange arguments(args.begin(), args.end());
+ cmList list;
+ if (expandElements == cmList::ExpandElements::Yes) {
+ list = cmList{ args.begin(), args.end(), expandElements };
+ arguments = IndexRange{ list.begin(), list.end() };
+ }
+
+ for (auto const& value : arguments) {
+ cmList::index_type index;
+ if (!GetNumericArgument(value, index)) {
+ reportError(ctx, cnt->GetOriginalExpression(),
+ cmStrCat("index: \"", value, "\" is not a valid index"));
+ return false;
+ }
+ indexes.push_back(index);
+ }
+ return true;
+}
+}
+
+static const struct ListNode : public cmGeneratorExpressionNode
+{
+ ListNode() {} // NOLINT(modernize-use-equals-default)
+
+ int NumExpectedParameters() const override { return TwoOrMoreParameters; }
+
+ bool AcceptsArbitraryContentParameter() const override { return true; }
+
+ std::string Evaluate(
+ const std::vector<std::string>& parameters,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content,
+ cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
+ {
+ static std::unordered_map<
+ cm::string_view,
+ std::function<std::string(cmGeneratorExpressionContext*,
+ const GeneratorExpressionContent*,
+ Arguments&)>>
+ listCommands{
+ { "LENGTH"_s,
+ [](cmGeneratorExpressionContext* ctx,
+ const GeneratorExpressionContent* cnt,
+ Arguments& args) -> std::string {
+ if (CheckListParameters(ctx, cnt, "LENGTH"_s, args)) {
+ return std::to_string(GetList(args.front()).size());
+ }
+ return std::string{};
+ } },
+ { "GET"_s,
+ [](cmGeneratorExpressionContext* ctx,
+ const GeneratorExpressionContent* cnt,
+ Arguments& args) -> std::string {
+ if (CheckListParametersEx(ctx, cnt, "GET"_s, args.size(), 2,
+ false)) {
+ auto list = GetList(args.front());
+ if (list.empty()) {
+ reportError(ctx, cnt->GetOriginalExpression(),
+ "given empty list");
+ return std::string{};
+ }
+
+ std::vector<cmList::index_type> indexes;
+ if (!GetNumericArguments(ctx, cnt, args.advance(1), indexes,
+ cmList::ExpandElements::Yes)) {
+ return std::string{};
+ }
+ try {
+ return list.get_items(indexes.begin(), indexes.end())
+ .to_string();
+ } catch (std::out_of_range& e) {
+ reportError(ctx, cnt->GetOriginalExpression(), e.what());
+ return std::string{};
+ }
+ }
+ return std::string{};
+ } },
+ { "JOIN"_s,
+ [](cmGeneratorExpressionContext* ctx,
+ const GeneratorExpressionContent* cnt,
+ Arguments& args) -> std::string {
+ if (CheckListParameters(ctx, cnt, "JOIN"_s, args, 2)) {
+ return GetList(args.front()).join(args[1]);
+ }
+ return std::string{};
+ } },
+ { "SUBLIST"_s,
+ [](cmGeneratorExpressionContext* ctx,
+ const GeneratorExpressionContent* cnt,
+ Arguments& args) -> std::string {
+ if (CheckListParameters(ctx, cnt, "SUBLIST"_s, args, 3)) {
+ auto list = GetList(args.front());
+ if (!list.empty()) {
+ std::vector<cmList::index_type> indexes;
+ if (!GetNumericArguments(ctx, cnt, args.advance(1), indexes)) {
+ return std::string{};
+ }
+ if (indexes[0] < 0) {
+ reportError(ctx, cnt->GetOriginalExpression(),
+ cmStrCat("begin index: ", indexes[0],
+ " is out of range 0 - ",
+ list.size() - 1));
+ return std::string{};
+ }
+ if (indexes[1] < -1) {
+ reportError(ctx, cnt->GetOriginalExpression(),
+ cmStrCat("length: ", indexes[1],
+ " should be -1 or greater"));
+ return std::string{};
+ }
+ try {
+ return list
+ .sublist(static_cast<cmList::size_type>(indexes[0]),
+ static_cast<cmList::size_type>(indexes[1]))
+ .to_string();
+ } catch (std::out_of_range& e) {
+ reportError(ctx, cnt->GetOriginalExpression(), e.what());
+ return std::string{};
+ }
+ }
+ }
+ return std::string{};
+ } },
+ { "FIND"_s,
+ [](cmGeneratorExpressionContext* ctx,
+ const GeneratorExpressionContent* cnt,
+ Arguments& args) -> std::string {
+ if (CheckListParameters(ctx, cnt, "FIND"_s, args, 2)) {
+ auto list = GetList(args.front());
+ auto index = list.find(args[1]);
+ return index == cmList::npos ? "-1" : std::to_string(index);
+ }
+ return std::string{};
+ } },
+ { "APPEND"_s,
+ [](cmGeneratorExpressionContext* ctx,
+ const GeneratorExpressionContent* cnt,
+ Arguments& args) -> std::string {
+ if (CheckListParametersEx(ctx, cnt, "APPEND"_s, args.size(), 2,
+ false)) {
+ auto list = args.front();
+ args.advance(1);
+ return cmList::append(list, args.begin(), args.end());
+ }
+ return std::string{};
+ } },
+ { "PREPEND"_s,
+ [](cmGeneratorExpressionContext* ctx,
+ const GeneratorExpressionContent* cnt,
+ Arguments& args) -> std::string {
+ if (CheckListParametersEx(ctx, cnt, "PREPEND"_s, args.size(), 2,
+ false)) {
+ auto list = args.front();
+ args.advance(1);
+ return cmList::prepend(list, args.begin(), args.end());
+ }
+ return std::string{};
+ } },
+ { "INSERT"_s,
+ [](cmGeneratorExpressionContext* ctx,
+ const GeneratorExpressionContent* cnt,
+ Arguments& args) -> std::string {
+ if (CheckListParametersEx(ctx, cnt, "INSERT"_s, args.size(), 3,
+ false)) {
+ cmList::index_type index;
+ if (!GetNumericArgument(args[1], index)) {
+ reportError(
+ ctx, cnt->GetOriginalExpression(),
+ cmStrCat("index: \"", args[1], "\" is not a valid index"));
+ return std::string{};
+ }
+ try {
+ auto list = GetList(args.front());
+ args.advance(2);
+ list.insert_items(index, args.begin(), args.end());
+ return list.to_string();
+ } catch (std::out_of_range& e) {
+ reportError(ctx, cnt->GetOriginalExpression(), e.what());
+ return std::string{};
+ }
+ }
+ return std::string{};
+ } },
+ { "POP_BACK"_s,
+ [](cmGeneratorExpressionContext* ctx,
+ const GeneratorExpressionContent* cnt,
+ Arguments& args) -> std::string {
+ if (CheckListParameters(ctx, cnt, "POP_BACK"_s, args)) {
+ auto list = GetList(args.front());
+ if (!list.empty()) {
+ list.pop_back();
+ return list.to_string();
+ }
+ }
+ return std::string{};
+ } },
+ { "POP_FRONT"_s,
+ [](cmGeneratorExpressionContext* ctx,
+ const GeneratorExpressionContent* cnt,
+ Arguments& args) -> std::string {
+ if (CheckListParameters(ctx, cnt, "POP_FRONT"_s, args)) {
+ auto list = GetList(args.front());
+ if (!list.empty()) {
+ list.pop_front();
+ return list.to_string();
+ }
+ }
+ return std::string{};
+ } },
+ { "REMOVE_DUPLICATES"_s,
+ [](cmGeneratorExpressionContext* ctx,
+ const GeneratorExpressionContent* cnt,
+ Arguments& args) -> std::string {
+ if (CheckListParameters(ctx, cnt, "REMOVE_DUPLICATES"_s, args)) {
+ return GetList(args.front()).remove_duplicates().to_string();
+ }
+ return std::string{};
+ } },
+ { "REMOVE_ITEM"_s,
+ [](cmGeneratorExpressionContext* ctx,
+ const GeneratorExpressionContent* cnt,
+ Arguments& args) -> std::string {
+ if (CheckListParametersEx(ctx, cnt, "REMOVE_ITEM"_s, args.size(),
+ 2, false)) {
+ auto list = GetList(args.front());
+ args.advance(1);
+ cmList items{ args.begin(), args.end(),
+ cmList::ExpandElements::Yes };
+ return list.remove_items(items.begin(), items.end()).to_string();
+ }
+ return std::string{};
+ } },
+ { "REMOVE_AT"_s,
+ [](cmGeneratorExpressionContext* ctx,
+ const GeneratorExpressionContent* cnt,
+ Arguments& args) -> std::string {
+ if (CheckListParametersEx(ctx, cnt, "REMOVE_AT"_s, args.size(), 2,
+ false)) {
+ auto list = GetList(args.front());
+ std::vector<cmList::index_type> indexes;
+ if (!GetNumericArguments(ctx, cnt, args.advance(1), indexes,
+ cmList::ExpandElements::Yes)) {
+ return std::string{};
+ }
+ try {
+ return list.remove_items(indexes.begin(), indexes.end())
+ .to_string();
+ } catch (std::out_of_range& e) {
+ reportError(ctx, cnt->GetOriginalExpression(), e.what());
+ return std::string{};
+ }
+ }
+ return std::string{};
+ } },
+ { "FILTER"_s,
+ [](cmGeneratorExpressionContext* ctx,
+ const GeneratorExpressionContent* cnt,
+ Arguments& args) -> std::string {
+ if (CheckListParameters(ctx, cnt, "FILTER"_s, args, 3)) {
+ auto const& op = args[1];
+ if (op != "INCLUDE"_s && op != "EXCLUDE"_s) {
+ reportError(
+ ctx, cnt->GetOriginalExpression(),
+ cmStrCat("sub-command FILTER does not recognize operator \"",
+ op, "\". It must be either INCLUDE or EXCLUDE."));
+ return std::string{};
+ }
+ try {
+ return GetList(args.front())
+ .filter(args[2],
+ op == "INCLUDE"_s ? cmList::FilterMode::INCLUDE
+ : cmList::FilterMode::EXCLUDE)
+ .to_string();
+ } catch (std::invalid_argument&) {
+ reportError(
+ ctx, cnt->GetOriginalExpression(),
+ cmStrCat("sub-command FILTER, failed to compile regex \"",
+ args[2], "\"."));
+ return std::string{};
+ }
+ }
+ return std::string{};
+ } },
+ { "TRANSFORM"_s,
+ [](cmGeneratorExpressionContext* ctx,
+ const GeneratorExpressionContent* cnt,
+ Arguments& args) -> std::string {
+ if (CheckListParametersEx(ctx, cnt, "TRANSFORM"_s, args.size(), 2,
+ false)) {
+ auto list = GetList(args.front());
+ if (!list.empty()) {
+ struct ActionDescriptor
+ {
+ ActionDescriptor(std::string name)
+ : Name(std::move(name))
+ {
+ }
+ ActionDescriptor(std::string name,
+ cmList::TransformAction action, int arity)
+ : Name(std::move(name))
+ , Action(action)
+ , Arity(arity)
+ {
+ }
+
+ operator const std::string&() const { return this->Name; }
+
+ std::string Name;
+ cmList::TransformAction Action;
+ int Arity = 0;
+ };
+
+ static std::set<
+ ActionDescriptor,
+ std::function<bool(const std::string&, const std::string&)>>
+ descriptors{
+ { { "APPEND", cmList::TransformAction::APPEND, 1 },
+ { "PREPEND", cmList::TransformAction::PREPEND, 1 },
+ { "TOUPPER", cmList::TransformAction::TOUPPER, 0 },
+ { "TOLOWER", cmList::TransformAction::TOLOWER, 0 },
+ { "STRIP", cmList::TransformAction::STRIP, 0 },
+ { "REPLACE", cmList::TransformAction::REPLACE, 2 } },
+ [](const std::string& x, const std::string& y) {
+ return x < y;
+ }
+ };
+
+ auto descriptor = descriptors.find(args.advance(1).front());
+ if (descriptor == descriptors.end()) {
+ reportError(ctx, cnt->GetOriginalExpression(),
+ cmStrCat(" sub-command TRANSFORM, ",
+ args.front(), " invalid action."));
+ return std::string{};
+ }
+
+ // Action arguments
+ args.advance(1);
+ if (args.size() < descriptor->Arity) {
+ reportError(ctx, cnt->GetOriginalExpression(),
+ cmStrCat("sub-command TRANSFORM, action ",
+ descriptor->Name, " expects ",
+ descriptor->Arity, " argument(s)."));
+ return std::string{};
+ }
+ std::vector<std::string> arguments;
+ if (descriptor->Arity > 0) {
+ arguments = std::vector<std::string>(
+ args.begin(), args.begin() + descriptor->Arity);
+ args.advance(descriptor->Arity);
+ }
+
+ const std::string REGEX{ "REGEX" };
+ const std::string AT{ "AT" };
+ const std::string FOR{ "FOR" };
+ std::unique_ptr<cmList::TransformSelector> selector;
+
+ try {
+ // handle optional arguments
+ while (!args.empty()) {
+ if ((args.front() == REGEX || args.front() == AT ||
+ args.front() == FOR) &&
+ selector) {
+ reportError(ctx, cnt->GetOriginalExpression(),
+ cmStrCat("sub-command TRANSFORM, selector "
+ "already specified (",
+ selector->GetTag(), ")."));
+
+ return std::string{};
+ }
+
+ // REGEX selector
+ if (args.front() == REGEX) {
+ if (args.advance(1).empty()) {
+ reportError(
+ ctx, cnt->GetOriginalExpression(),
+ "sub-command TRANSFORM, selector REGEX expects "
+ "'regular expression' argument.");
+ return std::string{};
+ }
+
+ selector = cmList::TransformSelector::New<
+ cmList::TransformSelector::REGEX>(args.front());
+
+ args.advance(1);
+ continue;
+ }
+
+ // AT selector
+ if (args.front() == AT) {
+ args.advance(1);
+ // get all specified indexes
+ std::vector<cmList::index_type> indexes;
+ while (!args.empty()) {
+ cmList indexList{ args.front() };
+ for (auto const& index : indexList) {
+ cmList::index_type value;
+
+ if (!GetNumericArgument(index, value)) {
+ // this is not a number, stop processing
+ reportError(
+ ctx, cnt->GetOriginalExpression(),
+ cmStrCat("sub-command TRANSFORM, selector AT: '",
+ index, "': unexpected argument."));
+ return std::string{};
+ }
+ indexes.push_back(value);
+ }
+ args.advance(1);
+ }
+
+ if (indexes.empty()) {
+ reportError(ctx, cnt->GetOriginalExpression(),
+ "sub-command TRANSFORM, selector AT "
+ "expects at least one "
+ "numeric value.");
+ return std::string{};
+ }
+
+ selector = cmList::TransformSelector::New<
+ cmList::TransformSelector::AT>(std::move(indexes));
+
+ continue;
+ }
+
+ // FOR selector
+ if (args.front() == FOR) {
+ if (args.advance(1).size() < 2) {
+ reportError(ctx, cnt->GetOriginalExpression(),
+ "sub-command TRANSFORM, selector FOR "
+ "expects, at least,"
+ " two arguments.");
+ return std::string{};
+ }
+
+ cmList::index_type start = 0;
+ cmList::index_type stop = 0;
+ cmList::index_type step = 1;
+ bool valid = false;
+
+ if (GetNumericArgument(args.front(), start) &&
+ GetNumericArgument(args.advance(1).front(), stop)) {
+ valid = true;
+ }
+
+ if (!valid) {
+ reportError(
+ ctx, cnt->GetOriginalExpression(),
+ "sub-command TRANSFORM, selector FOR expects, "
+ "at least, two numeric values.");
+ return std::string{};
+ }
+ // try to read a third numeric value for step
+ if (!args.advance(1).empty()) {
+ if (!GetNumericArgument(args.front(), step)) {
+ // this is not a number
+ step = -1;
+ }
+ args.advance(1);
+ }
+
+ if (step <= 0) {
+ reportError(
+ ctx, cnt->GetOriginalExpression(),
+ "sub-command TRANSFORM, selector FOR expects "
+ "positive numeric value for <step>.");
+ return std::string{};
+ }
+
+ selector = cmList::TransformSelector::New<
+ cmList::TransformSelector::FOR>({ start, stop, step });
+ continue;
+ }
+
+ reportError(ctx, cnt->GetOriginalExpression(),
+ cmStrCat("sub-command TRANSFORM, '",
+ cmJoin(args, ", "),
+ "': unexpected argument(s)."));
+ return std::string{};
+ }
+
+ return list
+ .transform(descriptor->Action, arguments,
+ std::move(selector))
+ .to_string();
+ } catch (cmList::transform_error& e) {
+ reportError(ctx, cnt->GetOriginalExpression(), e.what());
+ return std::string{};
+ }
+ }
+ }
+ return std::string{};
+ } },
+ { "REVERSE"_s,
+ [](cmGeneratorExpressionContext* ctx,
+ const GeneratorExpressionContent* cnt,
+ Arguments& args) -> std::string {
+ if (CheckListParameters(ctx, cnt, "REVERSE"_s, args)) {
+ return GetList(args.front()).reverse().to_string();
+ }
+ return std::string{};
+ } },
+ { "SORT"_s,
+ [](cmGeneratorExpressionContext* ctx,
+ const GeneratorExpressionContent* cnt,
+ Arguments& args) -> std::string {
+ if (CheckListParametersEx(ctx, cnt, "SORT"_s, args.size(), 1,
+ false)) {
+ auto list = GetList(args.front());
+ args.advance(1);
+ const auto COMPARE = "COMPARE:"_s;
+ const auto CASE = "CASE:"_s;
+ const auto ORDER = "ORDER:"_s;
+ using SortConfig = cmList::SortConfiguration;
+ SortConfig sortConfig;
+ for (auto const& arg : args) {
+ if (cmHasPrefix(arg, COMPARE)) {
+ if (sortConfig.Compare !=
+ SortConfig::CompareMethod::DEFAULT) {
+ reportError(ctx, cnt->GetOriginalExpression(),
+ "sub-command SORT, COMPARE option has been "
+ "specified multiple times.");
+ return std::string{};
+ }
+ auto option =
+ cm::string_view{ arg.c_str() + COMPARE.length() };
+ if (option == "STRING"_s) {
+ sortConfig.Compare = SortConfig::CompareMethod::STRING;
+ continue;
+ }
+ if (option == "FILE_BASENAME"_s) {
+ sortConfig.Compare =
+ SortConfig::CompareMethod::FILE_BASENAME;
+ continue;
+ }
+ if (option == "NATURAL"_s) {
+ sortConfig.Compare = SortConfig::CompareMethod::NATURAL;
+ continue;
+ }
+ reportError(
+ ctx, cnt->GetOriginalExpression(),
+ cmStrCat(
+ "sub-command SORT, an invalid COMPARE option has been "
+ "specified: \"",
+ option, "\"."));
+ return std::string{};
+ }
+ if (cmHasPrefix(arg, CASE)) {
+ if (sortConfig.Case !=
+ SortConfig::CaseSensitivity::DEFAULT) {
+ reportError(ctx, cnt->GetOriginalExpression(),
+ "sub-command SORT, CASE option has been "
+ "specified multiple times.");
+ return std::string{};
+ }
+ auto option = cm::string_view{ arg.c_str() + CASE.length() };
+ if (option == "SENSITIVE"_s) {
+ sortConfig.Case = SortConfig::CaseSensitivity::SENSITIVE;
+ continue;
+ }
+ if (option == "INSENSITIVE"_s) {
+ sortConfig.Case = SortConfig::CaseSensitivity::INSENSITIVE;
+ continue;
+ }
+ reportError(
+ ctx, cnt->GetOriginalExpression(),
+ cmStrCat(
+ "sub-command SORT, an invalid CASE option has been "
+ "specified: \"",
+ option, "\"."));
+ return std::string{};
+ }
+ if (cmHasPrefix(arg, ORDER)) {
+ if (sortConfig.Order != SortConfig::OrderMode::DEFAULT) {
+ reportError(ctx, cnt->GetOriginalExpression(),
+ "sub-command SORT, ORDER option has been "
+ "specified multiple times.");
+ return std::string{};
+ }
+ auto option =
+ cm::string_view{ arg.c_str() + ORDER.length() };
+ if (option == "ASCENDING"_s) {
+ sortConfig.Order = SortConfig::OrderMode::ASCENDING;
+ continue;
+ }
+ if (option == "DESCENDING"_s) {
+ sortConfig.Order = SortConfig::OrderMode::DESCENDING;
+ continue;
+ }
+ reportError(
+ ctx, cnt->GetOriginalExpression(),
+ cmStrCat(
+ "sub-command SORT, an invalid ORDER option has been "
+ "specified: \"",
+ option, "\"."));
+ return std::string{};
+ }
+ reportError(ctx, cnt->GetOriginalExpression(),
+ cmStrCat("sub-command SORT, option \"", arg,
+ "\" is invalid."));
+ return std::string{};
+ }
+
+ return list.sort(sortConfig).to_string();
+ }
+ return std::string{};
+ } }
+ };
+
+ if (cm::contains(listCommands, parameters.front())) {
+ auto args = Arguments{ parameters }.advance(1);
+ return listCommands[parameters.front()](context, content, args);
+ }
+
+ reportError(context, content->GetOriginalExpression(),
+ cmStrCat(parameters.front(), ": invalid option."));
+ return std::string{};
+ }
+} listNode;
+
static const struct MakeCIdentifierNode : public cmGeneratorExpressionNode
{
MakeCIdentifierNode() {} // NOLINT(modernize-use-equals-default)
@@ -1472,11 +2167,11 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
// This imported target has an appropriate location
// for this (possibly mapped) config.
// Check if there is a proper config mapping for the tested config.
- std::vector<std::string> mappedConfigs;
+ cmList mappedConfigs;
std::string mapProp = cmStrCat(
"MAP_IMPORTED_CONFIG_", cmSystemTools::UpperCase(context->Config));
if (cmValue mapValue = context->CurrentTarget->GetProperty(mapProp)) {
- cmExpandList(cmSystemTools::UpperCase(*mapValue), mappedConfigs);
+ mappedConfigs.assign(cmSystemTools::UpperCase(*mapValue));
for (auto const& param : parameters) {
if (cm::contains(mappedConfigs, cmSystemTools::UpperCase(param))) {
@@ -1581,7 +2276,8 @@ static const struct CompileLanguageAndIdNode : public cmGeneratorExpressionNode
// reportError(context, content->GetOriginalExpression(), "");
reportError(
context, content->GetOriginalExpression(),
- "$<COMPILE_LANG_AND_ID:lang,id> may only be used with binary targets "
+ "$<COMPILE_LANG_AND_ID:lang,id> may only be used with binary "
+ "targets "
"to specify include directories, compile definitions, and compile "
"options. It may not be used with the add_custom_command, "
"add_custom_target, or file(GENERATE) commands.");
@@ -1726,7 +2422,8 @@ static const struct LinkLanguageAndIdNode : public cmGeneratorExpressionNode
reportError(
context, content->GetOriginalExpression(),
"$<LINK_LANG_AND_ID:lang,id> may only be used with binary targets "
- "to specify link libraries, link directories, link options, and link "
+ "to specify link libraries, link directories, link options, and "
+ "link "
"depends.");
return std::string();
}
@@ -1785,8 +2482,7 @@ static const struct LinkLibraryNode : public cmGeneratorExpressionNode
return std::string();
}
- std::vector<std::string> list;
- cmExpandLists(parameters.begin(), parameters.end(), list);
+ cmList list{ parameters.begin(), parameters.end() };
if (list.empty()) {
reportError(
context, content->GetOriginalExpression(),
@@ -1871,8 +2567,7 @@ static const struct LinkGroupNode : public cmGeneratorExpressionNode
return std::string();
}
- std::vector<std::string> list;
- cmExpandLists(parameters.begin(), parameters.end(), list);
+ cmList list{ parameters.begin(), parameters.end() };
if (list.empty()) {
reportError(
context, content->GetOriginalExpression(),
@@ -1962,8 +2657,7 @@ static const struct DeviceLinkNode : public cmGeneratorExpressionNode
}
if (context->HeadTarget->IsDeviceLink()) {
- std::vector<std::string> list;
- cmExpandLists(parameters.begin(), parameters.end(), list);
+ cmList list{ parameters.begin(), parameters.end() };
const auto DL_BEGIN = "<DEVICE_LINK>"_s;
const auto DL_END = "</DEVICE_LINK>"_s;
cm::erase_if(list, [&](const std::string& item) {
@@ -2108,7 +2802,8 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
reportError(
context, content->GetOriginalExpression(),
"$<TARGET_PROPERTY:prop> may only be used with binary targets. "
- "It may not be used with add_custom_command or add_custom_target. "
+ "It may not be used with add_custom_command or add_custom_target. "
+ " "
" "
"Specify the target to read a property from using the "
"$<TARGET_PROPERTY:tgt,prop> signature instead.");
@@ -2373,14 +3068,14 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode
}
}
- std::vector<std::string> objects;
+ cmList objects;
if (gt->IsImported()) {
cmValue loc = nullptr;
cmValue imp = nullptr;
std::string suffix;
if (gt->Target->GetMappedConfig(context->Config, loc, imp, suffix)) {
- cmExpandList(*loc, objects);
+ objects.assign(*loc);
}
context->HadContextSensitiveCondition = true;
} else {
@@ -2398,7 +3093,7 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode
context->HadContextSensitiveCondition = true;
}
- for (std::string& o : objects) {
+ for (auto& o : objects) {
o = cmStrCat(obj_dir, o);
}
}
@@ -2518,7 +3213,7 @@ static const struct CompileFeaturesNode : public cmGeneratorExpressionNode
}
context->HadHeadSensitiveCondition = true;
- using LangMap = std::map<std::string, std::vector<std::string>>;
+ using LangMap = std::map<std::string, cmList>;
static LangMap availableFeatures;
LangMap testedFeatures;
@@ -2540,7 +3235,7 @@ static const struct CompileFeaturesNode : public cmGeneratorExpressionNode
reportError(context, content->GetOriginalExpression(), error);
return std::string();
}
- cmExpandList(featuresKnown, availableFeatures[lang]);
+ availableFeatures[lang].assign(featuresKnown);
}
}
@@ -3691,7 +4386,7 @@ static const struct ShellPathNode : public cmGeneratorExpressionNode
const GeneratorExpressionContent* content,
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
{
- std::vector<std::string> listIn = cmExpandedList(parameters.front());
+ cmList listIn{ parameters.front() };
if (listIn.empty()) {
reportError(context, content->GetOriginalExpression(),
"\"\" is not an absolute path.");
@@ -3802,6 +4497,7 @@ const cmGeneratorExpressionNode* cmGeneratorExpressionNode::GetNode(
{ "IN_LIST", &inListNode },
{ "FILTER", &filterNode },
{ "REMOVE_DUPLICATES", &removeDuplicatesNode },
+ { "LIST", &listNode },
{ "LOWER_CASE", &lowerCaseNode },
{ "UPPER_CASE", &upperCaseNode },
{ "PATH", &pathNode },
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 7e5ef0a7cb..28ba60f4ed 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -36,6 +36,7 @@
#include "cmGeneratorExpressionDAGChecker.h"
#include "cmGeneratorExpressionNode.h"
#include "cmGlobalGenerator.h"
+#include "cmList.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -730,6 +731,29 @@ void cmGeneratorTarget::AddIncludeDirectory(const std::string& src,
BT<std::string>(src, this->Makefile->GetBacktrace()), true));
}
+void cmGeneratorTarget::AddSystemIncludeDirectory(std::string const& inc,
+ std::string const& lang)
+{
+ std::string config_upper;
+ auto const& configs =
+ this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
+
+ for (auto const& config : configs) {
+ std::string inc_with_config = inc;
+ if (!config.empty()) {
+ cmSystemTools::ReplaceString(inc_with_config, "$<CONFIG>", config);
+ config_upper = cmSystemTools::UpperCase(config);
+ }
+ auto const& key = cmStrCat(config_upper, "/", lang);
+ this->Target->AddSystemIncludeDirectories({ inc_with_config });
+ this->SystemIncludesCache[key].emplace_back(inc_with_config);
+
+ // SystemIncludesCache should be sorted so that binary search can be used
+ std::sort(this->SystemIncludesCache[key].begin(),
+ this->SystemIncludesCache[key].end());
+ }
+}
+
std::vector<cmSourceFile*> const* cmGeneratorTarget::GetSourceDepends(
cmSourceFile const* sf) const
{
@@ -746,14 +770,13 @@ void handleSystemIncludesDep(cmLocalGenerator* lg,
const std::string& config,
cmGeneratorTarget const* headTarget,
cmGeneratorExpressionDAGChecker* dagChecker,
- std::vector<std::string>& result,
- bool excludeImported, std::string const& language)
+ cmList& result, bool excludeImported,
+ std::string const& language)
{
if (cmValue dirs =
depTgt->GetProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES")) {
- cmExpandList(cmGeneratorExpression::Evaluate(*dirs, lg, config, headTarget,
- dagChecker, depTgt, language),
- result);
+ result.append(cmGeneratorExpression::Evaluate(
+ *dirs, lg, config, headTarget, dagChecker, depTgt, language));
}
if (!depTgt->GetPropertyAsBool("SYSTEM")) {
return;
@@ -768,9 +791,8 @@ void handleSystemIncludesDep(cmLocalGenerator* lg,
}
if (cmValue dirs = depTgt->GetProperty("INTERFACE_INCLUDE_DIRECTORIES")) {
- cmExpandList(cmGeneratorExpression::Evaluate(*dirs, lg, config, headTarget,
- dagChecker, depTgt, language),
- result);
+ result.append(cmGeneratorExpression::Evaluate(
+ *dirs, lg, config, headTarget, dagChecker, depTgt, language));
}
}
}
@@ -1264,12 +1286,11 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory(
bool excludeImported = this->GetPropertyAsBool("NO_SYSTEM_FROM_IMPORTED");
- std::vector<std::string> result;
+ cmList result;
for (std::string const& it : this->Target->GetSystemIncludeDirectories()) {
- cmExpandList(cmGeneratorExpression::Evaluate(it, this->LocalGenerator,
- config, this, &dagChecker,
- nullptr, language),
- result);
+ result.append(cmGeneratorExpression::Evaluate(it, this->LocalGenerator,
+ config, this, &dagChecker,
+ nullptr, language));
}
std::vector<cmGeneratorTarget const*> const& deps =
@@ -1634,20 +1655,20 @@ void AddFileSetEntries(cmGeneratorTarget const* headTarget,
EvaluatedTargetPropertyEntries& entries)
{
for (auto const& entry : headTarget->Target->GetHeaderSetsEntries()) {
- for (auto const& name : cmExpandedList(entry.Value)) {
+ for (auto const& name : cmList{ entry.Value }) {
auto const* headerSet = headTarget->Target->GetFileSet(name);
addFileSetEntry(headTarget, config, dagChecker, headerSet, entries);
}
}
for (auto const& entry : headTarget->Target->GetCxxModuleSetsEntries()) {
- for (auto const& name : cmExpandedList(entry.Value)) {
+ for (auto const& name : cmList{ entry.Value }) {
auto const* cxxModuleSet = headTarget->Target->GetFileSet(name);
addFileSetEntry(headTarget, config, dagChecker, cxxModuleSet, entries);
}
}
for (auto const& entry :
headTarget->Target->GetCxxModuleHeaderSetsEntries()) {
- for (auto const& name : cmExpandedList(entry.Value)) {
+ for (auto const& name : cmList{ entry.Value }) {
auto const* cxxModuleHeaderSet = headTarget->Target->GetFileSet(name);
addFileSetEntry(headTarget, config, dagChecker, cxxModuleHeaderSet,
entries);
@@ -1740,8 +1761,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths(
cmBTStringRange sourceEntries = this->Target->GetSourceEntries();
for (auto const& entry : sourceEntries) {
- std::vector<std::string> items = cmExpandedList(entry.Value);
- for (std::string const& item : items) {
+ cmList items{ entry.Value };
+ for (auto const& item : items) {
if (cmHasLiteralPrefix(item, "$<TARGET_OBJECTS:") &&
item.back() == '>') {
continue;
@@ -1752,10 +1773,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths(
return files;
}
- std::vector<std::string> debugProperties;
- this->Makefile->GetDefExpandList("CMAKE_DEBUG_TARGET_PROPERTIES",
- debugProperties);
-
+ cmList debugProperties{ this->Makefile->GetDefinition(
+ "CMAKE_DEBUG_TARGET_PROPERTIES") };
bool debugSources =
!this->DebugSourcesDone && cm::contains(debugProperties, "SOURCES");
@@ -3105,8 +3124,8 @@ void cmTargetTraceDependencies::Trace()
// Queue dependencies added explicitly by the user.
if (cmValue additionalDeps = sf->GetProperty("OBJECT_DEPENDS")) {
- std::vector<std::string> objDeps = cmExpandedList(*additionalDeps);
- for (std::string& objDep : objDeps) {
+ cmList objDeps{ *additionalDeps };
+ for (auto& objDep : objDeps) {
if (cmSystemTools::FileIsFullPath(objDep)) {
objDep = cmSystemTools::CollapseFullPath(objDep);
}
@@ -3299,9 +3318,9 @@ std::string cmGeneratorTarget::GetCompilePDBDirectory(
std::vector<std::string> cmGeneratorTarget::GetAppleArchs(
std::string const& config, cm::optional<std::string> lang) const
{
- std::vector<std::string> archVec;
+ cmList archList;
if (!this->IsApple()) {
- return archVec;
+ return std::move(archList.data());
}
cmValue archs = nullptr;
if (!config.empty()) {
@@ -3313,17 +3332,18 @@ std::vector<std::string> cmGeneratorTarget::GetAppleArchs(
archs = this->GetProperty("OSX_ARCHITECTURES");
}
if (archs) {
- cmExpandList(*archs, archVec);
+ archList.assign(*archs);
}
- if (archVec.empty() &&
+ if (archList.empty() &&
// Fall back to a default architecture if no compiler target is set.
(!lang ||
this->Makefile
->GetDefinition(cmStrCat("CMAKE_", *lang, "_COMPILER_TARGET"))
.IsEmpty())) {
- this->Makefile->GetDefExpandList("_CMAKE_APPLE_ARCHS_DEFAULT", archVec);
+ archList.assign(
+ this->Makefile->GetDefinition("_CMAKE_APPLE_ARCHS_DEFAULT"));
}
- return archVec;
+ return std::move(archList.data());
}
void cmGeneratorTarget::AddExplicitLanguageFlags(std::string& flags,
@@ -3432,10 +3452,9 @@ void cmGeneratorTarget::AddCUDAArchitectureFlags(cmBuildStep compileOrLink,
std::vector<CudaArchitecture> architectures;
{
- std::vector<std::string> options;
- cmExpandList(property, options);
+ cmList options(property);
- for (std::string& option : options) {
+ for (auto& option : options) {
CudaArchitecture architecture;
// Architecture name is up to the first specifier.
@@ -3526,8 +3545,7 @@ void cmGeneratorTarget::AddISPCTargetFlags(std::string& flags) const
this->Makefile->GetSafeDefinition("CMAKE_ISPC_COMPILER_ID");
if (compiler == "Intel") {
- std::vector<std::string> targets;
- cmExpandList(property, targets);
+ cmList targets(property);
if (!targets.empty()) {
flags += cmStrCat(" --target=", cmWrap("", targets, "", ","));
}
@@ -3549,8 +3567,7 @@ void cmGeneratorTarget::AddHIPArchitectureFlags(std::string& flags) const
return;
}
- std::vector<std::string> options;
- cmExpandList(property, options);
+ cmList options(property);
for (std::string& option : options) {
flags += " --offload-arch=" + option;
@@ -3762,10 +3779,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories(
cmGeneratorExpressionDAGChecker dagChecker(this, "INCLUDE_DIRECTORIES",
nullptr, nullptr);
- std::vector<std::string> debugProperties;
- this->Makefile->GetDefExpandList("CMAKE_DEBUG_TARGET_PROPERTIES",
- debugProperties);
-
+ cmList debugProperties{ this->Makefile->GetDefinition(
+ "CMAKE_DEBUG_TARGET_PROPERTIES") };
bool debugIncludes = !this->DebugIncludesDone &&
cm::contains(debugProperties, "INCLUDE_DIRECTORIES");
@@ -4021,10 +4036,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileOptions(
cmGeneratorExpressionDAGChecker dagChecker(this, "COMPILE_OPTIONS", nullptr,
nullptr);
- std::vector<std::string> debugProperties;
- this->Makefile->GetDefExpandList("CMAKE_DEBUG_TARGET_PROPERTIES",
- debugProperties);
-
+ cmList debugProperties{ this->Makefile->GetDefinition(
+ "CMAKE_DEBUG_TARGET_PROPERTIES") };
bool debugOptions = !this->DebugCompileOptionsDone &&
cm::contains(debugProperties, "COMPILE_OPTIONS");
@@ -4064,10 +4077,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileFeatures(
cmGeneratorExpressionDAGChecker dagChecker(this, "COMPILE_FEATURES", nullptr,
nullptr);
- std::vector<std::string> debugProperties;
- this->Makefile->GetDefExpandList("CMAKE_DEBUG_TARGET_PROPERTIES",
- debugProperties);
-
+ cmList debugProperties{ this->Makefile->GetDefinition(
+ "CMAKE_DEBUG_TARGET_PROPERTIES") };
bool debugFeatures = !this->DebugCompileFeaturesDone &&
cm::contains(debugProperties, "COMPILE_FEATURES");
@@ -4116,10 +4127,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileDefinitions(
cmGeneratorExpressionDAGChecker dagChecker(this, "COMPILE_DEFINITIONS",
nullptr, nullptr);
- std::vector<std::string> debugProperties;
- this->Makefile->GetDefExpandList("CMAKE_DEBUG_TARGET_PROPERTIES",
- debugProperties);
-
+ cmList debugProperties{ this->Makefile->GetDefinition(
+ "CMAKE_DEBUG_TARGET_PROPERTIES") };
bool debugDefines = !this->DebugCompileDefinitionsDone &&
cm::contains(debugProperties, "COMPILE_DEFINITIONS");
@@ -4182,10 +4191,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetPrecompileHeaders(
cmGeneratorExpressionDAGChecker dagChecker(this, "PRECOMPILE_HEADERS",
nullptr, nullptr);
- std::vector<std::string> debugProperties;
- this->Makefile->GetDefExpandList("CMAKE_DEBUG_TARGET_PROPERTIES",
- debugProperties);
-
+ cmList debugProperties{ this->Makefile->GetDefinition(
+ "CMAKE_DEBUG_TARGET_PROPERTIES") };
bool debugDefines = !this->DebugPrecompileHeadersDone &&
std::find(debugProperties.begin(), debugProperties.end(),
"PRECOMPILE_HEADERS") != debugProperties.end();
@@ -4579,10 +4586,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkOptions(
cmGeneratorExpressionDAGChecker dagChecker(this, "LINK_OPTIONS", nullptr,
nullptr);
- std::vector<std::string> debugProperties;
- this->Makefile->GetDefExpandList("CMAKE_DEBUG_TARGET_PROPERTIES",
- debugProperties);
-
+ cmList debugProperties{ this->Makefile->GetDefinition(
+ "CMAKE_DEBUG_TARGET_PROPERTIES") };
bool debugOptions = !this->DebugLinkOptionsDone &&
cm::contains(debugProperties, "LINK_OPTIONS");
@@ -4606,7 +4611,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkOptions(
// wrap host link options
const std::string wrapper(this->Makefile->GetSafeDefinition(
"CMAKE_" + language + "_DEVICE_COMPILER_WRAPPER_FLAG"));
- std::vector<std::string> wrapperFlag = cmExpandedList(wrapper);
+ cmList wrapperFlag{ wrapper };
const std::string wrapperSep(this->Makefile->GetSafeDefinition(
"CMAKE_" + language + "_DEVICE_COMPILER_WRAPPER_FLAG_SEP"));
bool concatFlagAndArgs = true;
@@ -4665,7 +4670,7 @@ std::vector<BT<std::string>>& cmGeneratorTarget::ResolveLinkerWrapper(
"CMAKE_" + language +
(this->IsDeviceLink() ? "_DEVICE_LINKER_WRAPPER_FLAG"
: "_LINKER_WRAPPER_FLAG")));
- std::vector<std::string> wrapperFlag = cmExpandedList(wrapper);
+ cmList wrapperFlag{ wrapper };
const std::string wrapperSep(this->Makefile->GetSafeDefinition(
"CMAKE_" + language +
(this->IsDeviceLink() ? "_DEVICE_LINKER_WRAPPER_FLAG_SEP"
@@ -4863,10 +4868,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkDirectories(
cmGeneratorExpressionDAGChecker dagChecker(this, "LINK_DIRECTORIES", nullptr,
nullptr);
- std::vector<std::string> debugProperties;
- this->Makefile->GetDefExpandList("CMAKE_DEBUG_TARGET_PROPERTIES",
- debugProperties);
-
+ cmList debugProperties{ this->Makefile->GetDefinition(
+ "CMAKE_DEBUG_TARGET_PROPERTIES") };
bool debugDirectories = !this->DebugLinkDirectoriesDone &&
cm::contains(debugProperties, "LINK_DIRECTORIES");
@@ -4911,7 +4914,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkDepends(
EvaluatedTargetPropertyEntries entries;
if (cmValue linkDepends = this->GetProperty("LINK_DEPENDS")) {
- std::vector<std::string> depends = cmExpandedList(*linkDepends);
+ cmList depends{ *linkDepends };
for (const auto& depend : depends) {
std::unique_ptr<TargetPropertyEntry> entry = CreateTargetPropertyEntry(
*this->LocalGenerator->GetCMakeInstance(), depend);
@@ -5590,8 +5593,8 @@ void cmGeneratorTarget::ConstructSourceFileFlags() const
// Process public headers to mark the source files.
if (cmValue files = this->GetProperty("PUBLIC_HEADER")) {
- std::vector<std::string> relFiles = cmExpandedList(*files);
- for (std::string const& relFile : relFiles) {
+ cmList relFiles{ *files };
+ for (auto const& relFile : relFiles) {
if (cmSourceFile* sf = this->Makefile->GetSource(relFile)) {
SourceFileFlags& flags = this->SourceFlagsMap[sf];
flags.MacFolder = "Headers";
@@ -5603,8 +5606,8 @@ void cmGeneratorTarget::ConstructSourceFileFlags() const
// Process private headers after public headers so that they take
// precedence if a file is listed in both.
if (cmValue files = this->GetProperty("PRIVATE_HEADER")) {
- std::vector<std::string> relFiles = cmExpandedList(*files);
- for (std::string const& relFile : relFiles) {
+ cmList relFiles{ *files };
+ for (auto const& relFile : relFiles) {
if (cmSourceFile* sf = this->Makefile->GetSource(relFile)) {
SourceFileFlags& flags = this->SourceFlagsMap[sf];
flags.MacFolder = "PrivateHeaders";
@@ -5615,8 +5618,8 @@ void cmGeneratorTarget::ConstructSourceFileFlags() const
// Mark sources listed as resources.
if (cmValue files = this->GetProperty("RESOURCE")) {
- std::vector<std::string> relFiles = cmExpandedList(*files);
- for (std::string const& relFile : relFiles) {
+ cmList relFiles{ *files };
+ for (auto const& relFile : relFiles) {
if (cmSourceFile* sf = this->Makefile->GetSource(relFile)) {
SourceFileFlags& flags = this->SourceFlagsMap[sf];
flags.MacFolder = "";
@@ -5643,8 +5646,7 @@ cmGeneratorTarget::GetCompatibleInterfaces(std::string const& config) const
for (cmGeneratorTarget const* li : deps) {
#define CM_READ_COMPATIBLE_INTERFACE(X, x) \
if (cmValue prop = li->GetProperty("COMPATIBLE_INTERFACE_" #X)) { \
- std::vector<std::string> props; \
- cmExpandList(*prop, props); \
+ cmList props(*prop); \
compat.Props##x.insert(props.begin(), props.end()); \
}
CM_READ_COMPATIBLE_INTERFACE(BOOL, Bool)
@@ -5757,7 +5759,7 @@ void checkPropertyConsistency(cmGeneratorTarget const* depender,
return;
}
- std::vector<std::string> props = cmExpandedList(*prop);
+ cmList props{ *prop };
std::string pdir =
cmStrCat(cmSystemTools::GetCMakeRoot(), "/Help/prop_tgt/");
@@ -6718,10 +6720,8 @@ void cmGeneratorTarget::ReportPropertyOrigin(
const std::string& p, const std::string& result, const std::string& report,
const std::string& compatibilityType) const
{
- std::vector<std::string> debugProperties;
- this->Target->GetMakefile()->GetDefExpandList(
- "CMAKE_DEBUG_TARGET_PROPERTIES", debugProperties);
-
+ cmList debugProperties{ this->Target->GetMakefile()->GetDefinition(
+ "CMAKE_DEBUG_TARGET_PROPERTIES") };
bool debugOrigin = !this->DebugCompatiblePropertiesDone[p] &&
cm::contains(debugProperties, p);
@@ -6800,10 +6800,10 @@ void cmGeneratorTarget::ExpandLinkItems(
entry.Backtrace);
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(entry.Value);
cge->SetEvaluateForBuildsystem(true);
- std::vector<std::string> libs = cmExpandedList(
- cge->Evaluate(this->LocalGenerator, config, headTarget, &dagChecker,
- this, headTarget->LinkerLanguage));
- for (std::string const& lib : libs) {
+ cmList libs{ cge->Evaluate(this->LocalGenerator, config, headTarget,
+ &dagChecker, this,
+ headTarget->LinkerLanguage) };
+ for (auto const& lib : libs) {
if (cm::optional<cmLinkItem> maybeItem = this->LookupLinkItem(
lib, cge->GetBacktrace(), &scope,
field == LinkInterfaceField::Libraries ? LookupSelf::No
@@ -7467,10 +7467,10 @@ std::vector<ValueType> computeImplicitLanguageTargets(
currentTarget->GetRuntimeLinkLibrary(lang, config);
if (cmValue runtimeLinkOptions = currentTarget->Makefile->GetDefinition(
"CMAKE_" + lang + "_RUNTIME_LIBRARIES_" + runtimeLibrary)) {
- std::vector<std::string> libsVec = cmExpandedList(*runtimeLinkOptions);
- result.reserve(libsVec.size());
+ cmList libsList{ *runtimeLinkOptions };
+ result.reserve(libsList.size());
- for (std::string const& i : libsVec) {
+ for (auto const& i : libsList) {
cmGeneratorTarget::TargetOrString resolved =
currentTarget->ResolveTargetReference(i, lg);
if (resolved.Target) {
@@ -7551,9 +7551,9 @@ const cmLinkInterface* cmGeneratorTarget::GetImportLinkInterface(
this->ExpandLinkItems(info->LibrariesProp, cmMakeRange(info->Libraries),
config, headTarget, interfaceFor,
LinkInterfaceField::Libraries, iface);
- std::vector<std::string> deps = cmExpandedList(info->SharedDeps);
+ cmList deps{ info->SharedDeps };
LookupLinkItemScope scope{ this->LocalGenerator };
- for (std::string const& dep : deps) {
+ for (auto const& dep : deps) {
if (cm::optional<cmLinkItem> maybeItem = this->LookupLinkItem(
dep, cmListFileBacktrace(), &scope, LookupSelf::No)) {
iface.SharedDeps.emplace_back(std::move(*maybeItem));
@@ -7874,8 +7874,8 @@ void cmGeneratorTarget::GetObjectLibrariesCMP0026(
// behavior of CMP0024 and CMP0026 only.
cmBTStringRange rng = this->Target->GetSourceEntries();
for (auto const& entry : rng) {
- std::vector<std::string> files = cmExpandedList(entry.Value);
- for (std::string const& li : files) {
+ cmList files{ entry.Value };
+ for (auto const& li : files) {
if (cmHasLiteralPrefix(li, "$<TARGET_OBJECTS:") && li.back() == '>') {
std::string objLibName = li.substr(17, li.size() - 18);
@@ -8223,7 +8223,6 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries(
cmBTStringRange entryRange = this->Target->GetLinkImplementationEntries();
// Collect libraries directly linked in this configuration.
for (auto const& entry : entryRange) {
- std::vector<std::string> llibs;
// Keep this logic in sync with ExpandLinkItems.
cmGeneratorExpressionDAGChecker dagChecker(this, "LINK_LIBRARIES", nullptr,
nullptr);
@@ -8251,7 +8250,7 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries(
cge->Evaluate(this->LocalGenerator, config, head, &dagChecker, nullptr,
this->LinkerLanguage);
bool const checkCMP0027 = evaluated != entry.Value;
- cmExpandList(evaluated, llibs);
+ cmList llibs(evaluated);
if (cge->GetHadHeadSensitiveCondition()) {
impl.HadHeadSensitiveCondition = true;
}
@@ -8262,7 +8261,7 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries(
impl.HadLinkLanguageSensitiveCondition = true;
}
- for (std::string const& lib : llibs) {
+ for (auto const& lib : llibs) {
if (this->IsLinkLookupScope(lib, lg)) {
continue;
}
@@ -8430,16 +8429,16 @@ bool cmGeneratorTarget::HasPackageReferences() const
std::vector<std::string> cmGeneratorTarget::GetPackageReferences() const
{
- std::vector<std::string> packageReferences;
+ cmList packageReferences;
if (this->IsInBuildSystem()) {
if (cmValue vsPackageReferences =
this->GetProperty("VS_PACKAGE_REFERENCES")) {
- cmExpandList(*vsPackageReferences, packageReferences);
+ packageReferences.assign(*vsPackageReferences);
}
}
- return packageReferences;
+ return std::move(packageReferences.data());
}
std::string cmGeneratorTarget::GetPDBDirectory(const std::string& config) const
@@ -8544,6 +8543,30 @@ bool cmGeneratorTarget::IsLinkable() const
this->IsExecutableWithExports());
}
+bool cmGeneratorTarget::HasLinkDependencyFile(std::string const& config) const
+{
+ if (this->GetType() != cmStateEnums::EXECUTABLE &&
+ this->GetType() != cmStateEnums::SHARED_LIBRARY &&
+ this->GetType() != cmStateEnums::MODULE_LIBRARY) {
+ return false;
+ }
+
+ if (this->Target->GetProperty("LINK_DEPENDS_NO_SHARED").IsOn()) {
+ // Do not use the linker dependency file because it includes shared
+ // libraries as well
+ return false;
+ }
+
+ const std::string depsUseLinker{ "CMAKE_LINK_DEPENDS_USE_LINKER" };
+ auto linkLanguage = this->GetLinkerLanguage(config);
+ const std::string langDepsUseLinker{ cmStrCat("CMAKE_", linkLanguage,
+ "_LINK_DEPENDS_USE_LINKER") };
+
+ return (!this->Makefile->IsDefinitionSet(depsUseLinker) ||
+ this->Makefile->IsOn(depsUseLinker)) &&
+ this->Makefile->IsOn(langDepsUseLinker);
+}
+
bool cmGeneratorTarget::IsFrameworkOnApple() const
{
return this->Target->IsFrameworkOnApple();
@@ -8638,7 +8661,7 @@ bool cmGeneratorTarget::AddHeaderSetVerification()
const bool all = verifyValue.IsEmpty();
std::set<std::string> verifySet;
if (!all) {
- auto verifyList = cmExpandedList(verifyValue);
+ cmList verifyList{ verifyValue };
verifySet.insert(verifyList.begin(), verifyList.end());
}
@@ -8651,7 +8674,7 @@ bool cmGeneratorTarget::AddHeaderSetVerification()
std::set<cmFileSet*> fileSets;
for (auto const& entry : interfaceFileSetEntries) {
- for (auto const& name : cmExpandedList(entry.Value)) {
+ for (auto const& name : cmList{ entry.Value }) {
if (all || verifySet.count(name)) {
fileSets.insert(this->Target->GetFileSet(name));
verifySet.erase(name);
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 87227fd29c..78945c3fa9 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -805,6 +805,9 @@ public:
/** Return whether this target may be used to link another target. */
bool IsLinkable() const;
+ /** Return whether the link step generates a dependency file. */
+ bool HasLinkDependencyFile(std::string const& config) const;
+
/** Return whether this target is a shared library Framework on
Apple. */
bool IsFrameworkOnApple() const;
@@ -912,6 +915,8 @@ public:
std::vector<std::string> GetGeneratedISPCObjects(
std::string const& config) const;
+ void AddSystemIncludeDirectory(std::string const& inc,
+ std::string const& lang);
bool AddHeaderSetVerification();
std::string GenerateHeaderSetVerificationFile(
cmSourceFile& source, const std::string& dir,
diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx
index 8471dfe615..a1e0650d20 100644
--- a/Source/cmGhsMultiTargetGenerator.cxx
+++ b/Source/cmGhsMultiTargetGenerator.cxx
@@ -17,6 +17,7 @@
#include "cmGeneratorTarget.h"
#include "cmGlobalGhsMultiGenerator.h"
#include "cmLinkLineComputer.h" // IWYU pragma: keep
+#include "cmList.h"
#include "cmLocalGenerator.h"
#include "cmLocalGhsMultiGenerator.h"
#include "cmMakefile.h"
@@ -484,7 +485,7 @@ void cmGhsMultiTargetGenerator::WriteSourceProperty(
{
cmValue prop = sf->GetProperty(propName);
if (prop) {
- std::vector<std::string> list = cmExpandedList(*prop);
+ cmList list{ *prop };
for (const std::string& p : list) {
fout << " " << propFlag << p << '\n';
}
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 3563a1a17d..040f500519 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -42,6 +42,7 @@
#include "cmInstallGenerator.h"
#include "cmInstallRuntimeDependencySet.h"
#include "cmLinkLineComputer.h"
+#include "cmList.h"
#include "cmLocalGenerator.h"
#include "cmMSVC60LinkLineComputer.h"
#include "cmMakefile.h"
@@ -238,10 +239,10 @@ void cmGlobalGenerator::ResolveLanguageCompiler(const std::string& lang,
this->GetCMakeInstance()->GetState()->GetInitializedCacheValue(langComp);
// Split compiler from arguments
- std::vector<std::string> cnameArgVec;
+ cmList cnameArgList;
if (cname && !cname->empty()) {
- cmExpandList(*cname, cnameArgVec);
- cname = cmValue(cnameArgVec.front());
+ cnameArgList.assign(*cname);
+ cname = cmValue(cnameArgList.front());
}
std::string changeVars;
@@ -670,7 +671,7 @@ void cmGlobalGenerator::EnableLanguage(
mf->GetState()->SetInTopLevelIncludes(true);
std::string includes =
mf->GetSafeDefinition("CMAKE_PROJECT_TOP_LEVEL_INCLUDES");
- std::vector<std::string> includesList = cmExpandedList(includes);
+ cmList includesList{ includes };
for (std::string const& setupFile : includesList) {
std::string absSetupFile = cmSystemTools::CollapseFullPath(
setupFile, mf->GetCurrentSourceDirectory());
@@ -1234,7 +1235,7 @@ void cmGlobalGenerator::SetLanguageEnabledMaps(const std::string& l,
std::string ignoreExtensionsVar =
std::string("CMAKE_") + std::string(l) + std::string("_IGNORE_EXTENSIONS");
std::string ignoreExts = mf->GetSafeDefinition(ignoreExtensionsVar);
- std::vector<std::string> extensionList = cmExpandedList(ignoreExts);
+ cmList extensionList{ ignoreExts };
for (std::string const& i : extensionList) {
this->IgnoreExtensions[i] = true;
}
@@ -1246,7 +1247,7 @@ void cmGlobalGenerator::FillExtensionToLanguageMap(const std::string& l,
std::string extensionsVar = std::string("CMAKE_") + std::string(l) +
std::string("_SOURCE_FILE_EXTENSIONS");
const std::string& exts = mf->GetSafeDefinition(extensionsVar);
- std::vector<std::string> extensionList = cmExpandedList(exts);
+ cmList extensionList{ exts };
for (std::string const& i : extensionList) {
this->ExtensionToLanguage[i] = l;
}
@@ -1887,10 +1888,9 @@ void cmGlobalGenerator::FinalizeTargetConfiguration()
"CMAKE_" + li + "_STANDARD_INCLUDE_DIRECTORIES";
std::string const& standardIncludesStr =
mf->GetSafeDefinition(standardIncludesVar);
- std::vector<std::string> standardIncludesVec =
- cmExpandedList(standardIncludesStr);
- standardIncludesSet.insert(standardIncludesVec.begin(),
- standardIncludesVec.end());
+ cmList standardIncludesList{ standardIncludesStr };
+ standardIncludesSet.insert(standardIncludesList.begin(),
+ standardIncludesList.end());
}
mf->AddSystemIncludeDirectories(standardIncludesSet);
}
@@ -1985,7 +1985,6 @@ void cmGlobalGenerator::CheckTargetProperties()
notFoundMap[varName] = text;
}
}
- std::vector<std::string> incs;
cmValue incDirProp = target.second.GetProperty("INCLUDE_DIRECTORIES");
if (!incDirProp) {
continue;
@@ -1994,7 +1993,7 @@ void cmGlobalGenerator::CheckTargetProperties()
std::string incDirs = cmGeneratorExpression::Preprocess(
*incDirProp, cmGeneratorExpression::StripAllGeneratorExpressions);
- cmExpandList(incDirs, incs);
+ cmList incs(incDirs);
for (std::string const& incDir : incs) {
if (incDir.size() > 9 && cmIsNOTFOUND(incDir)) {
@@ -2789,11 +2788,9 @@ void cmGlobalGenerator::AddGlobalTarget_Test(
cmCustomCommandLine singleLine;
singleLine.push_back(cmSystemTools::GetCTestCommand());
singleLine.push_back("--force-new-ctest-process");
- std::vector<std::string> args;
- if (mf->GetDefExpandList("CMAKE_CTEST_ARGUMENTS", args)) {
- for (auto const& arg : args) {
- singleLine.push_back(arg);
- }
+ cmList args(mf->GetDefinition("CMAKE_CTEST_ARGUMENTS"));
+ for (auto const& arg : args) {
+ singleLine.push_back(arg);
}
if (cmNonempty(cmakeCfgIntDir) && cmakeCfgIntDir[0] != '.') {
singleLine.push_back("-C");
@@ -3348,12 +3345,12 @@ void cmGlobalGenerator::WriteSummary(cmGeneratorTarget* target)
cmSystemTools::MakeDirectory(dir);
cmGeneratedFileStream fout(file);
- std::vector<std::string> labels;
+ cmList labels;
// List the target-wide labels. All sources in the target get
// these labels.
if (targetLabels) {
- cmExpandList(*targetLabels, labels);
+ labels.assign(*targetLabels);
if (!labels.empty()) {
fout << "# Target labels\n";
for (std::string const& l : labels) {
@@ -3364,27 +3361,27 @@ void cmGlobalGenerator::WriteSummary(cmGeneratorTarget* target)
}
// List directory labels
- std::vector<std::string> directoryLabelsList;
- std::vector<std::string> cmakeDirectoryLabelsList;
+ cmList directoryLabelsList;
+ cmList cmakeDirectoryLabelsList;
if (directoryLabels) {
- cmExpandList(*directoryLabels, directoryLabelsList);
+ directoryLabelsList.assign(*directoryLabels);
}
if (cmakeDirectoryLabels) {
- cmExpandList(*cmakeDirectoryLabels, cmakeDirectoryLabelsList);
+ cmakeDirectoryLabelsList.assign(*cmakeDirectoryLabels);
}
if (!directoryLabelsList.empty() || !cmakeDirectoryLabelsList.empty()) {
fout << "# Directory labels\n";
}
- for (std::string const& li : directoryLabelsList) {
+ for (auto const& li : directoryLabelsList) {
fout << " " << li << "\n";
lj_target_labels.append(li);
}
- for (std::string const& li : cmakeDirectoryLabelsList) {
+ for (auto const& li : cmakeDirectoryLabelsList) {
fout << " " << li << "\n";
lj_target_labels.append(li);
}
@@ -3405,10 +3402,9 @@ void cmGlobalGenerator::WriteSummary(cmGeneratorTarget* target)
fout << sfp << "\n";
lj_source["file"] = sfp;
if (cmValue svalue = sf->GetProperty("LABELS")) {
- labels.clear();
Json::Value& lj_source_labels = lj_source["labels"] = Json::arrayValue;
- cmExpandList(*svalue, labels);
- for (std::string const& label : labels) {
+ labels.assign(*svalue);
+ for (auto const& label : labels) {
fout << " " << label << "\n";
lj_source_labels.append(label);
}
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index dde364886e..79fe52c193 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -546,6 +546,8 @@ public:
return cm::nullopt;
}
+ virtual bool SupportsLinkerDependencyFile() const { return false; }
+
std::string GetSharedLibFlagsForLanguage(std::string const& lang) const;
/** Generate an <output>.rule file path for a given command output. */
diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx
index b1f2b4a393..578e805332 100644
--- a/Source/cmGlobalGhsMultiGenerator.cxx
+++ b/Source/cmGlobalGhsMultiGenerator.cxx
@@ -18,6 +18,7 @@
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
#include "cmGhsMultiGpj.h"
+#include "cmList.h"
#include "cmLocalGenerator.h"
#include "cmLocalGhsMultiGenerator.h"
#include "cmMakefile.h"
@@ -531,7 +532,7 @@ void cmGlobalGhsMultiGenerator::WriteMacros(std::ostream& fout,
fout << "macro PROJ_NAME=" << root->GetProjectName() << '\n';
cmValue ghsGpjMacros = root->GetMakefile()->GetDefinition("GHS_GPJ_MACROS");
if (ghsGpjMacros) {
- std::vector<std::string> expandedList = cmExpandedList(*ghsGpjMacros);
+ cmList expandedList{ *ghsGpjMacros };
for (std::string const& arg : expandedList) {
fout << "macro " << arg << '\n';
}
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 0c28776a82..84c85e07e6 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -32,6 +32,7 @@
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmLinkLineComputer.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmLocalNinjaGenerator.h"
@@ -3031,19 +3032,17 @@ void cmGlobalNinjaMultiGenerator::GetQtAutoGenConfigs(
bool cmGlobalNinjaMultiGenerator::InspectConfigTypeVariables()
{
- std::vector<std::string> configsVec;
- cmExpandList(
- this->Makefiles.front()->GetSafeDefinition("CMAKE_CONFIGURATION_TYPES"),
- configsVec);
- if (configsVec.empty()) {
- configsVec.emplace_back();
+ cmList configsList{ this->Makefiles.front()->GetDefinition(
+ "CMAKE_CONFIGURATION_TYPES") };
+ if (configsList.empty()) {
+ configsList.emplace_back();
}
- std::set<std::string> configs(configsVec.cbegin(), configsVec.cend());
+ std::set<std::string> configs(configsList.cbegin(), configsList.cend());
this->DefaultFileConfig =
this->Makefiles.front()->GetSafeDefinition("CMAKE_DEFAULT_BUILD_TYPE");
if (this->DefaultFileConfig.empty()) {
- this->DefaultFileConfig = configsVec.front();
+ this->DefaultFileConfig = configsList.front();
}
if (!configs.count(this->DefaultFileConfig)) {
std::ostringstream msg;
@@ -3055,11 +3054,9 @@ bool cmGlobalNinjaMultiGenerator::InspectConfigTypeVariables()
return false;
}
- std::vector<std::string> crossConfigsVec;
- cmExpandList(
- this->Makefiles.front()->GetSafeDefinition("CMAKE_CROSS_CONFIGS"),
- crossConfigsVec);
- auto crossConfigs = ListSubsetWithAll(configs, configs, crossConfigsVec);
+ cmList crossConfigsList{ this->Makefiles.front()->GetSafeDefinition(
+ "CMAKE_CROSS_CONFIGS") };
+ auto crossConfigs = ListSubsetWithAll(configs, configs, crossConfigsList);
if (!crossConfigs) {
std::ostringstream msg;
msg << "CMAKE_CROSS_CONFIGS is not a subset of "
@@ -3086,12 +3083,11 @@ bool cmGlobalNinjaMultiGenerator::InspectConfigTypeVariables()
return false;
}
- std::vector<std::string> defaultConfigsVec;
- cmExpandList(defaultConfigsString, defaultConfigsVec);
+ cmList defaultConfigsList(defaultConfigsString);
if (!this->DefaultFileConfig.empty()) {
auto defaultConfigs =
ListSubsetWithAll(this->GetCrossConfigs(this->DefaultFileConfig),
- this->CrossConfigs, defaultConfigsVec);
+ this->CrossConfigs, defaultConfigsList);
if (!defaultConfigs) {
std::ostringstream msg;
msg << "CMAKE_DEFAULT_CONFIGS is not a subset of CMAKE_CROSS_CONFIGS";
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index bd541685c9..bfbe57f22b 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -236,6 +236,8 @@ public:
return cmDepfileFormat::GccDepfile;
}
+ bool SupportsLinkerDependencyFile() const override { return true; }
+
virtual cmGeneratedFileStream* GetImplFileStream(
const std::string& /*config*/) const
{
diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h
index 214ba2af51..760679a051 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.h
+++ b/Source/cmGlobalUnixMakefileGenerator3.h
@@ -99,6 +99,12 @@ public:
*/
bool SupportsCustomCommandDepfile() const override { return true; }
+ /**
+ * Utilized to determine if this generator
+ * supports linker dependency file.
+ */
+ bool SupportsLinkerDependencyFile() const override { return true; }
+
/** Get the documentation entry for this generator. */
static cmDocumentationEntry GetDocumentation();
diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx
index de139241ed..bcb26cc1cb 100644
--- a/Source/cmGlobalVisualStudio71Generator.cxx
+++ b/Source/cmGlobalVisualStudio71Generator.cxx
@@ -8,6 +8,7 @@
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmGlobalVisualStudioGenerator.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
@@ -205,12 +206,12 @@ void cmGlobalVisualStudio71Generator::WriteProjectConfigurations(
!platformMapping.empty() ? platformMapping : this->GetPlatformName();
std::string guid = this->GetGUID(name);
for (std::string const& i : configs) {
- std::vector<std::string> mapConfig;
+ cmList mapConfig;
const char* dstConfig = i.c_str();
if (target.GetProperty("EXTERNAL_MSPROJECT")) {
if (cmValue m = target.GetProperty("MAP_IMPORTED_CONFIG_" +
cmSystemTools::UpperCase(i))) {
- cmExpandList(*m, mapConfig);
+ mapConfig.assign(*m);
if (!mapConfig.empty()) {
dstConfig = mapConfig[0].c_str();
}
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
index 5de3a55939..694698e559 100644
--- a/Source/cmGlobalVisualStudio7Generator.cxx
+++ b/Source/cmGlobalVisualStudio7Generator.cxx
@@ -17,6 +17,7 @@
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
+#include "cmList.h"
#include "cmLocalGenerator.h"
#include "cmLocalVisualStudio7Generator.h"
#include "cmMakefile.h"
@@ -580,7 +581,7 @@ void cmGlobalVisualStudio7Generator::WriteSLNGlobalSections(
}
fout << "\tGlobalSection(" << name << ") = " << sectionType << "\n";
cmValue p = root->GetMakefile()->GetProperty(it);
- std::vector<std::string> keyValuePairs = cmExpandedList(p ? *p : "");
+ cmList keyValuePairs{ *p };
for (std::string const& itPair : keyValuePairs) {
const std::string::size_type posEqual = itPair.find('=');
if (posEqual != std::string::npos) {
diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx
index 2aba46fe2c..819bb09b1a 100644
--- a/Source/cmGlobalVisualStudio8Generator.cxx
+++ b/Source/cmGlobalVisualStudio8Generator.cxx
@@ -20,6 +20,7 @@
#include "cmGlobalGenerator.h"
#include "cmGlobalVisualStudio7Generator.h"
#include "cmGlobalVisualStudioGenerator.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmLocalVisualStudio7Generator.h"
@@ -262,6 +263,33 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
cmTarget* tgt = lg.AddUtilityCommand(CMAKE_CHECK_BUILD_SYSTEM_TARGET, false,
std::move(cc));
+ // Collect the input files used to generate all targets in this
+ // project.
+ std::vector<std::string> listFiles;
+ for (const auto& gen : generators) {
+ cm::append(listFiles, gen->GetMakefile()->GetListFiles());
+ }
+ // Sort the list of input files and remove duplicates.
+ std::sort(listFiles.begin(), listFiles.end(), std::less<std::string>());
+ auto new_end = std::unique(listFiles.begin(), listFiles.end());
+ listFiles.erase(new_end, listFiles.end());
+
+ // Add all cmake input files which are used by the project
+ // so Visual Studio does not close them when reloading it.
+ for (const std::string& listFile : listFiles) {
+ if (listFile.find("/CMakeFiles/") != std::string::npos) {
+ continue;
+ }
+ if (!cmSystemTools::IsSubDirectory(listFile,
+ lg.GetMakefile()->GetHomeDirectory()) &&
+ !cmSystemTools::IsSubDirectory(
+ listFile, lg.GetMakefile()->GetHomeOutputDirectory())) {
+ continue;
+ }
+
+ tgt->AddSource(listFile);
+ }
+
auto ptr = cm::make_unique<cmGeneratorTarget>(tgt, &lg);
auto* gt = ptr.get();
lg.AddGeneratorTarget(std::move(ptr));
@@ -295,13 +323,6 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
// The custom rule runs cmake so set UTF-8 pipes.
bool stdPipesUTF8 = true;
- // Collect the input files used to generate all targets in this
- // project.
- std::vector<std::string> listFiles;
- for (const auto& gen : generators) {
- cm::append(listFiles, gen->GetMakefile()->GetListFiles());
- }
-
// Add a custom prebuild target to run the VerifyGlobs script.
cmake* cm = this->GetCMakeInstance();
if (cm->DoWriteGlobVerifyTarget()) {
@@ -325,11 +346,6 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
listFiles.push_back(cm->GetGlobVerifyStamp());
}
- // Sort the list of input files and remove duplicates.
- std::sort(listFiles.begin(), listFiles.end(), std::less<std::string>());
- auto new_end = std::unique(listFiles.begin(), listFiles.end());
- listFiles.erase(new_end, listFiles.end());
-
// Create a rule to re-run CMake.
std::string argS = cmStrCat("-S", lg.GetSourceDirectory());
std::string argB = cmStrCat("-B", lg.GetBinaryDirectory());
@@ -396,12 +412,12 @@ void cmGlobalVisualStudio8Generator::WriteProjectConfigurations(
{
std::string guid = this->GetGUID(name);
for (std::string const& i : configs) {
- std::vector<std::string> mapConfig;
+ cmList mapConfig;
const char* dstConfig = i.c_str();
if (target.GetProperty("EXTERNAL_MSPROJECT")) {
if (cmValue m = target.GetProperty("MAP_IMPORTED_CONFIG_" +
cmSystemTools::UpperCase(i))) {
- cmExpandList(*m, mapConfig);
+ mapConfig.assign(*m);
if (!mapConfig.empty()) {
dstConfig = mapConfig[0].c_str();
}
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 139635797f..60f46e5aca 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -30,6 +30,7 @@
#include "cmGeneratorTarget.h"
#include "cmGlobalGeneratorFactory.h"
#include "cmLinkItem.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmLocalXCodeGenerator.h"
@@ -1027,7 +1028,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFile(
cmValue extraFileAttributes = sf->GetProperty("XCODE_FILE_ATTRIBUTES");
if (extraFileAttributes) {
// Expand the list of attributes.
- std::vector<std::string> attributes = cmExpandedList(*extraFileAttributes);
+ cmList attributes{ *extraFileAttributes };
// Store the attributes.
for (const auto& attribute : attributes) {
@@ -1171,7 +1172,7 @@ template <class T>
std::string GetTargetObjectDirArch(T const& target,
const std::string& defaultVal)
{
- auto archs = cmExpandedList(target.GetSafeProperty("OSX_ARCHITECTURES"));
+ cmList archs{ target.GetSafeProperty("OSX_ARCHITECTURES") };
if (archs.size() > 1) {
return "$(CURRENT_ARCH)";
} else if (archs.size() == 1) {
@@ -3127,8 +3128,8 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateUtilityTarget(
std::string cmGlobalXCodeGenerator::AddConfigurations(cmXCodeObject* target,
cmGeneratorTarget* gtgt)
{
- std::vector<std::string> const configVector = cmExpandedList(
- this->CurrentMakefile->GetRequiredDefinition("CMAKE_CONFIGURATION_TYPES"));
+ cmList const configList{ this->CurrentMakefile->GetRequiredDefinition(
+ "CMAKE_CONFIGURATION_TYPES") };
cmXCodeObject* configlist =
this->CreateObject(cmXCodeObject::XCConfigurationList);
cmXCodeObject* buildConfigurations =
@@ -3140,7 +3141,7 @@ std::string cmGlobalXCodeGenerator::AddConfigurations(cmXCodeObject* target,
configlist->SetComment(comment);
target->AddAttribute("buildConfigurationList",
this->CreateObjectReference(configlist));
- for (auto const& i : configVector) {
+ for (auto const& i : configList) {
cmXCodeObject* config =
this->CreateObject(cmXCodeObject::XCBuildConfiguration);
buildConfigurations->AddObject(config);
@@ -3153,12 +3154,12 @@ std::string cmGlobalXCodeGenerator::AddConfigurations(cmXCodeObject* target,
this->CreateTargetXCConfigSettings(gtgt, config, i);
}
- if (!configVector.empty()) {
+ if (!configList.empty()) {
configlist->AddAttribute("defaultConfigurationName",
- this->CreateString(configVector[0]));
+ this->CreateString(configList[0]));
configlist->AddAttribute("defaultConfigurationIsVisible",
this->CreateString("0"));
- return configVector[0];
+ return configList[0];
}
return "";
}
@@ -4029,7 +4030,7 @@ void cmGlobalXCodeGenerator::AddEmbeddedObjects(
this->CreateString("0"));
cmXCodeObject* buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
// Collect all embedded frameworks and dylibs and add them to build phase
- std::vector<std::string> relFiles = cmExpandedList(*files);
+ cmList relFiles{ *files };
for (std::string const& relFile : relFiles) {
cmXCodeObject* buildFile{ nullptr };
std::string filePath = relFile;
@@ -4599,13 +4600,12 @@ std::string cmGlobalXCodeGenerator::GetTargetTempDir(
void cmGlobalXCodeGenerator::ComputeArchitectures(cmMakefile* mf)
{
this->Architectures.clear();
- cmValue sysroot = mf->GetDefinition("CMAKE_OSX_SYSROOT");
- if (sysroot) {
- mf->GetDefExpandList("CMAKE_OSX_ARCHITECTURES", this->Architectures);
- }
+ cmList::append(this->Architectures,
+ mf->GetDefinition("CMAKE_OSX_ARCHITECTURES"));
if (this->Architectures.empty()) {
- mf->GetDefExpandList("_CMAKE_APPLE_ARCHS_DEFAULT", this->Architectures);
+ cmList::append(this->Architectures,
+ mf->GetDefinition("_CMAKE_APPLE_ARCHS_DEFAULT"));
}
if (this->Architectures.empty()) {
@@ -5008,7 +5008,7 @@ void cmGlobalXCodeGenerator::AppendDefines(BuildObjectListOrString& defs,
}
// Expand the list of definitions.
- std::vector<std::string> defines = cmExpandedList(defines_list);
+ cmList defines{ defines_list };
// Store the definitions in the string.
this->AppendDefines(defs, defines, dflag);
diff --git a/Source/cmGraphVizWriter.cxx b/Source/cmGraphVizWriter.cxx
index 2bb438d7d4..a8a7abb087 100644
--- a/Source/cmGraphVizWriter.cxx
+++ b/Source/cmGraphVizWriter.cxx
@@ -15,6 +15,7 @@
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmLinkItem.h"
+#include "cmList.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmState.h"
@@ -255,9 +256,8 @@ void cmGraphVizWriter::ReadSettings(
this->TargetsToIgnoreRegex.clear();
if (!ignoreTargetsRegexes.empty()) {
- std::vector<std::string> ignoreTargetsRegExVector =
- cmExpandedList(ignoreTargetsRegexes);
- for (std::string const& currentRegexString : ignoreTargetsRegExVector) {
+ cmList ignoreTargetsRegExList{ ignoreTargetsRegexes };
+ for (std::string const& currentRegexString : ignoreTargetsRegExList) {
cmsys::RegularExpression currentRegex;
if (!currentRegex.compile(currentRegexString)) {
std::cerr << "Could not compile bad regex \"" << currentRegexString
diff --git a/Source/cmIDEOptions.cxx b/Source/cmIDEOptions.cxx
index 9468d4abdb..f94faf88b8 100644
--- a/Source/cmIDEOptions.cxx
+++ b/Source/cmIDEOptions.cxx
@@ -12,6 +12,7 @@
#include "cmsys/String.h"
#include "cmIDEFlagTable.h"
+#include "cmList.h"
#include "cmStringAlgorithms.h"
cmIDEOptions::cmIDEOptions()
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx
index 40230d9fb6..7f5f15b3c9 100644
--- a/Source/cmInstallCommand.cxx
+++ b/Source/cmInstallCommand.cxx
@@ -39,6 +39,7 @@
#include "cmInstallRuntimeDependencySetGenerator.h"
#include "cmInstallScriptGenerator.h"
#include "cmInstallTargetGenerator.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
@@ -1079,7 +1080,7 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
if (createInstallGeneratorsForTargetFileSets && !namelinkOnly) {
cmValue files = target.GetProperty("PRIVATE_HEADER");
if (cmNonempty(files)) {
- std::vector<std::string> relFiles = cmExpandedList(*files);
+ cmList relFiles{ *files };
std::vector<std::string> absFiles;
if (!helper.MakeFilesFullPath("PRIVATE_HEADER", relFiles, absFiles)) {
return false;
@@ -1101,7 +1102,7 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
files = target.GetProperty("PUBLIC_HEADER");
if (cmNonempty(files)) {
- std::vector<std::string> relFiles = cmExpandedList(*files);
+ cmList relFiles{ *files };
std::vector<std::string> absFiles;
if (!helper.MakeFilesFullPath("PUBLIC_HEADER", relFiles, absFiles)) {
return false;
@@ -1123,7 +1124,7 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
files = target.GetProperty("RESOURCE");
if (cmNonempty(files)) {
- std::vector<std::string> relFiles = cmExpandedList(*files);
+ cmList relFiles{ *files };
std::vector<std::string> absFiles;
if (!helper.MakeFilesFullPath("RESOURCE", relFiles, absFiles)) {
return false;
@@ -1145,8 +1146,8 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
if (!namelinkOnly) {
for (std::size_t i = 0; i < fileSetArgs.size(); i++) {
if (auto* fileSet = target.GetFileSet(fileSetArgs[i].GetFileSet())) {
- auto interfaceFileSetEntries = cmExpandedList(target.GetSafeProperty(
- cmTarget::GetInterfaceFileSetsPropertyName(fileSet->GetType())));
+ cmList interfaceFileSetEntries{ target.GetSafeProperty(
+ cmTarget::GetInterfaceFileSetsPropertyName(fileSet->GetType())) };
if (std::find(interfaceFileSetEntries.begin(),
interfaceFileSetEntries.end(),
fileSetArgs[i].GetFileSet()) !=
diff --git a/Source/cmInstallDirectoryGenerator.cxx b/Source/cmInstallDirectoryGenerator.cxx
index d358763c71..6aa99102bd 100644
--- a/Source/cmInstallDirectoryGenerator.cxx
+++ b/Source/cmInstallDirectoryGenerator.cxx
@@ -6,6 +6,7 @@
#include "cmGeneratorExpression.h"
#include "cmInstallType.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
@@ -53,17 +54,16 @@ bool cmInstallDirectoryGenerator::Compute(cmLocalGenerator* lg)
std::vector<std::string> cmInstallDirectoryGenerator::GetDirectories(
std::string const& config) const
{
- std::vector<std::string> directories;
+ cmList directories;
if (this->ActionsPerConfig) {
for (std::string const& f : this->Directories) {
- cmExpandList(
- cmGeneratorExpression::Evaluate(f, this->LocalGenerator, config),
- directories);
+ directories.append(
+ cmGeneratorExpression::Evaluate(f, this->LocalGenerator, config));
}
} else {
directories = this->Directories;
}
- return directories;
+ return std::move(directories.data());
}
void cmInstallDirectoryGenerator::GenerateScriptActions(std::ostream& os,
diff --git a/Source/cmInstallFilesGenerator.cxx b/Source/cmInstallFilesGenerator.cxx
index 18a852b210..43dc656a75 100644
--- a/Source/cmInstallFilesGenerator.cxx
+++ b/Source/cmInstallFilesGenerator.cxx
@@ -6,8 +6,8 @@
#include "cmGeneratorExpression.h"
#include "cmInstallType.h"
+#include "cmList.h"
#include "cmListFileCache.h"
-#include "cmStringAlgorithms.h"
class cmLocalGenerator;
@@ -69,17 +69,15 @@ std::string cmInstallFilesGenerator::GetRename(std::string const& config) const
std::vector<std::string> cmInstallFilesGenerator::GetFiles(
std::string const& config) const
{
- std::vector<std::string> files;
if (this->ActionsPerConfig) {
+ cmList files;
for (std::string const& f : this->Files) {
- cmExpandList(
- cmGeneratorExpression::Evaluate(f, this->LocalGenerator, config),
- files);
+ files.append(
+ cmGeneratorExpression::Evaluate(f, this->LocalGenerator, config));
}
- } else {
- files = this->Files;
+ return std::move(files.data());
}
- return files;
+ return this->Files;
}
void cmInstallFilesGenerator::AddFilesInstallRule(
diff --git a/Source/cmInstalledFile.cxx b/Source/cmInstalledFile.cxx
index 5bf8320bbb..381c91bac1 100644
--- a/Source/cmInstalledFile.cxx
+++ b/Source/cmInstalledFile.cxx
@@ -5,9 +5,9 @@
#include <utility>
#include "cmGeneratorExpression.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
-#include "cmStringAlgorithms.h"
#include "cmValue.h"
cmInstalledFile::cmInstalledFile() = default;
@@ -97,12 +97,11 @@ bool cmInstalledFile::GetPropertyAsBool(const std::string& prop) const
return isSet && cmIsOn(value);
}
-void cmInstalledFile::GetPropertyAsList(const std::string& prop,
- std::vector<std::string>& list) const
+std::vector<std::string> cmInstalledFile::GetPropertyAsList(
+ const std::string& prop) const
{
std::string value;
this->GetProperty(prop, value);
- list.clear();
- cmExpandList(value, list);
+ return std::move(cmList(value).data());
}
diff --git a/Source/cmInstalledFile.h b/Source/cmInstalledFile.h
index 82474f5203..373c34938a 100644
--- a/Source/cmInstalledFile.h
+++ b/Source/cmInstalledFile.h
@@ -59,8 +59,7 @@ public:
bool GetPropertyAsBool(const std::string& prop) const;
- void GetPropertyAsList(const std::string& prop,
- std::vector<std::string>& list) const;
+ std::vector<std::string> GetPropertyAsList(const std::string& prop) const;
void SetName(cmMakefile* mf, const std::string& name);
diff --git a/Source/cmLDConfigLDConfigTool.cxx b/Source/cmLDConfigLDConfigTool.cxx
index cce6178dae..0752b3353d 100644
--- a/Source/cmLDConfigLDConfigTool.cxx
+++ b/Source/cmLDConfigLDConfigTool.cxx
@@ -9,9 +9,9 @@
#include "cmsys/RegularExpression.hxx"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmRuntimeDependencyArchive.h"
-#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmUVProcessChain.h"
@@ -34,7 +34,7 @@ bool cmLDConfigLDConfigTool::GetLDConfigPaths(std::vector<std::string>& paths)
}
}
- std::vector<std::string> ldConfigCommand = cmExpandedList(ldConfigPath);
+ cmList ldConfigCommand{ ldConfigPath };
ldConfigCommand.emplace_back("-v");
ldConfigCommand.emplace_back("-N"); // Don't rebuild the cache.
ldConfigCommand.emplace_back("-X"); // Don't update links.
diff --git a/Source/cmList.cxx b/Source/cmList.cxx
index bf5a65459a..022fcd2b4c 100644
--- a/Source/cmList.cxx
+++ b/Source/cmList.cxx
@@ -287,18 +287,20 @@ protected:
: TransformSelector(std::move(tag))
{
}
- TransformSelectorIndexes(std::string&& tag, std::vector<int> const& indexes)
+ TransformSelectorIndexes(std::string&& tag,
+ std::vector<index_type> const& indexes)
: TransformSelector(std::move(tag))
, Indexes(indexes)
{
}
- TransformSelectorIndexes(std::string&& tag, std::vector<int>&& indexes)
+ TransformSelectorIndexes(std::string&& tag,
+ std::vector<index_type>&& indexes)
: TransformSelector(std::move(tag))
, Indexes(indexes)
{
}
- int NormalizeIndex(index_type index, std::size_t count)
+ index_type NormalizeIndex(index_type index, std::size_t count)
{
if (index < 0) {
index = static_cast<index_type>(count) + index;
@@ -338,7 +340,7 @@ public:
class TransformSelectorFor : public TransformSelectorIndexes
{
public:
- TransformSelectorFor(int start, int stop, int step)
+ TransformSelectorFor(index_type start, index_type stop, index_type step)
: TransformSelectorIndexes("FOR")
, Start(start)
, Stop(stop)
@@ -369,7 +371,7 @@ public:
auto start = this->Start;
auto step = this->Step;
std::generate(this->Indexes.begin(), this->Indexes.end(),
- [&start, step]() -> int {
+ [&start, step]() -> index_type {
auto r = start;
start += step;
return r;
@@ -805,7 +807,7 @@ std::string cmList::join(cm::string_view glue) const
return cmJoin(this->Values, glue);
}
-std::string& cmList::append(cm::string_view value, std::string& list)
+std::string& cmList::append(std::string& list, cm::string_view value)
{
if (list.empty()) {
list = std::string(value);
@@ -816,7 +818,7 @@ std::string& cmList::append(cm::string_view value, std::string& list)
return list;
}
-std::string& cmList::prepend(cm::string_view value, std::string& list)
+std::string& cmList::prepend(std::string& list, cm::string_view value)
{
if (list.empty()) {
list = std::string(value);
@@ -835,18 +837,19 @@ cmList::size_type cmList::ComputeIndex(index_type pos, bool boundCheck) const
cmStrCat("index: ", pos, " out of range (0, 0)"));
}
+ auto index = pos;
if (!this->Values.empty()) {
auto length = this->Values.size();
- if (pos < 0) {
- pos = static_cast<index_type>(length) + pos;
+ if (index < 0) {
+ index = static_cast<index_type>(length) + index;
}
- if (pos < 0 || length <= static_cast<size_type>(pos)) {
+ if (index < 0 || length <= static_cast<size_type>(index)) {
throw std::out_of_range(cmStrCat("index: ", pos, " out of range (-",
this->Values.size(), ", ",
this->Values.size() - 1, ")"));
}
}
- return pos;
+ return index;
}
return pos < 0 ? this->Values.size() + pos : pos;
@@ -860,18 +863,19 @@ cmList::size_type cmList::ComputeInsertIndex(index_type pos,
cmStrCat("index: ", pos, " out of range (0, 0)"));
}
+ auto index = pos;
if (!this->Values.empty()) {
auto length = this->Values.size();
- if (pos < 0) {
- pos = static_cast<index_type>(length) + pos;
+ if (index < 0) {
+ index = static_cast<index_type>(length) + index;
}
- if (pos < 0 || length < static_cast<size_type>(pos)) {
+ if (index < 0 || length < static_cast<size_type>(index)) {
throw std::out_of_range(cmStrCat("index: ", pos, " out of range (-",
this->Values.size(), ", ",
this->Values.size(), ")"));
}
}
- return pos;
+ return index;
}
return pos < 0 ? this->Values.size() + pos : pos;
@@ -882,7 +886,7 @@ cmList cmList::GetItems(std::vector<index_type>&& indexes) const
cmList listItems;
for (auto index : indexes) {
- listItems.emplace_back(this->at(index));
+ listItems.emplace_back(this->get_item(index));
}
return listItems;
@@ -896,9 +900,10 @@ cmList& cmList::RemoveItems(std::vector<index_type>&& indexes)
// compute all indexes
std::vector<size_type> idx(indexes.size());
- std::transform(
- indexes.cbegin(), indexes.cend(), idx.begin(),
- [this](const index_type& index) { return this->ComputeIndex(index); });
+ std::transform(indexes.cbegin(), indexes.cend(), idx.begin(),
+ [this](const index_type& index) -> size_type {
+ return this->ComputeIndex(index);
+ });
std::sort(idx.begin(), idx.end(),
[](size_type l, size_type r) { return l > r; });
@@ -925,8 +930,8 @@ cmList& cmList::RemoveItems(std::vector<std::string>&& items)
}
cmList::container_type::iterator cmList::Insert(
- container_type::const_iterator pos, std::string&& value,
- container_type& container, ExpandElements expandElements,
+ container_type& container, container_type::const_iterator pos,
+ std::string&& value, ExpandElements expandElements,
EmptyElements emptyElements)
{
auto delta = std::distance(container.cbegin(), pos);
diff --git a/Source/cmList.h b/Source/cmList.h
index d994ad3890..d9ce9510c6 100644
--- a/Source/cmList.h
+++ b/Source/cmList.h
@@ -6,6 +6,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <algorithm>
+#include <cstdint>
#include <initializer_list>
#include <iterator>
#include <memory>
@@ -16,19 +17,25 @@
#include <vector>
#include <cm/string_view>
+#include <cm/type_traits>
+#include <cmext/iterator>
#include "cmValue.h"
/**
* CMake lists management
+ * A CMake list is a string where list elements are separated by the ';'
+ * character.
*
* For all operations, input arguments (single value like cm::string_view or
* multiple values specified through pair of iterators) are, by default,
* expanded. The expansion can be controlled by the cmList::ExpandElements
* option.
*
- * There is an exception to this rule. The following methods do not expand
- * their argument: cmList::push_back, cmList::emplace and cmList::emplace_back.
+ * There ate some exceptions to this rule:
+ * * When the input argument is a cmList instance, the value is not expanded.
+ * * The following methods do not expand their argument: cmList::push_back,
+ * cmList::emplace and cmList::emplace_back.
*/
class cmList
@@ -38,7 +45,7 @@ public:
using value_type = container_type::value_type;
using allocator_type = container_type::allocator_type;
- using index_type = int;
+ using index_type = std::intptr_t;
using size_type = container_type::size_type;
using difference_type = container_type::difference_type;
using reference = container_type::reference;
@@ -74,8 +81,18 @@ public:
this->assign(value, expandElements, emptyElements);
}
cmList(cm::string_view value, EmptyElements emptyElements)
+ : cmList(value, ExpandElements::Yes, emptyElements)
+ {
+ }
+ cmList(std::string const& value,
+ ExpandElements expandElements = ExpandElements::Yes,
+ EmptyElements emptyElements = EmptyElements::No)
+ {
+ this->assign(value, expandElements, emptyElements);
+ }
+ cmList(std::string const& value, EmptyElements emptyElements)
+ : cmList(value, ExpandElements::Yes, emptyElements)
{
- this->assign(value, ExpandElements::Yes, emptyElements);
}
cmList(cmValue list, ExpandElements expandElements = ExpandElements::Yes,
EmptyElements emptyElements = EmptyElements::No)
@@ -135,6 +152,11 @@ public:
this->assign(value);
return *this;
}
+ cmList& operator=(std::string const& value)
+ {
+ this->assign(value);
+ return *this;
+ }
cmList& operator=(cmValue value)
{
if (value) {
@@ -175,6 +197,17 @@ public:
{
this->assign(value, ExpandElements::Yes, emptyElements);
}
+ void assign(std::string const& value,
+ ExpandElements expandElements = ExpandElements::Yes,
+ EmptyElements emptyElements = EmptyElements::No)
+ {
+ this->clear();
+ this->append(value, expandElements, emptyElements);
+ }
+ void assign(std::string const& value, EmptyElements emptyElements)
+ {
+ this->assign(value, ExpandElements::Yes, emptyElements);
+ }
void assign(cmValue value,
ExpandElements expandElements = ExpandElements::Yes,
EmptyElements emptyElements = EmptyElements::No)
@@ -204,17 +237,17 @@ public:
this->assign(first, last, ExpandElements::Yes, emptyElements);
}
void assign(const cmList& init,
- ExpandElements expandElements = ExpandElements::Yes,
+ ExpandElements expandElements = ExpandElements::No,
EmptyElements emptyElements = EmptyElements::No)
{
this->assign(init.begin(), init.end(), expandElements, emptyElements);
}
void assign(const cmList& init, EmptyElements emptyElements)
{
- this->assign(init, ExpandElements::Yes, emptyElements);
+ this->assign(init, ExpandElements::No, emptyElements);
}
void assign(cmList&& init,
- ExpandElements expandElements = ExpandElements::Yes,
+ ExpandElements expandElements = ExpandElements::No,
EmptyElements emptyElements = EmptyElements::No)
{
this->assign(std::make_move_iterator(init.begin()),
@@ -224,7 +257,7 @@ public:
}
void assign(cmList&& init, EmptyElements emptyElements)
{
- this->assign(std::move(init), ExpandElements::Yes, emptyElements);
+ this->assign(std::move(init), ExpandElements::No, emptyElements);
}
void assign(const container_type& init,
ExpandElements expandElements = ExpandElements::Yes,
@@ -265,24 +298,21 @@ public:
operator container_type&&() && noexcept { return std::move(this->Values); }
// Element access
- reference at(index_type pos)
+ reference at(size_type pos) { return this->Values.at(pos); }
+ const_reference at(size_type pos) const { return this->Values.at(pos); }
+
+ reference operator[](size_type pos) { return this->Values[pos]; }
+ const_reference operator[](size_type pos) const { return this->Values[pos]; }
+
+ reference get_item(index_type pos)
{
return this->Values.at(this->ComputeIndex(pos));
}
- const_reference at(index_type pos) const
+ const_reference get_item(index_type pos) const
{
return this->Values.at(this->ComputeIndex(pos));
}
- reference operator[](index_type pos)
- {
- return this->Values[this->ComputeIndex(pos, false)];
- }
- const_reference operator[](index_type pos) const
- {
- return this->Values[this->ComputeIndex(pos, false)];
- }
-
reference front() { return this->Values.front(); }
const_reference front() const { return this->Values.front(); }
@@ -361,7 +391,7 @@ public:
ExpandElements expandElements = ExpandElements::Yes,
EmptyElements emptyElements = EmptyElements::No)
{
- return cmList::Insert(pos, std::string(value), this->Values,
+ return cmList::Insert(this->Values, pos, std::string(value),
expandElements, emptyElements);
}
iterator insert(const_iterator pos, cm::string_view value,
@@ -369,6 +399,18 @@ public:
{
return this->insert(pos, value, ExpandElements::Yes, emptyElements);
}
+ iterator insert(const_iterator pos, std::string const& value,
+ ExpandElements expandElements = ExpandElements::Yes,
+ EmptyElements emptyElements = EmptyElements::No)
+ {
+ return cmList::Insert(this->Values, pos, value, expandElements,
+ emptyElements);
+ }
+ iterator insert(const_iterator pos, std::string const& value,
+ EmptyElements emptyElements)
+ {
+ return this->insert(pos, value, ExpandElements::Yes, emptyElements);
+ }
iterator insert(const_iterator pos, cmValue value,
ExpandElements expandElements = ExpandElements::Yes,
EmptyElements emptyElements = EmptyElements::No)
@@ -390,7 +432,7 @@ public:
ExpandElements expandElements = ExpandElements::Yes,
EmptyElements emptyElements = EmptyElements::No)
{
- return cmList::Insert(pos, first, last, this->Values, expandElements,
+ return cmList::Insert(this->Values, pos, first, last, expandElements,
emptyElements);
}
template <typename InputIterator>
@@ -400,7 +442,7 @@ public:
return this->insert(pos, first, last, ExpandElements::Yes, emptyElements);
}
iterator insert(const_iterator pos, const cmList& values,
- ExpandElements expandElements = ExpandElements::Yes,
+ ExpandElements expandElements = ExpandElements::No,
EmptyElements emptyElements = EmptyElements::No)
{
return this->insert(pos, values.begin(), values.end(), expandElements,
@@ -409,10 +451,10 @@ public:
iterator insert(const_iterator pos, const cmList& values,
EmptyElements emptyElements)
{
- return this->insert(pos, values, ExpandElements::Yes, emptyElements);
+ return this->insert(pos, values, ExpandElements::No, emptyElements);
}
iterator insert(const_iterator pos, cmList&& values,
- ExpandElements expandElements = ExpandElements::Yes,
+ ExpandElements expandElements = ExpandElements::No,
EmptyElements emptyElements = EmptyElements::No)
{
auto result = this->insert(pos, std::make_move_iterator(values.begin()),
@@ -425,7 +467,7 @@ public:
iterator insert(const_iterator pos, cmList&& values,
EmptyElements emptyElements)
{
- return this->insert(pos, std::move(values), ExpandElements::Yes,
+ return this->insert(pos, std::move(values), ExpandElements::No,
emptyElements);
}
iterator insert(const_iterator pos, const container_type& values,
@@ -472,6 +514,16 @@ public:
{
return this->append(value, ExpandElements::Yes, emptyElements);
}
+ iterator append(std::string const& value,
+ ExpandElements expandElements = ExpandElements::Yes,
+ EmptyElements emptyElements = EmptyElements::No)
+ {
+ return this->insert(this->cend(), value, expandElements, emptyElements);
+ }
+ iterator append(std::string const& value, EmptyElements emptyElements)
+ {
+ return this->append(value, ExpandElements::Yes, emptyElements);
+ }
iterator append(cmValue value,
ExpandElements expandElements = ExpandElements::Yes,
EmptyElements emptyElements = EmptyElements::No)
@@ -501,7 +553,7 @@ public:
return this->append(first, last, ExpandElements::Yes, emptyElements);
}
iterator append(const cmList& values,
- ExpandElements expandElements = ExpandElements::Yes,
+ ExpandElements expandElements = ExpandElements::No,
EmptyElements emptyElements = EmptyElements::No)
{
return this->append(values.begin(), values.end(), expandElements,
@@ -509,10 +561,10 @@ public:
}
iterator append(const cmList& values, EmptyElements emptyElements)
{
- return this->append(values, ExpandElements::Yes, emptyElements);
+ return this->append(values, ExpandElements::No, emptyElements);
}
iterator append(cmList&& values,
- ExpandElements expandElements = ExpandElements::Yes,
+ ExpandElements expandElements = ExpandElements::No,
EmptyElements emptyElements = EmptyElements::No)
{
auto result = this->append(std::make_move_iterator(values.begin()),
@@ -524,7 +576,7 @@ public:
}
iterator append(cmList&& values, EmptyElements emptyElements)
{
- return this->append(std::move(values), ExpandElements::Yes, emptyElements);
+ return this->append(std::move(values), ExpandElements::No, emptyElements);
}
iterator append(const container_type& values,
ExpandElements expandElements = ExpandElements::Yes,
@@ -567,6 +619,16 @@ public:
{
return this->prepend(value, ExpandElements::Yes, emptyElements);
}
+ iterator prepend(std::string const& value,
+ ExpandElements expandElements = ExpandElements::Yes,
+ EmptyElements emptyElements = EmptyElements::No)
+ {
+ return this->insert(this->cbegin(), value, expandElements, emptyElements);
+ }
+ iterator prepend(std::string const& value, EmptyElements emptyElements)
+ {
+ return this->prepend(value, ExpandElements::Yes, emptyElements);
+ }
iterator prepend(cmValue value,
ExpandElements expandElements = ExpandElements::Yes,
EmptyElements emptyElements = EmptyElements::No)
@@ -596,7 +658,7 @@ public:
return this->prepend(first, last, ExpandElements::Yes, emptyElements);
}
iterator prepend(const cmList& values,
- ExpandElements expandElements = ExpandElements::Yes,
+ ExpandElements expandElements = ExpandElements::No,
EmptyElements emptyElements = EmptyElements::No)
{
return this->prepend(values.begin(), values.end(), expandElements,
@@ -604,10 +666,10 @@ public:
}
iterator prepend(const cmList& values, EmptyElements emptyElements)
{
- return this->prepend(values, ExpandElements::Yes, emptyElements);
+ return this->prepend(values, ExpandElements::No, emptyElements);
}
iterator prepend(cmList&& values,
- ExpandElements expandElements = ExpandElements::Yes,
+ ExpandElements expandElements = ExpandElements::No,
EmptyElements emptyElements = EmptyElements::No)
{
auto result = this->prepend(std::make_move_iterator(values.begin()),
@@ -619,8 +681,7 @@ public:
}
iterator prepend(cmList&& values, EmptyElements emptyElements)
{
- return this->prepend(std::move(values), ExpandElements::Yes,
- emptyElements);
+ return this->prepend(std::move(values), ExpandElements::No, emptyElements);
}
iterator prepend(const container_type& values,
ExpandElements expandElements = ExpandElements::Yes,
@@ -654,6 +715,7 @@ public:
return this->insert(this->cbegin(), ilist);
}
+ void push_back(std::string const& value) { this->Values.push_back(value); }
void push_back(cm::string_view value)
{
this->Values.push_back(std::string{ value });
@@ -733,6 +795,8 @@ public:
cmList& remove_duplicates();
+ void resize(size_type count) { this->Values.resize(count); }
+
enum class FilterMode
{
INCLUDE,
@@ -880,46 +944,61 @@ public:
// ==============
// these methods can be used to store CMake list expansion directly in a
// std::vector.
- static void assign(cm::string_view value,
- std::vector<std::string>& container,
+ static void assign(std::vector<std::string>& container,
+ cm::string_view value,
+ EmptyElements emptyElements = EmptyElements::No)
+ {
+ container.clear();
+ cmList::append(container, value, emptyElements);
+ }
+ static void assign(std::vector<std::string>& container,
+ std::string const& value,
EmptyElements emptyElements = EmptyElements::No)
{
container.clear();
- cmList::append(value, container, emptyElements);
+ cmList::append(container, value, emptyElements);
}
- static void assign(cmValue value, std::vector<std::string>& container,
+ static void assign(std::vector<std::string>& container, cmValue value,
EmptyElements emptyElements = EmptyElements::No)
{
if (value) {
- cmList::assign(*value, container, emptyElements);
+ cmList::assign(container, *value, emptyElements);
} else {
container.clear();
}
}
template <typename InputIterator>
- static void assign(InputIterator first, InputIterator last,
- std::vector<std::string>& container,
+ static void assign(std::vector<std::string>& container, InputIterator first,
+ InputIterator last,
EmptyElements emptyElements = EmptyElements::No)
{
container.clear();
- cmList::append(first, last, container, emptyElements);
+ cmList::append(container, first, last, emptyElements);
}
static std::vector<std::string>::iterator insert(
- std::vector<std::string>::const_iterator pos, cm::string_view value,
std::vector<std::string>& container,
+ std::vector<std::string>::const_iterator pos, cm::string_view value,
EmptyElements emptyElements = EmptyElements::No)
{
- return cmList::Insert(pos, std::string(value), container,
+ return cmList::Insert(container, pos, std::string(value),
ExpandElements::Yes, emptyElements);
}
static std::vector<std::string>::iterator insert(
- std::vector<std::string>::const_iterator pos, cmValue value,
std::vector<std::string>& container,
+ std::vector<std::string>::const_iterator pos, std::string const& value,
+ EmptyElements emptyElements = EmptyElements::No)
+ {
+ return cmList::Insert(container, pos, value, ExpandElements::Yes,
+ emptyElements);
+ }
+ static std::vector<std::string>::iterator insert(
+ std::vector<std::string>& container,
+ std::vector<std::string>::const_iterator pos, cmValue value,
EmptyElements emptyElements = EmptyElements::No)
{
if (value) {
- return cmList::insert(pos, *value, container, emptyElements);
+ return cmList::insert(container, pos, *value, emptyElements);
}
auto delta = std::distance(container.cbegin(), pos);
@@ -927,63 +1006,73 @@ public:
}
template <typename InputIterator>
static std::vector<std::string>::iterator insert(
+ std::vector<std::string>& container,
std::vector<std::string>::const_iterator pos, InputIterator first,
- InputIterator last, std::vector<std::string>& container,
- EmptyElements emptyElements = EmptyElements::No)
+ InputIterator last, EmptyElements emptyElements = EmptyElements::No)
{
- return cmList::Insert(pos, first, last, container, ExpandElements::Yes,
+ return cmList::Insert(container, pos, first, last, ExpandElements::Yes,
emptyElements);
}
static std::vector<std::string>::iterator append(
- cm::string_view value, std::vector<std::string>& container,
+ std::vector<std::string>& container, cm::string_view value,
EmptyElements emptyElements = EmptyElements::No)
{
- return cmList::insert(container.cend(), value, container, emptyElements);
+ return cmList::insert(container, container.cend(), value, emptyElements);
}
static std::vector<std::string>::iterator append(
- cmValue value, std::vector<std::string>& container,
+ std::vector<std::string>& container, std::string const& value,
+ EmptyElements emptyElements = EmptyElements::No)
+ {
+ return cmList::insert(container, container.cend(), value, emptyElements);
+ }
+ static std::vector<std::string>::iterator append(
+ std::vector<std::string>& container, cmValue value,
EmptyElements emptyElements = EmptyElements::No)
{
if (value) {
- return cmList::append(*value, container, emptyElements);
+ return cmList::append(container, *value, emptyElements);
}
return container.end();
}
template <typename InputIterator>
static std::vector<std::string>::iterator append(
- InputIterator first, InputIterator last,
- std::vector<std::string>& container,
- EmptyElements emptyElements = EmptyElements::No)
+ std::vector<std::string>& container, InputIterator first,
+ InputIterator last, EmptyElements emptyElements = EmptyElements::No)
{
- return cmList::insert(container.cend(), first, last, container,
+ return cmList::insert(container, container.cend(), first, last,
emptyElements);
}
static std::vector<std::string>::iterator prepend(
- cm::string_view value, std::vector<std::string>& container,
+ std::vector<std::string>& container, cm::string_view value,
+ EmptyElements emptyElements = EmptyElements::No)
+ {
+ return cmList::insert(container, container.cbegin(), value, emptyElements);
+ }
+ static std::vector<std::string>::iterator prepend(
+ std::vector<std::string>& container, std::string const& value,
EmptyElements emptyElements = EmptyElements::No)
{
- return cmList::insert(container.cbegin(), value, container, emptyElements);
+ return cmList::insert(container, container.cbegin(), value, emptyElements);
}
static std::vector<std::string>::iterator prepend(
- cmValue value, std::vector<std::string>& container,
+ std::vector<std::string>& container, cmValue value,
EmptyElements emptyElements = EmptyElements::No)
{
if (value) {
- return cmList::prepend(*value, container, emptyElements);
+ return cmList::prepend(container, *value, emptyElements);
}
return container.begin();
}
template <typename InputIterator>
static std::vector<std::string>::iterator prepend(
- InputIterator first, InputIterator last,
- std::vector<std::string>& container,
- EmptyElements emptyElements = EmptyElements::No)
+ std::vector<std::string>& container, InputIterator first,
+ InputIterator last, EmptyElements emptyElements = EmptyElements::No)
{
- return cmList::insert(container.cbegin(), first, last, container,
+ return cmList::insert(container, container.cbegin(), first, last,
emptyElements);
}
@@ -991,40 +1080,40 @@ public:
// but without any intermediate expansion. So the operation is simply a
// string concatenation with special handling for the CMake list item
// separator
- static std::string& append(cm::string_view value, std::string& list);
+ static std::string& append(std::string& list, cm::string_view value);
template <typename InputIterator>
- static std::string& append(InputIterator first, InputIterator last,
- std::string& list)
+ static std::string& append(std::string& list, InputIterator first,
+ InputIterator last)
{
if (first == last) {
return list;
}
- return cmList::append(cm::string_view{ std::accumulate(
+ return cmList::append(list,
+ cm::string_view{ std::accumulate(
std::next(first), last, *first,
[](std::string a, const std::string& b) {
return std::move(a) +
std::string(cmList::element_separator) + b;
- }) },
- list);
+ }) });
}
- static std::string& prepend(cm::string_view value, std::string& list);
+ static std::string& prepend(std::string& list, cm::string_view value);
template <typename InputIterator>
- static std::string& prepend(InputIterator first, InputIterator last,
- std::string& list)
+ static std::string& prepend(std::string& list, InputIterator first,
+ InputIterator last)
{
if (first == last) {
return list;
}
- return cmList::prepend(cm::string_view{ std::accumulate(
+ return cmList::prepend(list,
+ cm::string_view{ std::accumulate(
std::next(first), last, *first,
[](std::string a, const std::string& b) {
return std::move(a) +
std::string(cmList::element_separator) + b;
- }) },
- list);
+ }) });
}
// Non-members
@@ -1047,26 +1136,26 @@ private:
cmList& RemoveItems(std::vector<index_type>&& indexes);
cmList& RemoveItems(std::vector<std::string>&& items);
- static container_type::iterator Insert(container_type::const_iterator pos,
+ static container_type::iterator Insert(container_type& container,
+ container_type::const_iterator pos,
std::string&& value,
- container_type& container,
ExpandElements expandElements,
EmptyElements emptyElements);
- static container_type::iterator Insert(container_type::const_iterator pos,
+ static container_type::iterator Insert(container_type& container,
+ container_type::const_iterator pos,
const std::string& value,
- container_type& container,
ExpandElements expandElements,
EmptyElements emptyElements)
{
auto tmp = value;
- return cmList::Insert(pos, std::move(tmp), container, expandElements,
+ return cmList::Insert(container, pos, std::move(tmp), expandElements,
emptyElements);
}
template <typename InputIterator>
- static container_type::iterator Insert(container_type::const_iterator pos,
+ static container_type::iterator Insert(container_type& container,
+ container_type::const_iterator pos,
InputIterator first,
InputIterator last,
- container_type& container,
ExpandElements expandElements,
EmptyElements emptyElements)
{
@@ -1080,7 +1169,7 @@ private:
if (expandElements == ExpandElements::Yes) {
for (; first != last; ++first) {
auto size = container.size();
- insertPos = cmList::Insert(insertPos, *first, container,
+ insertPos = cmList::Insert(container, insertPos, *first,
expandElements, emptyElements);
insertPos += container.size() - size;
}
@@ -1177,6 +1266,13 @@ inline std::vector<std::string>& operator+=(std::vector<std::string>& l,
return l;
}
+namespace std {
+inline void swap(cmList& lhs, cmList& rhs) noexcept
+{
+ lhs.swap(rhs);
+}
+} // namespace std
+
namespace cm {
inline void erase(cmList& list, const std::string& value)
{
@@ -1188,11 +1284,69 @@ inline void erase_if(cmList& list, Predicate pred)
{
list.erase(std::remove_if(list.begin(), list.end(), pred), list.end());
}
+
+//
+// Provide a special implementation of cm::append because, in this case,
+// expansion must not be applied to the inserted elements
+//
+#if defined(__SUNPRO_CC) && defined(__sparc)
+// Oracle DeveloperStudio C++ compiler on Solaris/Sparc fails to compile
+// templates with constraints.
+// So, on this platform, use only simple templates.
+template <typename InputIt,
+ cm::enable_if_t<cm::is_input_iterator<InputIt>::value, int> = 0>
+void append(cmList& v, InputIt first, InputIt last)
+{
+ v.append(first, last, cmList::ExpandElements::No);
}
-namespace srd {
-inline void swap(cmList& lhs, cmList& rhs) noexcept
+template <typename Range,
+ cm::enable_if_t<cm::is_input_range<Range>::value, int> = 0>
+void append(cmList& v, Range const& r)
{
- lhs.swap(rhs);
+ v.append(r.begin(), r.end(), cmList::ExpandElements::No);
+}
+
+#else
+
+template <
+ typename InputIt,
+ cm::enable_if_t<
+ cm::is_input_iterator<InputIt>::value &&
+ std::is_convertible<typename std::iterator_traits<InputIt>::value_type,
+ cmList::value_type>::value,
+ int> = 0>
+void append(cmList& v, InputIt first, InputIt last)
+{
+ v.append(first, last, cmList::ExpandElements::No);
+}
+
+template <typename Range,
+ cm::enable_if_t<cm::is_input_range<Range>::value &&
+ std::is_convertible<typename Range::value_type,
+ cmList::value_type>::value,
+ int> = 0>
+void append(cmList& v, Range const& r)
+{
+ v.append(r.begin(), r.end(), cmList::ExpandElements::No);
}
+#endif
+
+} // namespace cm
+
+/**
+ * Helper functions for legacy support. Use preferably cmList class directly
+ * or the static methods of the class.
+ */
+inline void cmExpandList(
+ cm::string_view arg, std::vector<std::string>& argsOut,
+ cmList::EmptyElements emptyElements = cmList::EmptyElements::No)
+{
+ cmList::append(argsOut, arg, emptyElements);
+}
+inline void cmExpandList(
+ cmValue arg, std::vector<std::string>& argsOut,
+ cmList::EmptyElements emptyElements = cmList::EmptyElements::No)
+{
+ cmList::append(argsOut, arg, emptyElements);
}
diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx
index 40be0ceeb5..acffa2ec81 100644
--- a/Source/cmListCommand.cxx
+++ b/Source/cmListCommand.cxx
@@ -205,7 +205,7 @@ bool HandleAppendCommand(std::vector<std::string> const& args,
GetListString(listString, listName, makefile);
makefile.AddDefinition(
- listName, cmList::append(args.begin() + 2, args.end(), listString));
+ listName, cmList::append(listString, args.begin() + 2, args.end()));
return true;
}
@@ -226,7 +226,7 @@ bool HandlePrependCommand(std::vector<std::string> const& args,
GetListString(listString, listName, makefile);
makefile.AddDefinition(
- listName, cmList::prepend(args.begin() + 2, args.end(), listString));
+ listName, cmList::prepend(listString, args.begin() + 2, args.end()));
return true;
}
diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx
index 6270c825f2..97f5de9697 100644
--- a/Source/cmListFileCache.cxx
+++ b/Source/cmListFileCache.cxx
@@ -11,10 +11,10 @@
# include <cmsys/Encoding.hxx>
#endif
+#include "cmList.h"
#include "cmListFileLexer.h"
#include "cmMessageType.h"
#include "cmMessenger.h"
-#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
struct cmListFileParser
@@ -496,10 +496,11 @@ std::ostream& operator<<(std::ostream& os, BT<std::string> const& s)
}
std::vector<BT<std::string>> cmExpandListWithBacktrace(
- std::string const& list, cmListFileBacktrace const& bt, bool emptyArgs)
+ std::string const& list, cmListFileBacktrace const& bt,
+ cmList::EmptyElements emptyArgs)
{
std::vector<BT<std::string>> result;
- std::vector<std::string> tmp = cmExpandedList(list, emptyArgs);
+ cmList tmp{ list, emptyArgs };
result.reserve(tmp.size());
for (std::string& i : tmp) {
result.emplace_back(std::move(i), bt);
diff --git a/Source/cmListFileCache.h b/Source/cmListFileCache.h
index 05539892c9..e4e6eb37ed 100644
--- a/Source/cmListFileCache.h
+++ b/Source/cmListFileCache.h
@@ -13,6 +13,7 @@
#include <cm/optional>
#include "cmConstStack.h"
+#include "cmList.h"
#include "cmSystemTools.h"
/** \class cmListFileCache
@@ -232,7 +233,7 @@ public:
std::vector<BT<std::string>> cmExpandListWithBacktrace(
std::string const& list,
cmListFileBacktrace const& bt = cmListFileBacktrace(),
- bool emptyArgs = false);
+ cmList::EmptyElements emptyArgs = cmList::EmptyElements::No);
struct cmListFile
{
diff --git a/Source/cmLocalCommonGenerator.cxx b/Source/cmLocalCommonGenerator.cxx
index eca7a9eb6e..aa953f469d 100644
--- a/Source/cmLocalCommonGenerator.cxx
+++ b/Source/cmLocalCommonGenerator.cxx
@@ -8,7 +8,6 @@
#include "cmGeneratorTarget.h"
#include "cmMakefile.h"
#include "cmOutputConverter.h"
-#include "cmState.h"
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmStringAlgorithms.h"
@@ -17,9 +16,8 @@
class cmGlobalGenerator;
cmLocalCommonGenerator::cmLocalCommonGenerator(cmGlobalGenerator* gg,
- cmMakefile* mf, WorkDir wd)
+ cmMakefile* mf)
: cmLocalGenerator(gg, mf)
- , WorkingDirectory(wd)
{
this->ConfigNames =
this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
@@ -29,21 +27,9 @@ cmLocalCommonGenerator::~cmLocalCommonGenerator() = default;
std::string const& cmLocalCommonGenerator::GetWorkingDirectory() const
{
- if (this->WorkingDirectory == WorkDir::TopBin) {
- return this->GetState()->GetBinaryDirectory();
- }
return this->StateSnapshot.GetDirectory().GetCurrentBinary();
}
-std::string cmLocalCommonGenerator::MaybeRelativeToWorkDir(
- std::string const& path) const
-{
- if (this->WorkingDirectory == WorkDir::TopBin) {
- return this->MaybeRelativeToTopBinDir(path);
- }
- return this->MaybeRelativeToCurBinDir(path);
-}
-
std::string cmLocalCommonGenerator::GetTargetFortranFlags(
cmGeneratorTarget const* target, std::string const& config)
{
diff --git a/Source/cmLocalCommonGenerator.h b/Source/cmLocalCommonGenerator.h
index 0505c138d1..52f7a9e5e6 100644
--- a/Source/cmLocalCommonGenerator.h
+++ b/Source/cmLocalCommonGenerator.h
@@ -20,15 +20,8 @@ class cmSourceFile;
*/
class cmLocalCommonGenerator : public cmLocalGenerator
{
-protected:
- enum class WorkDir
- {
- TopBin,
- CurBin,
- };
-
public:
- cmLocalCommonGenerator(cmGlobalGenerator* gg, cmMakefile* mf, WorkDir wd);
+ cmLocalCommonGenerator(cmGlobalGenerator* gg, cmMakefile* mf);
~cmLocalCommonGenerator() override;
std::vector<std::string> const& GetConfigNames() const
@@ -36,9 +29,7 @@ public:
return this->ConfigNames;
}
- std::string const& GetWorkingDirectory() const;
-
- std::string MaybeRelativeToWorkDir(std::string const& path) const;
+ virtual std::string const& GetWorkingDirectory() const;
std::string GetTargetFortranFlags(cmGeneratorTarget const* target,
std::string const& config) override;
@@ -48,8 +39,6 @@ public:
cmGeneratorTarget const* gt = nullptr) override;
protected:
- WorkDir WorkingDirectory;
-
std::vector<std::string> ConfigNames;
friend class cmCommonTargetGenerator;
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 01e4241360..4089fd440b 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -38,6 +38,7 @@
#include "cmInstallTargetGenerator.h"
#include "cmLinkLineComputer.h"
#include "cmLinkLineDeviceComputer.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmRange.h"
#include "cmRulePlaceholderExpander.h"
@@ -146,12 +147,10 @@ cmLocalGenerator::cmLocalGenerator(cmGlobalGenerator* gg, cmMakefile* makefile)
this->Makefile->GetDefinition("CMAKE_APPLE_ARCH_SYSROOTS")) {
std::string const& appleArchs =
this->Makefile->GetSafeDefinition("CMAKE_OSX_ARCHITECTURES");
- std::vector<std::string> archs;
- std::vector<std::string> sysroots;
- cmExpandList(appleArchs, archs);
- cmExpandList(*appleArchSysroots, sysroots, true);
+ cmList archs(appleArchs);
+ cmList sysroots{ appleArchSysroots, cmList::EmptyElements::Yes };
if (archs.size() == sysroots.size()) {
- for (size_t i = 0; i < archs.size(); ++i) {
+ for (cmList::size_type i = 0; i < archs.size(); ++i) {
this->AppleArchSysroots[archs[i]] = sysroots[i];
}
} else {
@@ -208,12 +207,12 @@ cmLocalGenerator::cmLocalGenerator(cmGlobalGenerator* gg, cmMakefile* makefile)
}
}
-cmRulePlaceholderExpander* cmLocalGenerator::CreateRulePlaceholderExpander()
- const
+std::unique_ptr<cmRulePlaceholderExpander>
+cmLocalGenerator::CreateRulePlaceholderExpander() const
{
- return new cmRulePlaceholderExpander(this->Compilers, this->VariableMappings,
- this->CompilerSysroot,
- this->LinkerSysroot);
+ return cm::make_unique<cmRulePlaceholderExpander>(
+ this->Compilers, this->VariableMappings, this->CompilerSysroot,
+ this->LinkerSysroot);
}
cmLocalGenerator::~cmLocalGenerator() = default;
@@ -347,7 +346,7 @@ void cmLocalGenerator::GenerateTestFiles()
cmValue testIncludeFiles = this->Makefile->GetProperty("TEST_INCLUDE_FILES");
if (testIncludeFiles) {
- std::vector<std::string> includesList = cmExpandedList(*testIncludeFiles);
+ cmList includesList{ *testIncludeFiles };
for (std::string const& i : includesList) {
fout << "include(\"" << i << "\")\n";
}
@@ -1064,9 +1063,9 @@ void cmLocalGenerator::AddCompileOptions(std::vector<BT<std::string>>& flags,
std::string isJMCEnabled =
cmGeneratorExpression::Evaluate(*jmcExprGen, this, config);
if (cmIsOn(isJMCEnabled)) {
- std::vector<std::string> optVec = cmExpandedList(*jmc);
+ cmList optList{ *jmc };
std::string jmcFlags;
- this->AppendCompileOptions(jmcFlags, optVec);
+ this->AppendCompileOptions(jmcFlags, optList);
if (!jmcFlags.empty()) {
flags.emplace_back(std::move(jmcFlags));
}
@@ -1168,11 +1167,11 @@ std::vector<BT<std::string>> cmLocalGenerator::GetIncludeDirectoriesImplicit(
// Standard include directories to be added unconditionally at the end.
// These are intended to simulate additional implicit include directories.
- std::vector<std::string> userStandardDirs;
+ cmList userStandardDirs;
{
std::string const value = this->Makefile->GetSafeDefinition(
cmStrCat("CMAKE_", lang, "_STANDARD_INCLUDE_DIRECTORIES"));
- cmExpandList(value, userStandardDirs);
+ userStandardDirs.assign(value);
for (std::string& usd : userStandardDirs) {
cmSystemTools::ConvertToUnixSlashes(usd);
}
@@ -1195,13 +1194,12 @@ std::vector<BT<std::string>> cmLocalGenerator::GetIncludeDirectoriesImplicit(
// directories for modules ('.mod' files).
if (lang != "Fortran") {
size_t const impDirVecOldSize = impDirVec.size();
- if (this->Makefile->GetDefExpandList(
- cmStrCat("CMAKE_", lang, "_IMPLICIT_INCLUDE_DIRECTORIES"),
- impDirVec)) {
- // FIXME: Use cmRange with 'advance()' when it supports non-const.
- for (size_t i = impDirVecOldSize; i < impDirVec.size(); ++i) {
- cmSystemTools::ConvertToUnixSlashes(impDirVec[i]);
- }
+ cmList::append(impDirVec,
+ this->Makefile->GetDefinition(cmStrCat(
+ "CMAKE_", lang, "_IMPLICIT_INCLUDE_DIRECTORIES")));
+ // FIXME: Use cmRange with 'advance()' when it supports non-const.
+ for (size_t i = impDirVecOldSize; i < impDirVec.size(); ++i) {
+ cmSystemTools::ConvertToUnixSlashes(impDirVec[i]);
}
}
@@ -1588,6 +1586,8 @@ void cmLocalGenerator::GetTargetFlags(
this->AppendPositionIndependentLinkerFlags(extraLinkFlags, target, config,
linkLanguage);
this->AppendIPOLinkerFlags(extraLinkFlags, target, config, linkLanguage);
+ this->AppendDependencyInfoLinkerFlags(extraLinkFlags, target, config,
+ linkLanguage);
this->AppendModuleDefinitionFlag(extraLinkFlags, target, linkLineComputer,
config);
@@ -1954,8 +1954,8 @@ void cmLocalGenerator::AddLanguageFlags(std::string& flags,
cmValue opt =
target->Target->GetMakefile()->GetDefinition(optionFlagDef);
if (opt) {
- std::vector<std::string> optVec = cmExpandedList(*opt);
- for (std::string const& i : optVec) {
+ cmList optList{ *opt };
+ for (std::string const& i : optList) {
this->AppendFlagEscape(flags, i);
}
}
@@ -2426,7 +2426,7 @@ void cmLocalGenerator::AddPositionIndependentFlags(std::string& flags,
cmStrCat("CMAKE_", lang, "_COMPILE_OPTIONS_PIC"));
}
if (!picFlags.empty()) {
- std::vector<std::string> options = cmExpandedList(picFlags);
+ cmList options{ picFlags };
for (std::string const& o : options) {
this->AppendFlagEscape(flags, o);
}
@@ -2447,10 +2447,9 @@ void cmLocalGenerator::AddColorDiagnosticsFlags(std::string& flags,
cmStrCat("CMAKE_", lang, "_COMPILE_OPTIONS_COLOR_DIAGNOSTICS_OFF");
}
- std::vector<std::string> options;
- this->Makefile->GetDefExpandList(colorFlagName, options);
+ cmList options{ this->Makefile->GetDefinition(colorFlagName) };
- for (std::string const& option : options) {
+ for (auto const& option : options) {
this->AppendFlagEscape(flags, option);
}
}
@@ -2973,6 +2972,7 @@ void cmLocalGenerator::WriteUnitySourceInclude(
unity_file << *beforeInclude << "\n";
}
+ unity_file << "// NOLINTNEXTLINE(bugprone-suspicious-include)\n";
unity_file << "#include \"" << sf_full_path << "\"\n";
if (afterInclude) {
@@ -3163,7 +3163,7 @@ void cmLocalGenerator::AppendIPOLinkerFlags(std::string& flags,
return;
}
- std::vector<std::string> flagsList = cmExpandedList(*rawFlagsList);
+ cmList flagsList{ *rawFlagsList };
for (std::string const& o : flagsList) {
this->AppendFlagEscape(flags, o);
}
@@ -3198,12 +3198,47 @@ void cmLocalGenerator::AppendPositionIndependentLinkerFlags(
return;
}
- std::vector<std::string> flagsList = cmExpandedList(pieFlags);
+ cmList flagsList{ pieFlags };
for (const auto& flag : flagsList) {
this->AppendFlagEscape(flags, flag);
}
}
+void cmLocalGenerator::AppendDependencyInfoLinkerFlags(
+ std::string& flags, cmGeneratorTarget* target, const std::string& config,
+ const std::string& linkLanguage)
+{
+ if (!this->GetGlobalGenerator()->SupportsLinkerDependencyFile() ||
+ !target->HasLinkDependencyFile(config)) {
+ return;
+ }
+
+ auto depFlag = *this->Makefile->GetDefinition(
+ cmStrCat("CMAKE_", linkLanguage, "_LINKER_DEPFILE_FLAGS"));
+ if (depFlag.empty()) {
+ return;
+ }
+
+ auto depFile = this->ConvertToOutputFormat(
+ this->MaybeRelativeToWorkDir(this->GetLinkDependencyFile(target, config)),
+ cmOutputConverter::SHELL);
+ auto rulePlaceholderExpander = this->CreateRulePlaceholderExpander();
+ cmRulePlaceholderExpander::RuleVariables linkDepsVariables;
+ linkDepsVariables.DependencyFile = depFile.c_str();
+ rulePlaceholderExpander->ExpandRuleVariables(this, depFlag,
+ linkDepsVariables);
+ auto depFlags = cmExpandListWithBacktrace(depFlag);
+ target->ResolveLinkerWrapper(depFlags, linkLanguage);
+
+ this->AppendFlags(flags, depFlags);
+}
+
+std::string cmLocalGenerator::GetLinkDependencyFile(
+ cmGeneratorTarget* /*target*/, const std::string& /*config*/) const
+{
+ return "link.d";
+}
+
void cmLocalGenerator::AppendModuleDefinitionFlag(
std::string& flags, cmGeneratorTarget const* target,
cmLinkLineComputer* linkLineComputer, std::string const& config)
@@ -3264,7 +3299,7 @@ void cmLocalGenerator::AppendCompileOptions(std::string& options,
}
// Expand the list of options.
- std::vector<std::string> options_vec = cmExpandedList(options_list);
+ cmList options_vec{ options_list };
this->AppendCompileOptions(options, options_vec, regex);
}
@@ -3322,7 +3357,7 @@ void cmLocalGenerator::AppendIncludeDirectories(
}
// Expand the list of includes.
- std::vector<std::string> includes_vec = cmExpandedList(includes_list);
+ cmList includes_vec{ includes_list };
this->AppendIncludeDirectories(includes, includes_vec, sourceFile);
}
@@ -3454,7 +3489,7 @@ void cmLocalGenerator::AppendFeatureOptions(std::string& flags,
cmValue optionList = this->Makefile->GetDefinition(
cmStrCat("CMAKE_", lang, "_COMPILE_OPTIONS_", feature));
if (optionList) {
- std::vector<std::string> options = cmExpandedList(*optionList);
+ cmList options{ *optionList };
for (std::string const& o : options) {
this->AppendFlagEscape(flags, o);
}
@@ -4385,12 +4420,11 @@ void AddUtilityCommand(cmLocalGenerator& lg, cmCommandOrigin origin,
std::vector<std::string> ComputeISPCObjectSuffixes(cmGeneratorTarget* target)
{
- const std::string& targetProperty =
- target->GetSafeProperty("ISPC_INSTRUCTION_SETS");
- std::vector<std::string> ispcTargets;
+ const cmValue targetProperty = target->GetProperty("ISPC_INSTRUCTION_SETS");
+ cmList ispcTargets;
- if (!cmIsOff(targetProperty)) {
- cmExpandList(targetProperty, ispcTargets);
+ if (!targetProperty.IsOff()) {
+ ispcTargets.assign(targetProperty);
for (auto& ispcTarget : ispcTargets) {
// transform targets into the suffixes
auto pos = ispcTarget.find('-');
@@ -4402,7 +4436,7 @@ std::vector<std::string> ComputeISPCObjectSuffixes(cmGeneratorTarget* target)
ispcTarget = target_suffix;
}
}
- return ispcTargets;
+ return std::move(ispcTargets.data());
}
std::vector<std::string> ComputeISPCExtraObjects(
@@ -4500,11 +4534,11 @@ cmLocalGenerator::MakeCustomCommandGenerators(cmCustomCommand const& cc,
std::vector<std::string> cmLocalGenerator::ExpandCustomCommandOutputPaths(
cmCompiledGeneratorExpression const& cge, std::string const& config)
{
- std::vector<std::string> paths = cmExpandedList(cge.Evaluate(this, config));
+ cmList paths{ cge.Evaluate(this, config) };
for (std::string& p : paths) {
p = cmSystemTools::CollapseFullPath(p, this->GetCurrentBinaryDirectory());
}
- return paths;
+ return std::move(paths.data());
}
std::vector<std::string> cmLocalGenerator::ExpandCustomCommandOutputGenex(
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index bda82bce00..c811408138 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -89,7 +89,7 @@ class cmLocalGenerator : public cmOutputConverter
{
public:
cmLocalGenerator(cmGlobalGenerator* gg, cmMakefile* makefile);
- virtual ~cmLocalGenerator();
+ ~cmLocalGenerator() override;
/**
* Generate the makefile for this directory.
@@ -137,7 +137,8 @@ public:
return this->GlobalGenerator;
}
- virtual cmRulePlaceholderExpander* CreateRulePlaceholderExpander() const;
+ virtual std::unique_ptr<cmRulePlaceholderExpander>
+ CreateRulePlaceholderExpander() const;
std::string GetLinkLibsCMP0065(std::string const& linkLanguage,
cmGeneratorTarget& tgt) const;
@@ -183,6 +184,12 @@ public:
cmGeneratorTarget* target,
const std::string& config,
const std::string& lang);
+ void AppendDependencyInfoLinkerFlags(std::string& flags,
+ cmGeneratorTarget* target,
+ const std::string& config,
+ const std::string& lang);
+ virtual std::string GetLinkDependencyFile(cmGeneratorTarget* target,
+ const std::string& config) const;
void AppendModuleDefinitionFlag(std::string& flags,
cmGeneratorTarget const* target,
cmLinkLineComputer* linkLineComputer,
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index d0bd3758f4..4b0604c55e 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -22,6 +22,7 @@
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmGlobalNinjaGenerator.h"
+#include "cmList.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -40,19 +41,18 @@
cmLocalNinjaGenerator::cmLocalNinjaGenerator(cmGlobalGenerator* gg,
cmMakefile* mf)
- : cmLocalCommonGenerator(gg, mf, WorkDir::TopBin)
+ : cmLocalCommonGenerator(gg, mf)
{
}
// Virtual public methods.
-cmRulePlaceholderExpander*
+std::unique_ptr<cmRulePlaceholderExpander>
cmLocalNinjaGenerator::CreateRulePlaceholderExpander() const
{
- cmRulePlaceholderExpander* ret =
- this->cmLocalGenerator::CreateRulePlaceholderExpander();
+ auto ret = this->cmLocalGenerator::CreateRulePlaceholderExpander();
ret->SetTargetImpLib("$TARGET_IMPLIB");
- return ret;
+ return std::unique_ptr<cmRulePlaceholderExpander>(std::move(ret));
}
cmLocalNinjaGenerator::~cmLocalNinjaGenerator() = default;
@@ -187,6 +187,26 @@ cmGlobalNinjaGenerator* cmLocalNinjaGenerator::GetGlobalNinjaGenerator()
return static_cast<cmGlobalNinjaGenerator*>(this->GetGlobalGenerator());
}
+std::string const& cmLocalNinjaGenerator::GetWorkingDirectory() const
+{
+ return this->GetState()->GetBinaryDirectory();
+}
+
+std::string cmLocalNinjaGenerator::MaybeRelativeToWorkDir(
+ std::string const& path) const
+{
+ return this->GetGlobalNinjaGenerator()->NinjaOutputPath(
+ this->MaybeRelativeToTopBinDir(path));
+}
+
+std::string cmLocalNinjaGenerator::GetLinkDependencyFile(
+ cmGeneratorTarget* target, std::string const& config) const
+{
+ return cmStrCat(target->GetSupportDirectory(),
+ this->GetGlobalNinjaGenerator()->ConfigDirectory(config),
+ "/link.d");
+}
+
// Virtual protected methods.
std::string cmLocalNinjaGenerator::ConvertToIncludeReference(
@@ -301,7 +321,7 @@ void cmLocalNinjaGenerator::WritePools(std::ostream& os)
if (jobpools) {
cmGlobalNinjaGenerator::WriteComment(
os, "Pools defined by global property JOB_POOLS");
- std::vector<std::string> pools = cmExpandedList(*jobpools);
+ cmList pools{ *jobpools };
for (std::string const& pool : pools) {
const std::string::size_type eq = pool.find('=');
unsigned int jobs;
@@ -892,8 +912,7 @@ std::string cmLocalNinjaGenerator::MakeCustomLauncher(
}
vars.Output = output.c_str();
- std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
- this->CreateRulePlaceholderExpander());
+ auto rulePlaceholderExpander = this->CreateRulePlaceholderExpander();
std::string launcher = *property_value;
rulePlaceholderExpander->ExpandRuleVariables(this, launcher, vars);
@@ -908,14 +927,11 @@ void cmLocalNinjaGenerator::AdditionalCleanFiles(const std::string& config)
{
if (cmValue prop_value =
this->Makefile->GetProperty("ADDITIONAL_CLEAN_FILES")) {
- std::vector<std::string> cleanFiles;
- {
- cmExpandList(cmGeneratorExpression::Evaluate(*prop_value, this, config),
- cleanFiles);
- }
+ cmList cleanFiles{ cmGeneratorExpression::Evaluate(*prop_value, this,
+ config) };
std::string const& binaryDir = this->GetCurrentBinaryDirectory();
cmGlobalNinjaGenerator* gg = this->GetGlobalNinjaGenerator();
- for (std::string const& cleanFile : cleanFiles) {
+ for (auto const& cleanFile : cleanFiles) {
// Support relative paths
gg->AddAdditionalCleanFile(
cmSystemTools::CollapseFullPath(cleanFile, binaryDir), config);
diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h
index 4d393d9c3a..74b8b3b3f8 100644
--- a/Source/cmLocalNinjaGenerator.h
+++ b/Source/cmLocalNinjaGenerator.h
@@ -6,6 +6,7 @@
#include <iosfwd>
#include <map>
+#include <memory>
#include <set>
#include <string>
#include <vector>
@@ -41,7 +42,8 @@ public:
void Generate() override;
- cmRulePlaceholderExpander* CreateRulePlaceholderExpander() const override;
+ std::unique_ptr<cmRulePlaceholderExpander> CreateRulePlaceholderExpander()
+ const override;
std::string GetTargetDirectory(
cmGeneratorTarget const* target) const override;
@@ -52,6 +54,10 @@ public:
const cmake* GetCMakeInstance() const;
cmake* GetCMakeInstance();
+ std::string const& GetWorkingDirectory() const override;
+
+ std::string MaybeRelativeToWorkDir(std::string const& path) const override;
+
/// @returns the relative path between the HomeOutputDirectory and this
/// local generators StartOutputDirectory.
std::string GetHomeRelativeOutputPath() const
@@ -90,6 +96,9 @@ public:
bool HasUniqueByproducts(std::vector<std::string> const& byproducts,
cmListFileBacktrace const& bt);
+ std::string GetLinkDependencyFile(cmGeneratorTarget* target,
+ std::string const& config) const override;
+
protected:
std::string ConvertToIncludeReference(
std::string const& path, cmOutputConverter::OutputFormat format) override;
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index 56a41b1a98..cfe4eb629d 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -29,6 +29,7 @@
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmGlobalUnixMakefileGenerator3.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
@@ -110,7 +111,7 @@ private:
cmLocalUnixMakefileGenerator3::cmLocalUnixMakefileGenerator3(
cmGlobalGenerator* gg, cmMakefile* mf)
- : cmLocalCommonGenerator(gg, mf, WorkDir::CurBin)
+ : cmLocalCommonGenerator(gg, mf)
{
this->MakefileVariableSize = 0;
this->ColorMakefile = false;
@@ -238,6 +239,12 @@ void cmLocalUnixMakefileGenerator3::GetIndividualFileTargets(
}
}
+std::string cmLocalUnixMakefileGenerator3::GetLinkDependencyFile(
+ cmGeneratorTarget* target, std::string const& /*config*/) const
+{
+ return cmStrCat(target->GetSupportDirectory(), "/link.d");
+}
+
void cmLocalUnixMakefileGenerator3::WriteLocalMakefile()
{
// generate the includes
@@ -962,8 +969,7 @@ void cmLocalUnixMakefileGenerator3::AppendCustomCommand(
*content << dir;
}
- std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
- this->CreateRulePlaceholderExpander());
+ auto rulePlaceholderExpander = this->CreateRulePlaceholderExpander();
// Add each command line to the set of commands.
std::vector<std::string> commands1;
@@ -1129,14 +1135,13 @@ void cmLocalUnixMakefileGenerator3::AppendCleanCommand(
void cmLocalUnixMakefileGenerator3::AppendDirectoryCleanCommand(
std::vector<std::string>& commands)
{
- std::vector<std::string> cleanFiles;
+ cmList cleanFiles;
// Look for additional files registered for cleaning in this directory.
if (cmValue prop_value =
this->Makefile->GetProperty("ADDITIONAL_CLEAN_FILES")) {
- cmExpandList(cmGeneratorExpression::Evaluate(
- *prop_value, this,
- this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE")),
- cleanFiles);
+ cleanFiles.assign(cmGeneratorExpression::Evaluate(
+ *prop_value, this,
+ this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE")));
}
if (cleanFiles.empty()) {
return;
@@ -1434,7 +1439,7 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies(
this->Makefile->GetSafeDefinition("CMAKE_DEPENDS_DEPENDENCY_FILES");
if (!depends.empty()) {
// dependencies are managed by compiler
- auto depFiles = cmExpandedList(depends, true);
+ cmList depFiles{ depends, cmList::EmptyElements::Yes };
std::string const internalDepFile =
targetDir + "/compiler_depend.internal";
std::string const depFile = targetDir + "/compiler_depend.make";
@@ -1556,8 +1561,7 @@ bool cmLocalUnixMakefileGenerator3::ScanDependencies(
this->WriteDisclaimer(internalRuleFileStream);
// for each language we need to scan, scan it
- std::vector<std::string> langs =
- cmExpandedList(mf->GetSafeDefinition("CMAKE_DEPENDS_LANGUAGES"));
+ cmList langs{ mf->GetSafeDefinition("CMAKE_DEPENDS_LANGUAGES") };
for (std::string const& lang : langs) {
// construct the checker
// Create the scanner for this language
@@ -1602,7 +1606,7 @@ void cmLocalUnixMakefileGenerator3::CheckMultipleOutputs(bool verbose)
}
// Convert the string to a list and preserve empty entries.
- std::vector<std::string> pairs = cmExpandedList(*pairs_string, true);
+ cmList pairs{ *pairs_string, cmList::EmptyElements::Yes };
for (auto i = pairs.begin(); i != pairs.end() && (i + 1) != pairs.end();) {
const std::string& depender = *i++;
const std::string& dependee = *i++;
@@ -1822,7 +1826,7 @@ void cmLocalUnixMakefileGenerator3::ClearDependencies(cmMakefile* mf,
if (!infoDef) {
return;
}
- std::vector<std::string> files = cmExpandedList(*infoDef);
+ cmList files{ *infoDef };
// Each depend information file corresponds to a target. Clear the
// dependencies for that target.
@@ -1863,7 +1867,7 @@ void cmLocalUnixMakefileGenerator3::ClearDependencies(cmMakefile* mf,
cmSystemTools::Touch(DepTimestamp.GenericString(), true);
// clear the dependencies files generated by the compiler
- std::vector<std::string> dependencies = cmExpandedList(depsFiles, true);
+ cmList dependencies{ depsFiles, cmList::EmptyElements::Yes };
cmDependsCompiler depsManager;
depsManager.SetVerbose(verbose);
depsManager.ClearDependencies(dependencies);
@@ -1973,14 +1977,14 @@ 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;
+ cmList transformRules;
if (cmValue xform =
this->Makefile->GetProperty("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM")) {
- cmExpandList(*xform, transformRules);
+ transformRules.assign(*xform);
}
if (cmValue xform =
target->GetProperty("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM")) {
- cmExpandList(*xform, transformRules);
+ transformRules.append(*xform);
}
if (!transformRules.empty()) {
cmakefileStream << "\nset(CMAKE_INCLUDE_TRANSFORMS\n";
@@ -2009,6 +2013,18 @@ void cmLocalUnixMakefileGenerator3::WriteDependLanguageInfo(
<< this->MaybeRelativeToTopBinDir(src) << "\"\n";
}
}
+ } else if (compilerLang.first == "LINK"_s) {
+ auto depFormat = this->Makefile->GetDefinition(
+ cmStrCat("CMAKE_", target->GetLinkerLanguage(this->GetConfigName()),
+ "_LINKER_DEPFILE_FORMAT"));
+ for (auto const& compilerPair : compilerPairs) {
+ for (auto const& src : compilerPair.second) {
+ cmakefileStream << R"( "" ")"
+ << this->MaybeRelativeToTopBinDir(compilerPair.first)
+ << "\" \"" << depFormat << "\" \""
+ << this->MaybeRelativeToTopBinDir(src) << "\"\n";
+ }
+ }
} else {
auto depFormat = this->Makefile->GetSafeDefinition(
cmStrCat("CMAKE_", compilerLang.first, "_DEPFILE_FORMAT"));
diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h
index 78aa7f9c2f..7d5a9224b4 100644
--- a/Source/cmLocalUnixMakefileGenerator3.h
+++ b/Source/cmLocalUnixMakefileGenerator3.h
@@ -191,6 +191,9 @@ public:
// Eclipse generator.
void GetIndividualFileTargets(std::vector<std::string>& targets);
+ std::string GetLinkDependencyFile(cmGeneratorTarget* target,
+ std::string const& config) const override;
+
protected:
void WriteLocalMakefile();
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index 239748db67..a7ea0dff2c 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -29,6 +29,7 @@
#include "cmGlobalGenerator.h"
#include "cmGlobalVisualStudio7Generator.h"
#include "cmGlobalVisualStudioGenerator.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmOutputConverter.h"
@@ -1576,12 +1577,12 @@ cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo(
// Check for extra object-file dependencies.
if (cmValue deps = sf.GetProperty("OBJECT_DEPENDS")) {
- std::vector<std::string> depends = cmExpandedList(*deps);
- const char* sep = "";
- for (const std::string& d : depends) {
- fc.AdditionalDeps += sep;
- fc.AdditionalDeps += lg->ConvertToXMLOutputPath(d);
- sep = ";";
+ cmList depends{ *deps };
+ if (!depends.empty()) {
+ for (std::string& d : depends) {
+ d = lg->ConvertToXMLOutputPath(d);
+ }
+ fc.AdditionalDeps += depends.to_string();
needfc = true;
}
}
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 3a69b2eeed..01afc44f28 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -43,6 +43,7 @@
#include "cmGlobalGenerator.h"
#include "cmInstallGenerator.h" // IWYU pragma: keep
#include "cmInstallSubdirectoryGenerator.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMessageType.h"
@@ -1448,15 +1449,13 @@ bool cmMakefile::ParseDefineFlag(std::string const& def, bool remove)
if (remove) {
if (cmValue cdefs = this->GetProperty("COMPILE_DEFINITIONS")) {
// Expand the list.
- std::vector<std::string> defs = cmExpandedList(*cdefs);
+ cmList defs{ *cdefs };
// Recompose the list without the definition.
- auto defEnd = std::remove(defs.begin(), defs.end(), define);
- auto defBegin = defs.begin();
- std::string ndefs = cmJoin(cmMakeRange(defBegin, defEnd), ";");
+ defs.remove_items({ define });
// Store the new list.
- this->SetProperty("COMPILE_DEFINITIONS", ndefs);
+ this->SetProperty("COMPILE_DEFINITIONS", defs.to_string());
}
} else {
// Append the definition to the directory property.
@@ -1958,21 +1957,15 @@ void cmMakefile::AddCacheDefinition(const std::string& name, const char* value,
value = existingValue->c_str();
}
if (type == cmStateEnums::PATH || type == cmStateEnums::FILEPATH) {
- std::vector<std::string>::size_type cc;
- std::vector<std::string> files;
nvalue = value ? value : "";
- cmExpandList(nvalue, files);
- nvalue.clear();
- for (cc = 0; cc < files.size(); cc++) {
- if (!cmIsOff(files[cc])) {
- files[cc] = cmSystemTools::CollapseFullPath(files[cc]);
+ cmList files(nvalue);
+ for (auto& file : files) {
+ if (!cmIsOff(file)) {
+ file = cmSystemTools::CollapseFullPath(file);
}
- if (cc > 0) {
- nvalue += ";";
- }
- nvalue += files[cc];
}
+ nvalue = files.to_string();
this->GetCMakeInstance()->AddCacheEntry(name, nvalue, doc, type);
nvalue = *this->GetState()->GetInitializedCacheValue(name);
@@ -2064,7 +2057,7 @@ void cmMakefile::AddGlobalLinkInformation(cmTarget& target)
}
if (cmValue linkLibsProp = this->GetProperty("LINK_LIBRARIES")) {
- std::vector<std::string> linkLibs = cmExpandedList(*linkLibsProp);
+ cmList linkLibs{ *linkLibsProp };
for (auto j = linkLibs.begin(); j != linkLibs.end(); ++j) {
std::string libraryName = *j;
@@ -2378,7 +2371,7 @@ void cmMakefile::ExpandVariablesCMP0019()
}
if (cmValue linkLibsProp = this->GetProperty("LINK_LIBRARIES")) {
- std::vector<std::string> linkLibs = cmExpandedList(*linkLibsProp);
+ cmList linkLibs{ *linkLibsProp };
for (auto l = linkLibs.begin(); l != linkLibs.end(); ++l) {
std::string libName = *l;
@@ -2614,18 +2607,6 @@ const std::string& cmMakefile::GetSafeDefinition(const std::string& name) const
return this->GetDefinition(name);
}
-bool cmMakefile::GetDefExpandList(const std::string& name,
- std::vector<std::string>& out,
- bool emptyArgs) const
-{
- cmValue def = this->GetDefinition(name);
- if (!def) {
- return false;
- }
- cmExpandList(*def, out, emptyArgs);
- return true;
-}
-
std::vector<std::string> cmMakefile::GetDefinitions() const
{
std::vector<std::string> res = this->StateSnapshot.ClosureKeys();
@@ -3266,9 +3247,9 @@ std::string cmMakefile::GetDefaultConfiguration() const
std::vector<std::string> cmMakefile::GetGeneratorConfigs(
GeneratorConfigQuery mode) const
{
- std::vector<std::string> configs;
+ cmList configs;
if (this->GetGlobalGenerator()->IsMultiConfig()) {
- this->GetDefExpandList("CMAKE_CONFIGURATION_TYPES", configs);
+ configs.assign(this->GetDefinition("CMAKE_CONFIGURATION_TYPES"));
} else if (mode != cmMakefile::OnlyMultiConfig) {
const std::string& buildType = this->GetSafeDefinition("CMAKE_BUILD_TYPE");
if (!buildType.empty()) {
@@ -3278,7 +3259,7 @@ std::vector<std::string> cmMakefile::GetGeneratorConfigs(
if (mode == cmMakefile::IncludeEmptyConfig && configs.empty()) {
configs.emplace_back();
}
- return configs;
+ return std::move(configs.data());
}
bool cmMakefile::IsFunctionBlocked(const cmListFileFunction& lff,
@@ -3406,7 +3387,7 @@ bool cmMakefile::ExpandArguments(
if (i.Delim == cmListFileArgument::Quoted) {
outArgs.emplace_back(value, true);
} else {
- std::vector<std::string> stringArgs = cmExpandedList(value);
+ cmList stringArgs{ value };
for (std::string const& stringArg : stringArgs) {
outArgs.emplace_back(stringArg, false);
}
@@ -3812,7 +3793,7 @@ std::string cmMakefile::GetModulesFile(const std::string& filename,
// Always search in CMAKE_MODULE_PATH:
cmValue cmakeModulePath = this->GetDefinition("CMAKE_MODULE_PATH");
if (cmakeModulePath) {
- std::vector<std::string> modulePath = cmExpandedList(*cmakeModulePath);
+ cmList modulePath{ *cmakeModulePath };
// Look through the possible module directories.
for (std::string itempl : modulePath) {
@@ -4155,11 +4136,11 @@ void cmMakefile::GetTests(const std::string& config,
void cmMakefile::AddCMakeDependFilesFromUser()
{
- std::vector<std::string> deps;
+ cmList deps;
if (cmValue deps_str = this->GetProperty("CMAKE_CONFIGURE_DEPENDS")) {
- cmExpandList(*deps_str, deps);
+ deps.assign(*deps_str);
}
- for (std::string const& dep : deps) {
+ for (auto const& dep : deps) {
if (cmSystemTools::FileIsFullPath(dep)) {
this->AddCMakeDependFile(dep);
} else {
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index a43ff41f9c..d1f5be53a0 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -518,8 +518,6 @@ public:
const std::string& GetRequiredDefinition(const std::string& name) const;
bool IsDefinitionSet(const std::string&) const;
bool IsNormalDefinitionSet(const std::string&) const;
- bool GetDefExpandList(const std::string& name, std::vector<std::string>& out,
- bool emptyArgs = false) const;
/**
* Get the list of all variables in the current space. If argument
* cacheonly is specified and is greater than 0, then only cache
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index 196007328e..4a2b9e8996 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -16,6 +16,7 @@
#include "cmGlobalUnixMakefileGenerator3.h"
#include "cmLinkLineComputer.h"
#include "cmLinkLineDeviceComputer.h"
+#include "cmList.h"
#include "cmLocalGenerator.h"
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
@@ -69,6 +70,8 @@ void cmMakefileExecutableTargetGenerator::WriteRuleFiles()
this->WriteExecutableRule(true);
}
+ this->WriteTargetLinkDependRules();
+
// Write clean target
this->WriteTargetCleanRules();
@@ -151,11 +154,10 @@ void cmMakefileExecutableTargetGenerator::WriteNvidiaDeviceExecutableRule(
bool useLinkScript = this->GlobalGenerator->GetUseLinkScript();
// Construct the main link rule.
- std::vector<std::string> real_link_commands;
const std::string linkRuleVar = "CMAKE_CUDA_DEVICE_LINK_EXECUTABLE";
const std::string linkRule = this->GetLinkRule(linkRuleVar);
std::vector<std::string> commands1;
- cmExpandList(linkRule, real_link_commands);
+ cmList real_link_commands(linkRule);
bool useResponseFileForObjects =
this->CheckUseResponseFileForObjects(linkLanguage);
@@ -230,12 +232,12 @@ void cmMakefileExecutableTargetGenerator::WriteNvidiaDeviceExecutableRule(
launcher = cmStrCat(val, ' ');
}
- std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
- this->LocalGenerator->CreateRulePlaceholderExpander());
+ auto rulePlaceholderExpander =
+ this->LocalGenerator->CreateRulePlaceholderExpander();
// Expand placeholders in the commands.
rulePlaceholderExpander->SetTargetImpLib(targetOutput);
- for (std::string& real_link_command : real_link_commands) {
+ for (auto& real_link_command : real_link_commands) {
real_link_command = cmStrCat(launcher, real_link_command);
rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator,
real_link_command, vars);
@@ -466,18 +468,18 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
bool useLinkScript = this->GlobalGenerator->GetUseLinkScript();
// Construct the main link rule.
- std::vector<std::string> real_link_commands;
std::string linkRuleVar = this->GeneratorTarget->GetCreateRuleVariable(
linkLanguage, this->GetConfigName());
std::string linkRule = this->GetLinkRule(linkRuleVar);
std::vector<std::string> commands1;
- cmExpandList(linkRule, real_link_commands);
+ cmList real_link_commands(linkRule);
+
if (this->GeneratorTarget->IsExecutableWithExports()) {
// If a separate rule for creating an import library is specified
// add it now.
std::string implibRuleVar =
cmStrCat("CMAKE_", linkLanguage, "_CREATE_IMPORT_LIBRARY");
- this->Makefile->GetDefExpandList(implibRuleVar, real_link_commands);
+ real_link_commands.append(this->Makefile->GetDefinition(implibRuleVar));
}
bool useResponseFileForObjects =
@@ -596,12 +598,12 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
launcher = cmStrCat(val, ' ');
}
- std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
- this->LocalGenerator->CreateRulePlaceholderExpander());
+ auto rulePlaceholderExpander =
+ this->LocalGenerator->CreateRulePlaceholderExpander();
// Expand placeholders in the commands.
rulePlaceholderExpander->SetTargetImpLib(targetOutPathImport);
- for (std::string& real_link_command : real_link_commands) {
+ for (auto& real_link_command : real_link_commands) {
real_link_command = cmStrCat(launcher, real_link_command);
rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator,
real_link_command, vars);
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index 3e4a08ee27..b07a74b568 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -16,6 +16,7 @@
#include "cmGlobalUnixMakefileGenerator3.h"
#include "cmLinkLineComputer.h"
#include "cmLinkLineDeviceComputer.h"
+#include "cmList.h"
#include "cmLocalGenerator.h"
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
@@ -61,6 +62,9 @@ void cmMakefileLibraryTargetGenerator::WriteRuleFiles()
// write in rules for object files and custom commands
this->WriteTargetBuildRules();
+ // Write in the rules for the link dependency file
+ this->WriteTargetLinkDependRules();
+
// write the link rules
// Write the rule for this target type.
switch (this->GeneratorTarget->GetType()) {
@@ -304,7 +308,7 @@ void cmMakefileLibraryTargetGenerator::WriteNvidiaDeviceLibraryRules(
vars.Language = linkLanguage.c_str();
// Expand the rule variables.
- std::vector<std::string> real_link_commands;
+ cmList real_link_commands;
{
// Set path conversion for link script shells.
this->LocalGenerator->SetLinkScriptShell(useLinkScript);
@@ -369,16 +373,16 @@ void cmMakefileLibraryTargetGenerator::WriteNvidiaDeviceLibraryRules(
launcher = cmStrCat(val, ' ');
}
- std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
- this->LocalGenerator->CreateRulePlaceholderExpander());
+ auto rulePlaceholderExpander =
+ this->LocalGenerator->CreateRulePlaceholderExpander();
// Construct the main link rule and expand placeholders.
rulePlaceholderExpander->SetTargetImpLib(targetOutput);
std::string linkRule = this->GetLinkRule(linkRuleVar);
- cmExpandList(linkRule, real_link_commands);
+ real_link_commands.append(linkRule);
// Expand placeholders.
- for (std::string& real_link_command : real_link_commands) {
+ for (auto& real_link_command : real_link_commands) {
real_link_command = cmStrCat(launcher, real_link_command);
rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator,
real_link_command, vars);
@@ -640,9 +644,9 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
// For static libraries there might be archiving rules.
bool haveStaticLibraryRule = false;
- std::vector<std::string> archiveCreateCommands;
- std::vector<std::string> archiveAppendCommands;
- std::vector<std::string> archiveFinishCommands;
+ cmList archiveCreateCommands;
+ cmList archiveAppendCommands;
+ cmList archiveFinishCommands;
std::string::size_type archiveCommandLimit = std::string::npos;
if (this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY) {
haveStaticLibraryRule = this->Makefile->IsDefinitionSet(linkRuleVar);
@@ -652,21 +656,23 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
arCreateVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
arCreateVar, linkLanguage, this->GetConfigName());
- this->Makefile->GetDefExpandList(arCreateVar, archiveCreateCommands);
+ archiveCreateCommands.assign(this->Makefile->GetDefinition(arCreateVar));
+
std::string arAppendVar =
cmStrCat("CMAKE_", linkLanguage, "_ARCHIVE_APPEND");
arAppendVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
arAppendVar, linkLanguage, this->GetConfigName());
- this->Makefile->GetDefExpandList(arAppendVar, archiveAppendCommands);
+ archiveAppendCommands.assign(this->Makefile->GetDefinition(arAppendVar));
+
std::string arFinishVar =
cmStrCat("CMAKE_", linkLanguage, "_ARCHIVE_FINISH");
arFinishVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
arFinishVar, linkLanguage, this->GetConfigName());
- this->Makefile->GetDefExpandList(arFinishVar, archiveFinishCommands);
+ archiveFinishCommands.assign(this->Makefile->GetDefinition(arFinishVar));
}
// Decide whether to use archiving rules.
@@ -690,11 +696,11 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
}
// Expand the rule variables.
- std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
- this->LocalGenerator->CreateRulePlaceholderExpander());
+ auto rulePlaceholderExpander =
+ this->LocalGenerator->CreateRulePlaceholderExpander();
bool useWatcomQuote =
this->Makefile->IsOn(linkRuleVar + "_USE_WATCOM_QUOTE");
- std::vector<std::string> real_link_commands;
+ cmList real_link_commands;
{
// Set path conversion for link script shells.
this->LocalGenerator->SetLinkScriptShell(useLinkScript);
@@ -879,7 +885,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
} else {
// Get the set of commands.
std::string linkRule = this->GetLinkRule(linkRuleVar);
- cmExpandList(linkRule, real_link_commands);
+ real_link_commands.append(linkRule);
if (this->UseLWYU) {
cmValue lwyuCheck =
this->Makefile->GetDefinition("CMAKE_LINK_WHAT_YOU_USE_CHECK");
@@ -895,7 +901,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
}
// Expand placeholders.
- for (std::string& real_link_command : real_link_commands) {
+ for (auto& real_link_command : real_link_commands) {
real_link_command = cmStrCat(launcher, real_link_command);
rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator,
real_link_command, vars);
@@ -965,7 +971,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
this->GeneratorTarget->HasImportLibrary(this->GetConfigName())) {
auto genStubsRule =
this->Makefile->GetDefinition("CMAKE_CREATE_TEXT_STUBS");
- auto genStubs_commands = cmExpandedList(genStubsRule);
+ cmList genStubs_commands{ genStubsRule };
std::string TBDFullPath =
cmStrCat(outpathImp, this->TargetNames.ImportOutput);
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 3112acd578..02cdf57275 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -29,6 +29,7 @@
#include "cmGlobalCommonGenerator.h"
#include "cmGlobalUnixMakefileGenerator3.h"
#include "cmLinkLineComputer.h" // IWYU pragma: keep
+#include "cmList.h"
#include "cmLocalCommonGenerator.h"
#include "cmLocalGenerator.h"
#include "cmLocalUnixMakefileGenerator3.h"
@@ -149,6 +150,8 @@ void cmMakefileTargetGenerator::GetTargetLinkFlags(
this->LocalGenerator->AppendPositionIndependentLinkerFlags(
flags, this->GeneratorTarget, this->GetConfigName(), linkLanguage);
+ this->LocalGenerator->AppendDependencyInfoLinkerFlags(
+ flags, this->GeneratorTarget, this->GetConfigName(), linkLanguage);
}
void cmMakefileTargetGenerator::CreateRuleFile()
@@ -207,27 +210,24 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
// -- Write the custom commands for this target
// Evaluates generator expressions and expands prop_value
- auto evaluatedFiles =
- [this](const std::string& prop_value) -> std::vector<std::string> {
- std::vector<std::string> files;
- cmExpandList(cmGeneratorExpression::Evaluate(
- prop_value, this->LocalGenerator, this->GetConfigName(),
- this->GeneratorTarget),
- files);
+ auto evaluatedFiles = [this](const std::string& prop_value) -> cmList {
+ cmList files{ cmGeneratorExpression::Evaluate(
+ prop_value, this->LocalGenerator, this->GetConfigName(),
+ this->GeneratorTarget) };
return files;
};
// Look for additional files registered for cleaning in this directory.
if (cmValue prop_value =
this->Makefile->GetProperty("ADDITIONAL_MAKE_CLEAN_FILES")) {
- std::vector<std::string> const files = evaluatedFiles(*prop_value);
+ auto const files = evaluatedFiles(*prop_value);
this->CleanFiles.insert(files.begin(), files.end());
}
// Look for additional files registered for cleaning in this target.
if (cmValue prop_value =
this->GeneratorTarget->GetProperty("ADDITIONAL_CLEAN_FILES")) {
- std::vector<std::string> const files = evaluatedFiles(*prop_value);
+ auto const files = evaluatedFiles(*prop_value);
// For relative path support
std::string const& binaryDir =
this->LocalGenerator->GetCurrentBinaryDirectory();
@@ -416,8 +416,10 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules()
this->GlobalGenerator->SupportsCompilerDependencies() &&
(!this->Makefile->IsDefinitionSet(depsUseCompiler) ||
this->Makefile->IsOn(depsUseCompiler));
+ bool linkerGenerateDeps =
+ this->GeneratorTarget->HasLinkDependencyFile(this->GetConfigName());
- if (compilerGenerateDeps || ccGenerateDeps) {
+ if (compilerGenerateDeps || linkerGenerateDeps || ccGenerateDeps) {
std::string compilerDependFile =
cmStrCat(this->TargetBuildDirectoryFull, "/compiler_depend.make");
*this->BuildFileStream << "# Include any dependencies generated by the "
@@ -965,8 +967,8 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
bool const lang_has_assembly = lang_has_preprocessor;
bool const lang_can_export_cmds = lang_has_preprocessor;
- std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
- this->LocalGenerator->CreateRulePlaceholderExpander());
+ auto rulePlaceholderExpander =
+ this->LocalGenerator->CreateRulePlaceholderExpander();
// Construct the compile rules.
{
@@ -1002,10 +1004,10 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
vars.CudaCompileMode = cudaCompileMode.c_str();
}
- std::vector<std::string> compileCommands;
+ cmList compileCommands;
const std::string& compileRule = this->Makefile->GetRequiredDefinition(
"CMAKE_" + lang + "_COMPILE_OBJECT");
- cmExpandList(compileRule, compileCommands);
+ compileCommands.assign(compileRule);
if (this->GeneratorTarget->GetPropertyAsBool("EXPORT_COMPILE_COMMANDS") &&
lang_can_export_cmds && compileCommands.size() == 1) {
@@ -1200,7 +1202,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
// If compiler launcher was specified and not consumed above, it
// goes to the beginning of the command line.
if (!compileCommands.empty() && !compilerLauncher.empty()) {
- std::vector<std::string> args = cmExpandedList(compilerLauncher, true);
+ cmList args{ compilerLauncher, cmList::EmptyElements::Yes };
if (!args.empty()) {
args[0] = this->LocalGenerator->ConvertToOutputFormat(
args[0], cmOutputConverter::SHELL);
@@ -1208,7 +1210,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
i = this->LocalGenerator->EscapeForShell(i);
}
}
- compileCommands.front().insert(0, cmJoin(args, " ") + " ");
+ compileCommands.front().insert(0, args.join(" ") + " ");
}
std::string launcher;
@@ -1240,9 +1242,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
const auto& extraCommands = this->Makefile->GetSafeDefinition(
cmStrCat("CMAKE_", lang, "_DEPENDS_EXTRA_COMMANDS"));
if (!extraCommands.empty()) {
- auto commandList = cmExpandedList(extraCommands);
- compileCommands.insert(compileCommands.end(), commandList.cbegin(),
- commandList.cend());
+ compileCommands.append(extraCommands);
}
const auto& depFormat = this->Makefile->GetRequiredDefinition(
@@ -1283,14 +1283,15 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
}
// Check for extra outputs created by the compilation.
- std::vector<std::string> outputs(1, relativeObj);
+ cmList outputs;
+ outputs.emplace_back(relativeObj);
if (cmValue extra_outputs_str = source.GetProperty("OBJECT_OUTPUTS")) {
std::string evaluated_outputs = cmGeneratorExpression::Evaluate(
*extra_outputs_str, this->LocalGenerator, config);
if (!evaluated_outputs.empty()) {
// Register these as extra files to clean.
- cmExpandList(evaluated_outputs, outputs);
+ outputs.append(evaluated_outputs);
}
}
if (!ispcHeaderRelative.empty()) {
@@ -1341,8 +1342,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
cmStrCat("CMAKE_", lang, "_CREATE_PREPROCESSED_SOURCE");
if (cmValue preprocessRule =
this->Makefile->GetDefinition(preprocessRuleVar)) {
- std::vector<std::string> preprocessCommands =
- cmExpandedList(*preprocessRule);
+ cmList preprocessCommands{ *preprocessRule };
std::string shellObjI = this->LocalGenerator->ConvertToOutputFormat(
objI, cmOutputConverter::SHELL);
@@ -1386,8 +1386,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
cmStrCat("CMAKE_", lang, "_CREATE_ASSEMBLY_SOURCE");
if (cmValue assemblyRule =
this->Makefile->GetDefinition(assemblyRuleVar)) {
- std::vector<std::string> assemblyCommands =
- cmExpandedList(*assemblyRule);
+ cmList assemblyCommands{ *assemblyRule };
std::string shellObjS = this->LocalGenerator->ConvertToOutputFormat(
objS, cmOutputConverter::SHELL);
@@ -1504,6 +1503,21 @@ bool cmMakefileTargetGenerator::WriteMakeRule(
return symbolic;
}
+void cmMakefileTargetGenerator::WriteTargetLinkDependRules()
+{
+ if (!this->GeneratorTarget->HasLinkDependencyFile(this->GetConfigName())) {
+ return;
+ }
+
+ auto depFile = this->LocalGenerator->GetLinkDependencyFile(
+ this->GeneratorTarget, this->GetConfigName());
+ this->CleanFiles.insert(depFile);
+ this->LocalGenerator->AddImplicitDepends(
+ this->GeneratorTarget, "LINK",
+ this->GeneratorTarget->GetFullPath(this->GetConfigName()), depFile,
+ cmDependencyScannerKind::Compiler);
+}
+
void cmMakefileTargetGenerator::WriteTargetDependRules()
{
// must write the targets depend info file
@@ -1674,7 +1688,7 @@ void cmMakefileTargetGenerator::WriteDeviceLinkRule(
}
cmLocalUnixMakefileGenerator3* localGen{ this->LocalGenerator };
- std::vector<std::string> architectures = cmExpandedList(architecturesStr);
+ cmList architectures{ architecturesStr };
std::string const& relPath = localGen->GetHomeRelativeOutputPath();
// Ensure there are no duplicates.
@@ -1775,8 +1789,7 @@ void cmMakefileTargetGenerator::WriteDeviceLinkRule(
vars.Flags = flags.c_str();
std::string compileCmd = this->GetLinkRule("CMAKE_CUDA_DEVICE_LINK_COMPILE");
- std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
- localGen->CreateRulePlaceholderExpander());
+ auto rulePlaceholderExpander = localGen->CreateRulePlaceholderExpander();
rulePlaceholderExpander->ExpandRuleVariables(localGen, compileCmd, vars);
commands.emplace_back(compileCmd);
@@ -2057,8 +2070,14 @@ void cmMakefileTargetGenerator::AppendTargetDepends(
return;
}
- // Loop over all library dependencies.
const std::string& cfg = this->GetConfigName();
+
+ if (this->GeneratorTarget->HasLinkDependencyFile(cfg)) {
+ depends.push_back(
+ cmStrCat(this->TargetBuildDirectoryFull, "/compiler_depend.ts"));
+ }
+
+ // Loop over all library dependencies.
if (cmComputeLinkInformation* cli =
this->GeneratorTarget->GetLinkInformation(cfg)) {
cm::append(depends, cli->GetDepends());
diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h
index 98c3a0e8db..ef7a60fa62 100644
--- a/Source/cmMakefileTargetGenerator.h
+++ b/Source/cmMakefileTargetGenerator.h
@@ -77,6 +77,8 @@ protected:
// write the clean rules for this target
void WriteTargetCleanRules();
+ // write the linker depend rules for this target
+ void WriteTargetLinkDependRules();
// write the depend rules for this target
void WriteTargetDependRules();
diff --git a/Source/cmMessageCommand.cxx b/Source/cmMessageCommand.cxx
index 52373f3160..baf40f8258 100644
--- a/Source/cmMessageCommand.cxx
+++ b/Source/cmMessageCommand.cxx
@@ -10,6 +10,7 @@
#include "cmConfigureLog.h"
#include "cmExecutionStatus.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmMessenger.h"
@@ -31,13 +32,13 @@ enum class CheckingType
std::string IndentText(std::string text, cmMakefile& mf)
{
auto indent =
- cmJoin(cmExpandedList(mf.GetSafeDefinition("CMAKE_MESSAGE_INDENT")), "");
+ cmList{ mf.GetSafeDefinition("CMAKE_MESSAGE_INDENT") }.join("");
const auto showContext = mf.GetCMakeInstance()->GetShowLogContext() ||
mf.IsOn("CMAKE_MESSAGE_CONTEXT_SHOW");
if (showContext) {
- auto context = cmJoin(
- cmExpandedList(mf.GetSafeDefinition("CMAKE_MESSAGE_CONTEXT")), ".");
+ auto context =
+ cmList{ mf.GetSafeDefinition("CMAKE_MESSAGE_CONTEXT") }.join(".");
if (!context.empty()) {
indent.insert(0u, cmStrCat("["_s, context, "] "_s));
}
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index 4d68460521..063ca6ba6a 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -23,6 +23,7 @@
#include "cmGlobalNinjaGenerator.h"
#include "cmLinkLineComputer.h"
#include "cmLinkLineDeviceComputer.h"
+#include "cmList.h"
#include "cmLocalCommonGenerator.h"
#include "cmLocalGenerator.h"
#include "cmLocalNinjaGenerator.h"
@@ -213,6 +214,22 @@ std::string cmNinjaNormalTargetGenerator::TextStubsGeneratorRule(
'_', config);
}
+bool cmNinjaNormalTargetGenerator::CheckUseResponseFileForLibraries(
+ const std::string& l) const
+{
+ // Check for an explicit setting one way or the other.
+ std::string const responseVar =
+ "CMAKE_" + l + "_USE_RESPONSE_FILE_FOR_LIBRARIES";
+
+ // If the option is defined, read it's value
+ if (cmValue val = this->Makefile->GetDefinition(responseVar)) {
+ return val.IsOn();
+ }
+
+ // Default to true
+ return true;
+}
+
struct cmNinjaRemoveNoOpCommands
{
bool operator()(std::string const& cmd)
@@ -251,9 +268,16 @@ void cmNinjaNormalTargetGenerator::WriteNvidiaDeviceLinkRule(
} else {
rule.RspContent = "$in_newline";
}
- rule.RspContent += " $LINK_LIBRARIES";
+
+ // add the link command in the file if necessary
+ if (this->CheckUseResponseFileForLibraries("CUDA")) {
+ rule.RspContent += " $LINK_LIBRARIES";
+ vars.LinkLibraries = "";
+ } else {
+ vars.LinkLibraries = "$LINK_PATH $LINK_LIBRARIES";
+ }
+
vars.Objects = responseFlag.c_str();
- vars.LinkLibraries = "";
}
vars.ObjectDir = "$OBJECT_DIR";
@@ -278,8 +302,8 @@ void cmNinjaNormalTargetGenerator::WriteNvidiaDeviceLinkRule(
launcher = cmStrCat(val, ' ');
}
- std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
- this->GetLocalGenerator()->CreateRulePlaceholderExpander());
+ auto rulePlaceholderExpander =
+ this->GetLocalGenerator()->CreateRulePlaceholderExpander();
// Rule for linking library/executable.
std::vector<std::string> linkCmds = this->ComputeDeviceLinkCmd();
@@ -338,8 +362,8 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkRules(
std::string compileCmd = this->GetMakefile()->GetRequiredDefinition(
"CMAKE_CUDA_DEVICE_LINK_COMPILE");
- std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
- this->GetLocalGenerator()->CreateRulePlaceholderExpander());
+ auto rulePlaceholderExpander =
+ this->GetLocalGenerator()->CreateRulePlaceholderExpander();
rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(),
compileCmd, vars);
@@ -393,6 +417,13 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile,
std::string cmakeVarLang =
cmStrCat("CMAKE_", this->TargetLinkLanguage(config));
+ if (this->GeneratorTarget->HasLinkDependencyFile(config)) {
+ auto DepFileFormat = this->GetMakefile()->GetDefinition(
+ cmStrCat(cmakeVarLang, "_LINKER_DEPFILE_FORMAT"));
+ rule.DepType = DepFileFormat;
+ rule.DepFile = "$DEP_FILE";
+ }
+
// build response file name
std::string cmakeLinkVar = cmakeVarLang + "_RESPONSE_FILE_LINK_FLAG";
cmValue flag = this->GetMakefile()->GetDefinition(cmakeLinkVar);
@@ -416,13 +447,20 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile,
} else {
rule.RspContent = "$in_newline";
}
- rule.RspContent += " $LINK_PATH $LINK_LIBRARIES";
+
+ // If libraries in rsp is enable
+ if (this->CheckUseResponseFileForLibraries(lang)) {
+ rule.RspContent += " $LINK_PATH $LINK_LIBRARIES";
+ vars.LinkLibraries = "";
+ } else {
+ vars.LinkLibraries = "$LINK_PATH $LINK_LIBRARIES";
+ }
+
if (this->TargetLinkLanguage(config) == "Swift") {
vars.SwiftSources = responseFlag.c_str();
} else {
vars.Objects = responseFlag.c_str();
}
- vars.LinkLibraries = "";
}
vars.ObjectDir = "$OBJECT_DIR";
@@ -473,8 +511,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile,
launcher = cmStrCat(val, ' ');
}
- std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
- this->GetLocalGenerator()->CreateRulePlaceholderExpander());
+ auto rulePlaceholderExpander =
+ this->GetLocalGenerator()->CreateRulePlaceholderExpander();
// Rule for linking library/executable.
std::vector<std::string> linkCmds = this->ComputeLinkCmd(config);
@@ -546,8 +584,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile,
std::string cmd =
this->GetMakefile()->GetDefinition("CMAKE_CREATE_TEXT_STUBS");
- std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
- this->GetLocalGenerator()->CreateRulePlaceholderExpander());
+ auto rulePlaceholderExpander =
+ this->GetLocalGenerator()->CreateRulePlaceholderExpander();
cmRulePlaceholderExpander::RuleVariables vars;
vars.Target = "$in";
rulePlaceholderExpander->SetTargetImpLib("$out");
@@ -579,7 +617,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile,
std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeDeviceLinkCmd()
{
- std::vector<std::string> linkCmds;
+ cmList linkCmds;
// this target requires separable cuda compilation
// now build the correct command depending on if the target is
@@ -588,23 +626,23 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeDeviceLinkCmd()
case cmStateEnums::STATIC_LIBRARY:
case cmStateEnums::SHARED_LIBRARY:
case cmStateEnums::MODULE_LIBRARY: {
- this->GetMakefile()->GetDefExpandList("CMAKE_CUDA_DEVICE_LINK_LIBRARY",
- linkCmds);
+ linkCmds.assign(
+ this->GetMakefile()->GetDefinition("CMAKE_CUDA_DEVICE_LINK_LIBRARY"));
} break;
case cmStateEnums::EXECUTABLE: {
- this->GetMakefile()->GetDefExpandList(
- "CMAKE_CUDA_DEVICE_LINK_EXECUTABLE", linkCmds);
+ linkCmds.assign(this->GetMakefile()->GetDefinition(
+ "CMAKE_CUDA_DEVICE_LINK_EXECUTABLE"));
} break;
default:
break;
}
- return linkCmds;
+ return std::move(linkCmds.data());
}
std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd(
const std::string& config)
{
- std::vector<std::string> linkCmds;
+ cmList linkCmds;
cmMakefile* mf = this->GetMakefile();
{
// If we have a rule variable prefer it. In the case of static libraries
@@ -623,7 +661,7 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd(
linkCmdStr += *rule;
}
}
- cmExpandList(linkCmdStr, linkCmds);
+ linkCmds.assign(linkCmdStr);
if (this->UseLWYU) {
cmValue lwyuCheck = mf->GetDefinition("CMAKE_LINK_WHAT_YOU_USE_CHECK");
if (lwyuCheck) {
@@ -642,7 +680,7 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd(
linkCmds.push_back(std::move(cmakeCommand));
}
}
- return linkCmds;
+ return std::move(linkCmds.data());
}
}
switch (this->GetGeneratorTarget()->GetType()) {
@@ -663,7 +701,7 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd(
linkCmdVar, this->TargetLinkLanguage(config), config);
std::string const& linkCmd = mf->GetRequiredDefinition(linkCmdVar);
- cmExpandList(linkCmd, linkCmds);
+ linkCmds.append(linkCmd);
}
{
std::string linkCmdVar = cmStrCat(
@@ -673,7 +711,7 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd(
linkCmdVar, this->TargetLinkLanguage(config), config);
std::string const& linkCmd = mf->GetRequiredDefinition(linkCmdVar);
- cmExpandList(linkCmd, linkCmds);
+ linkCmds.append(linkCmd);
}
#ifdef __APPLE__
// On macOS ranlib truncates the fractional part of the static archive
@@ -697,7 +735,7 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd(
default:
assert(false && "Unexpected target type");
}
- return linkCmds;
+ return std::move(linkCmds.data());
}
void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement(
@@ -754,7 +792,7 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement(
}
this->WriteDeviceLinkRules(config);
- this->WriteDeviceLinkStatements(config, cmExpandedList(architecturesStr),
+ this->WriteDeviceLinkStatements(config, cmList{ architecturesStr },
targetOutputReal);
} else {
this->WriteNvidiaDeviceLinkStatement(config, fileConfig, targetOutputDir,
@@ -1103,6 +1141,14 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
cmNinjaBuild linkBuild(this->LanguageLinkerRule(config));
cmNinjaVars& vars = linkBuild.Variables;
+ if (this->GeneratorTarget->HasLinkDependencyFile(config)) {
+ vars["DEP_FILE"] = this->GetLocalGenerator()->ConvertToOutputFormat(
+ this->ConvertToNinjaPath(
+ this->GetLocalGenerator()->GetLinkDependencyFile(this->GeneratorTarget,
+ config)),
+ cmOutputConverter::SHELL);
+ }
+
// Compute the comment.
linkBuild.Comment =
cmStrCat("Link the ", this->GetVisibleTypeName(), ' ', targetOutputReal);
diff --git a/Source/cmNinjaNormalTargetGenerator.h b/Source/cmNinjaNormalTargetGenerator.h
index 85f42a4487..187ea4627a 100644
--- a/Source/cmNinjaNormalTargetGenerator.h
+++ b/Source/cmNinjaNormalTargetGenerator.h
@@ -26,7 +26,7 @@ private:
const std::string& config) const;
std::string LanguageLinkerCudaFatbinaryRule(const std::string& config) const;
std::string TextStubsGeneratorRule(const std::string& config) const;
-
+ bool CheckUseResponseFileForLibraries(const std::string& config) const;
const char* GetVisibleTypeName() const;
void WriteLanguagesRules(const std::string& config);
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 5dbc283fac..4ed491d33c 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -9,6 +9,7 @@
#include <iterator>
#include <map>
#include <ostream>
+#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <utility>
@@ -21,8 +22,6 @@
#include <cm3p/json/value.h>
#include <cm3p/json/writer.h>
-#include "cmsys/RegularExpression.hxx"
-
#include "cmComputeLinkInformation.h"
#include "cmCustomCommandGenerator.h"
#include "cmDyndepCollation.h"
@@ -32,6 +31,7 @@
#include "cmGeneratorTarget.h"
#include "cmGlobalCommonGenerator.h"
#include "cmGlobalNinjaGenerator.h"
+#include "cmList.h"
#include "cmLocalGenerator.h"
#include "cmLocalNinjaGenerator.h"
#include "cmMakefile.h"
@@ -665,8 +665,8 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
std::string const modmapFormat =
this->Makefile->GetSafeDefinition(modmapFormatVar);
- std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
- this->GetLocalGenerator()->CreateRulePlaceholderExpander());
+ auto rulePlaceholderExpander =
+ this->GetLocalGenerator()->CreateRulePlaceholderExpander();
std::string const tdi = this->GetLocalGenerator()->ConvertToOutputFormat(
this->ConvertToNinjaPath(this->GetTargetDependInfoPath(lang, config)),
@@ -689,7 +689,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
// Rule to scan dependencies of sources that need preprocessing.
{
- std::vector<std::string> scanCommands;
+ cmList scanCommands;
std::string scanRuleName;
std::string ppFileName;
if (compilationPreprocesses) {
@@ -697,8 +697,8 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
ppFileName = "$PREPROCESSED_OUTPUT_FILE";
std::string const& scanCommand = mf->GetRequiredDefinition(
cmStrCat("CMAKE_EXPERIMENTAL_", lang, "_SCANDEP_SOURCE"));
- cmExpandList(scanCommand, scanCommands);
- for (std::string& i : scanCommands) {
+ scanCommands.assign(scanCommand);
+ for (auto& i : scanCommands) {
i = cmStrCat(launcher, i);
}
} else {
@@ -706,8 +706,8 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
ppFileName = "$out";
std::string const& ppCommmand = mf->GetRequiredDefinition(
cmStrCat("CMAKE_", lang, "_PREPROCESS_SOURCE"));
- cmExpandList(ppCommmand, scanCommands);
- for (std::string& i : scanCommands) {
+ scanCommands.assign(ppCommmand);
+ for (auto& i : scanCommands) {
i = cmStrCat(launcher, i);
}
scanCommands.emplace_back(GetScanCommand(cmakeCmd, tdi, lang, "$out",
@@ -886,10 +886,9 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
}
// Rule for compiling object file.
- std::vector<std::string> compileCmds;
const std::string cmdVar = cmStrCat("CMAKE_", lang, "_COMPILE_OBJECT");
const std::string& compileCmd = mf->GetRequiredDefinition(cmdVar);
- cmExpandList(compileCmd, compileCmds);
+ cmList compileCmds(compileCmd);
// See if we need to use a compiler launcher like ccache or distcc
std::string compilerLauncher;
@@ -1038,7 +1037,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
// If compiler launcher was specified and not consumed above, it
// goes to the beginning of the command line.
if (!compileCmds.empty() && !compilerLauncher.empty()) {
- std::vector<std::string> args = cmExpandedList(compilerLauncher, true);
+ cmList args{ compilerLauncher, cmList::EmptyElements::Yes };
if (!args.empty()) {
args[0] = this->LocalGenerator->ConvertToOutputFormat(
args[0], cmOutputConverter::SHELL);
@@ -1046,7 +1045,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
i = this->LocalGenerator->EscapeForShell(i);
}
}
- compileCmds.front().insert(0, cmStrCat(cmJoin(args, " "), ' '));
+ compileCmds.front().insert(0, cmStrCat(args.join(" "), ' '));
}
if (!compileCmds.empty()) {
@@ -1056,12 +1055,10 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
const auto& extraCommands = this->GetMakefile()->GetSafeDefinition(
cmStrCat("CMAKE_", lang, "_DEPENDS_EXTRA_COMMANDS"));
if (!extraCommands.empty()) {
- auto commandList = cmExpandedList(extraCommands);
- compileCmds.insert(compileCmds.end(), commandList.cbegin(),
- commandList.cend());
+ compileCmds.append(extraCommands);
}
- for (std::string& i : compileCmds) {
+ for (auto& i : compileCmds) {
i = cmStrCat(launcher, i);
rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(), i,
vars);
@@ -1261,7 +1258,6 @@ namespace {
cmNinjaBuild GetScanBuildStatement(const std::string& ruleName,
const std::string& ppFileName,
bool compilePP, bool compilePPWithDefines,
- cmValue ppExcludeFlagsRegex,
cmNinjaBuild& objBuild, cmNinjaVars& vars,
const std::string& objectFileName,
cmLocalGenerator* lg)
@@ -1290,20 +1286,6 @@ cmNinjaBuild GetScanBuildStatement(const std::string& ruleName,
// Scanning and compilation generally use the same flags.
scanBuild.Variables["FLAGS"] = vars["FLAGS"];
- // Exclude flags not valid during preprocessing.
- if (compilePP && !ppExcludeFlagsRegex.IsEmpty()) {
- std::string in = std::move(scanBuild.Variables["FLAGS"]);
- std::string out;
- cmsys::RegularExpression regex(*ppExcludeFlagsRegex);
- std::string::size_type pos = 0;
- while (regex.find(in.c_str() + pos)) {
- out = cmStrCat(out, in.substr(pos, regex.start()), ' ');
- pos += regex.end();
- }
- out = cmStrCat(out, in.substr(pos));
- scanBuild.Variables["FLAGS"] = std::move(out);
- }
-
if (compilePP && !compilePPWithDefines) {
// Move preprocessor definitions to the scan/preprocessor build statement.
std::swap(scanBuild.Variables["DEFINES"], vars["DEFINES"]);
@@ -1468,7 +1450,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
}
if (cmValue objectDeps = source->GetProperty("OBJECT_DEPENDS")) {
- std::vector<std::string> objDepList = cmExpandedList(*objectDeps);
+ cmList objDepList{ *objectDeps };
std::copy(objDepList.begin(), objDepList.end(),
std::back_inserter(depList));
}
@@ -1528,22 +1510,18 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
std::string scanRuleName;
std::string ppFileName;
- cmValue ppExcludeFlagsRegex;
if (compilePP) {
scanRuleName = this->LanguagePreprocessAndScanRule(language, config);
ppFileName = this->ConvertToNinjaPath(
this->GetPreprocessedFilePath(source, config));
- ppExcludeFlagsRegex = this->Makefile->GetDefinition(cmStrCat(
- "CMAKE_", language, "_PREPROCESS_SOURCE_EXCLUDE_FLAGS_REGEX"));
} else {
scanRuleName = this->LanguageScanRule(language, config);
ppFileName = cmStrCat(objectFileName, ".ddi.i");
}
cmNinjaBuild ppBuild = GetScanBuildStatement(
- scanRuleName, ppFileName, compilePP, compilePPWithDefines,
- ppExcludeFlagsRegex, objBuild, vars, objectFileName,
- this->LocalGenerator);
+ scanRuleName, ppFileName, compilePP, compilePPWithDefines, objBuild,
+ vars, objectFileName, this->LocalGenerator);
if (compilePP) {
// In case compilation requires flags that are incompatible with
@@ -1688,7 +1666,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
if (!evaluatedObjectOutputs.empty()) {
cmNinjaBuild build("phony");
build.Comment = "Additional output files.";
- build.Outputs = cmExpandedList(evaluatedObjectOutputs);
+ build.Outputs = cmList{ evaluatedObjectOutputs }.data();
std::transform(build.Outputs.begin(), build.Outputs.end(),
build.Outputs.begin(), this->MapToNinjaPath());
build.ExplicitDeps = objBuild.Outputs;
@@ -1882,16 +1860,15 @@ void cmNinjaTargetGenerator::ExportObjectCompileCommand(
compileObjectVars.CudaCompileMode = cudaCompileMode.c_str();
}
- std::vector<std::string> compileCmds;
const std::string cmdVar = cmStrCat("CMAKE_", language, "_COMPILE_OBJECT");
const std::string& compileCmd =
this->Makefile->GetRequiredDefinition(cmdVar);
- cmExpandList(compileCmd, compileCmds);
+ cmList compileCmds(compileCmd);
- std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
- this->GetLocalGenerator()->CreateRulePlaceholderExpander());
+ auto rulePlaceholderExpander =
+ this->GetLocalGenerator()->CreateRulePlaceholderExpander();
- for (std::string& i : compileCmds) {
+ for (auto& i : compileCmds) {
// no launcher for CMAKE_EXPORT_COMPILE_COMMANDS
rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(), i,
compileObjectVars);
@@ -1909,13 +1886,11 @@ void cmNinjaTargetGenerator::AdditionalCleanFiles(const std::string& config)
if (cmValue prop_value =
this->GeneratorTarget->GetProperty("ADDITIONAL_CLEAN_FILES")) {
cmLocalNinjaGenerator* lg = this->LocalGenerator;
- std::vector<std::string> cleanFiles;
- cmExpandList(cmGeneratorExpression::Evaluate(*prop_value, lg, config,
- this->GeneratorTarget),
- cleanFiles);
+ cmList cleanFiles(cmGeneratorExpression::Evaluate(*prop_value, lg, config,
+ this->GeneratorTarget));
std::string const& binaryDir = lg->GetCurrentBinaryDirectory();
cmGlobalNinjaGenerator* gg = lg->GetGlobalNinjaGenerator();
- for (std::string const& cleanFile : cleanFiles) {
+ for (auto const& cleanFile : cleanFiles) {
// Support relative paths
gg->AddAdditionalCleanFile(
cmSystemTools::CollapseFullPath(cleanFile, binaryDir), config);
diff --git a/Source/cmOutputConverter.cxx b/Source/cmOutputConverter.cxx
index 6c54e01e3d..53cb21e59d 100644
--- a/Source/cmOutputConverter.cxx
+++ b/Source/cmOutputConverter.cxx
@@ -6,16 +6,15 @@
#include <cassert>
#include <cctype>
#include <set>
-#include <vector>
#ifdef _WIN32
# include <unordered_map>
# include <utility>
#endif
+#include "cmList.h"
#include "cmState.h"
#include "cmStateDirectory.h"
-#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"
@@ -176,7 +175,12 @@ std::string cmOutputConverter::ConvertToOutputForExisting(
}
std::string tmp{};
- cmSystemTools::GetShortPath(remote, tmp);
+ cmsys::Status status = cmSystemTools::GetShortPath(remote, tmp);
+ if (!status) {
+ // Fallback for cases when Windows refuses to resolve the short path,
+ // like for C:\Program Files\WindowsApps\...
+ tmp = remote;
+ }
shortPathCache[remote] = tmp;
return tmp;
}();
@@ -319,7 +323,7 @@ cmOutputConverter::FortranFormat cmOutputConverter::GetFortranFormat(
{
FortranFormat format = FortranFormatNone;
if (!value.empty()) {
- for (std::string const& fi : cmExpandedList(value)) {
+ for (std::string const& fi : cmList(value)) {
if (fi == "FIXED") {
format = FortranFormatFixed;
}
diff --git a/Source/cmOutputConverter.h b/Source/cmOutputConverter.h
index 2717bdd1c2..625d89768c 100644
--- a/Source/cmOutputConverter.h
+++ b/Source/cmOutputConverter.h
@@ -16,6 +16,7 @@ class cmOutputConverter
{
public:
cmOutputConverter(cmStateSnapshot const& snapshot);
+ virtual ~cmOutputConverter() = default;
/**
* Convert the given remote path to a relative path with respect to
@@ -27,6 +28,15 @@ public:
std::string MaybeRelativeToTopBinDir(std::string const& path) const;
std::string MaybeRelativeToCurBinDir(std::string const& path) const;
+ /**
+ * The effective working directory can be different for each generator.
+ * By default, equivalent to the current binary directory.
+ */
+ virtual std::string MaybeRelativeToWorkDir(std::string const& path) const
+ {
+ return this->MaybeRelativeToCurBinDir(path);
+ }
+
std::string const& GetRelativePathTopSource() const;
std::string const& GetRelativePathTopBinary() const;
void SetRelativePathTop(std::string const& topSource,
diff --git a/Source/cmOutputRequiredFilesCommand.cxx b/Source/cmOutputRequiredFilesCommand.cxx
index ad276d2f70..f147ed22de 100644
--- a/Source/cmOutputRequiredFilesCommand.cxx
+++ b/Source/cmOutputRequiredFilesCommand.cxx
@@ -14,6 +14,7 @@
#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"
#include "cmStringAlgorithms.h"
@@ -126,9 +127,9 @@ public:
std::string incDirs = cmGeneratorExpression::Preprocess(
*incDirProp, cmGeneratorExpression::StripAllGeneratorExpressions);
- std::vector<std::string> includes = cmExpandedList(incDirs);
+ cmList includes{ incDirs };
- for (std::string& path : includes) {
+ for (auto& path : includes) {
this->Makefile->ExpandVariablesInString(path);
if (uniqueIncludes.insert(path).second) {
orderedAndUniqueIncludes.push_back(path);
diff --git a/Source/cmParseArgumentsCommand.cxx b/Source/cmParseArgumentsCommand.cxx
index 7e195664e2..b0462f056a 100644
--- a/Source/cmParseArgumentsCommand.cxx
+++ b/Source/cmParseArgumentsCommand.cxx
@@ -12,6 +12,7 @@
#include "cmArgumentParser.h"
#include "cmArgumentParserTypes.h"
#include "cmExecutionStatus.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmRange.h"
@@ -169,17 +170,15 @@ bool cmParseArgumentsCommand(std::vector<std::string> const& args,
};
// the second argument is a (cmake) list of options without argument
- std::vector<std::string> list = cmExpandedList(*argIter++);
+ cmList list{ *argIter++ };
parser.Bind(list, options, duplicateKey);
// the third argument is a (cmake) list of single argument options
- list.clear();
- cmExpandList(*argIter++, list);
+ list.assign(*argIter++);
parser.Bind(list, singleValArgs, duplicateKey);
// the fourth argument is a (cmake) list of multi argument options
- list.clear();
- cmExpandList(*argIter++, list);
+ list.assign(*argIter++);
parser.Bind(list, multiValArgs, duplicateKey);
list.clear();
@@ -187,7 +186,7 @@ bool cmParseArgumentsCommand(std::vector<std::string> const& args,
// Flatten ;-lists in the arguments into a single list as was done
// by the original function(CMAKE_PARSE_ARGUMENTS).
for (; argIter != argEnd; ++argIter) {
- cmExpandList(*argIter, list);
+ list.append(*argIter);
}
} else {
// in the PARSE_ARGV move read the arguments from ARGC and ARGV#
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index fe883826aa..a0030d3dc1 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -450,7 +450,16 @@ class cmMakefile;
27, 0, cmPolicies::WARN) \
SELECT(POLICY, CMP0149, \
"Visual Studio generators select latest Windows SDK by default.", 3, \
- 27, 0, cmPolicies::WARN)
+ 27, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0150, \
+ "ExternalProject_Add and FetchContent_Declare commands " \
+ "treat relative GIT_REPOSITORY paths as being relative " \
+ "to the parent project's remote.", \
+ 3, 27, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0151, \
+ "AUTOMOC include directory is a system include directory by " \
+ "default.", \
+ 3, 27, 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/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx
index 782c154653..d897f0e5be 100644
--- a/Source/cmQtAutoGenInitializer.cxx
+++ b/Source/cmQtAutoGenInitializer.cxx
@@ -35,6 +35,7 @@
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmLinkItem.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
@@ -507,7 +508,7 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
std::string const& deps =
this->GenTarget->GetSafeProperty("AUTOGEN_TARGET_DEPENDS");
if (!deps.empty()) {
- for (std::string const& depName : cmExpandedList(deps)) {
+ for (auto const& depName : cmList{ deps }) {
// Allow target and file dependencies
auto* depTarget = this->Makefile->FindTargetToUse(depName);
if (depTarget) {
@@ -545,8 +546,8 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
this->Moc.MacroNames.erase(cmRemoveDuplicates(this->Moc.MacroNames),
this->Moc.MacroNames.end());
{
- auto filterList = cmExpandedList(
- this->GenTarget->GetSafeProperty("AUTOMOC_DEPEND_FILTERS"));
+ cmList filterList = { this->GenTarget->GetSafeProperty(
+ "AUTOMOC_DEPEND_FILTERS") };
if ((filterList.size() % 2) != 0) {
cmSystemTools::Error(
cmStrCat("AutoMoc: AUTOMOC_DEPEND_FILTERS predefs size ",
@@ -558,7 +559,7 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
"Q_PLUGIN_METADATA",
"[\n][ \t]*Q_PLUGIN_METADATA[ \t]*\\("
"[^\\)]*FILE[ \t]*\"([^\"]+)\"");
- for (std::size_t ii = 0; ii != filterList.size(); ii += 2) {
+ for (cmList::size_type ii = 0; ii != filterList.size(); ii += 2) {
this->Moc.DependFilters.emplace_back(filterList[ii],
filterList[ii + 1]);
}
@@ -573,7 +574,31 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
// Add autogen include directory to the origin target INCLUDE_DIRECTORIES
if (this->MocOrUicEnabled() || (this->Rcc.Enabled && this->MultiConfig)) {
- this->GenTarget->AddIncludeDirectory(this->Dir.IncludeGenExp, true);
+ auto addBefore = false;
+ auto const& value =
+ this->GenTarget->GetProperty("AUTOGEN_USE_SYSTEM_INCLUDE");
+ if (value.IsSet()) {
+ if (cmIsOn(value)) {
+ this->GenTarget->AddSystemIncludeDirectory(this->Dir.IncludeGenExp,
+ "CXX");
+ } else {
+ addBefore = true;
+ }
+ } else {
+ switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0151)) {
+ case cmPolicies::WARN:
+ case cmPolicies::OLD:
+ addBefore = true;
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::NEW:
+ this->GenTarget->AddSystemIncludeDirectory(this->Dir.IncludeGenExp,
+ "CXX");
+ break;
+ }
+ }
+ this->GenTarget->AddIncludeDirectory(this->Dir.IncludeGenExp, addBefore);
}
// Scan files
@@ -613,8 +638,9 @@ bool cmQtAutoGenInitializer::InitMoc()
if (this->GenTarget->GetPropertyAsBool("AUTOMOC_COMPILER_PREDEFINES") &&
(this->QtVersion >= IntegerVersion(5, 8))) {
// Command
- this->Makefile->GetDefExpandList("CMAKE_CXX_COMPILER_PREDEFINES_COMMAND",
- this->Moc.PredefsCmd);
+ cmList::assign(
+ this->Moc.PredefsCmd,
+ this->Makefile->GetDefinition("CMAKE_CXX_COMPILER_PREDEFINES_COMMAND"));
// Header
if (!this->Moc.PredefsCmd.empty()) {
this->ConfigFileNames(this->Moc.PredefsFile,
@@ -701,7 +727,7 @@ bool cmQtAutoGenInitializer::InitUic()
this->GenTarget->GetSafeProperty("AUTOUIC_SEARCH_PATHS");
if (!usp.empty()) {
this->Uic.SearchPaths =
- SearchPathSanitizer(this->Makefile)(cmExpandedList(usp));
+ SearchPathSanitizer(this->Makefile)(cmList{ usp });
}
}
// Uic target options
@@ -961,8 +987,8 @@ bool cmQtAutoGenInitializer::InitScanFiles()
if (uicOpts.empty()) {
this->Uic.UiFilesNoOptions.emplace_back(fullPath);
} else {
- this->Uic.UiFilesWithOptions.emplace_back(fullPath,
- cmExpandedList(uicOpts));
+ this->Uic.UiFilesWithOptions.emplace_back(
+ fullPath, std::move(cmList{ uicOpts }.data()));
}
auto uiHeaderRelativePath = cmSystemTools::RelativePath(
@@ -1063,8 +1089,8 @@ bool cmQtAutoGenInitializer::InitScanFiles()
if (!this->Rcc.Qrcs.empty()) {
const bool modernQt = (this->QtVersion.Major >= 5);
// Target rcc options
- std::vector<std::string> optionsTarget =
- cmExpandedList(this->GenTarget->GetSafeProperty(kw.AUTORCC_OPTIONS));
+ cmList optionsTarget{ this->GenTarget->GetSafeProperty(
+ kw.AUTORCC_OPTIONS) };
// Check if file name is unique
for (Qrc& qrc : this->Rcc.Qrcs) {
diff --git a/Source/cmRemoveCommand.cxx b/Source/cmRemoveCommand.cxx
index 8af13ae2b4..65a2268bc8 100644
--- a/Source/cmRemoveCommand.cxx
+++ b/Source/cmRemoveCommand.cxx
@@ -3,8 +3,8 @@
#include "cmRemoveCommand.h"
#include "cmExecutionStatus.h"
+#include "cmList.h"
#include "cmMakefile.h"
-#include "cmStringAlgorithms.h"
#include "cmValue.h"
// cmRemoveCommand
@@ -25,12 +25,11 @@ bool cmRemoveCommand(std::vector<std::string> const& args,
}
// expand the variable
- std::vector<std::string> const varArgsExpanded = cmExpandedList(*cacheValue);
+ cmList const varArgsExpanded{ *cacheValue };
// expand the args
// check for REMOVE(VAR v1 v2 ... vn)
- std::vector<std::string> const argsExpanded =
- cmExpandedLists(args.begin() + 1, args.end());
+ cmList const argsExpanded{ args.begin() + 1, args.end() };
// now create the new value
std::string value;
diff --git a/Source/cmRuntimeDependencyArchive.cxx b/Source/cmRuntimeDependencyArchive.cxx
index 4dfdfae4f9..2fbf2fa04c 100644
--- a/Source/cmRuntimeDependencyArchive.cxx
+++ b/Source/cmRuntimeDependencyArchive.cxx
@@ -3,13 +3,21 @@
#include "cmRuntimeDependencyArchive.h"
+#include <algorithm>
+#include <sstream>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <cm/memory>
+
#include "cmBinUtilsLinuxELFLinker.h"
#include "cmBinUtilsMacOSMachOLinker.h"
#include "cmBinUtilsWindowsPELinker.h"
#include "cmExecutionStatus.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmStateTypes.h"
-#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#if defined(_WIN32)
@@ -22,14 +30,6 @@
# include "cmVSSetupHelper.h"
#endif
-#include <algorithm>
-#include <sstream>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include <cm/memory>
-
#if defined(_WIN32)
static void AddVisualStudioPath(std::vector<std::string>& paths,
const std::string& prefix,
diff --git a/Source/cmSearchPath.cxx b/Source/cmSearchPath.cxx
index d5f6f0dc21..2b992ef285 100644
--- a/Source/cmSearchPath.cxx
+++ b/Source/cmSearchPath.cxx
@@ -9,6 +9,7 @@
#include <cm/optional>
#include "cmFindCommon.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -71,7 +72,7 @@ void cmSearchPath::AddCMakePath(const std::string& variable)
// Get a path from a CMake variable.
if (cmValue value = this->FC->Makefile->GetDefinition(variable)) {
- std::vector<std::string> expanded = cmExpandedList(*value);
+ cmList expanded{ *value };
for (std::string const& p : expanded) {
this->AddPathInternal(
@@ -95,7 +96,7 @@ void cmSearchPath::AddCMakePrefixPath(const std::string& variable)
// Get a path from a CMake variable.
if (cmValue value = this->FC->Makefile->GetDefinition(variable)) {
- std::vector<std::string> expanded = cmExpandedList(*value);
+ cmList expanded{ *value };
this->AddPrefixPaths(
expanded, this->FC->Makefile->GetCurrentSourceDirectory().c_str());
diff --git a/Source/cmStandardLevelResolver.cxx b/Source/cmStandardLevelResolver.cxx
index d2eac0cd7b..f6e8bc6f34 100644
--- a/Source/cmStandardLevelResolver.cxx
+++ b/Source/cmStandardLevelResolver.cxx
@@ -18,6 +18,7 @@
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -349,7 +350,7 @@ struct StandardLevelComputer
for (size_t i = 0; i < this->Levels.size(); ++i) {
if (cmValue prop = makefile->GetDefinition(
cmStrCat(prefix, this->LevelsAsStrings[i], "_COMPILE_FEATURES"))) {
- std::vector<std::string> props = cmExpandedList(*prop);
+ cmList props{ *prop };
if (cm::contains(props, feature)) {
maxLevel = { static_cast<int>(i), this->Levels[i] };
}
@@ -468,7 +469,7 @@ bool cmStandardLevelResolver::CheckCompileFeaturesAvailable(
return false;
}
- std::vector<std::string> availableFeatures = cmExpandedList(features);
+ cmList availableFeatures{ features };
if (!cm::contains(availableFeatures, feature)) {
std::ostringstream e;
e << "The compiler feature \"" << feature << "\" is not known to " << lang
diff --git a/Source/cmStringAlgorithms.cxx b/Source/cmStringAlgorithms.cxx
index 66bf383941..e352d8dd22 100644
--- a/Source/cmStringAlgorithms.cxx
+++ b/Source/cmStringAlgorithms.cxx
@@ -80,77 +80,6 @@ std::vector<std::string> cmTokenize(cm::string_view str, cm::string_view sep)
return tokens;
}
-void cmExpandList(cm::string_view arg, std::vector<std::string>& argsOut,
- bool emptyArgs)
-{
- // If argument is empty, it is an empty list.
- if (!emptyArgs && arg.empty()) {
- return;
- }
-
- // if there are no ; in the name then just copy the current string
- if (arg.find(';') == cm::string_view::npos) {
- argsOut.emplace_back(arg);
- return;
- }
-
- std::string newArg;
- // Break the string at non-escaped semicolons not nested in [].
- int squareNesting = 0;
- cm::string_view::iterator last = arg.begin();
- cm::string_view::iterator const cend = arg.end();
- for (cm::string_view::iterator c = last; c != cend; ++c) {
- switch (*c) {
- case '\\': {
- // We only want to allow escaping of semicolons. Other
- // escapes should not be processed here.
- cm::string_view::iterator cnext = c + 1;
- if ((cnext != cend) && *cnext == ';') {
- newArg.append(last, c);
- // Skip over the escape character
- last = cnext;
- c = cnext;
- }
- } break;
- case '[': {
- ++squareNesting;
- } break;
- case ']': {
- --squareNesting;
- } break;
- case ';': {
- // Break the string here if we are not nested inside square
- // brackets.
- if (squareNesting == 0) {
- newArg.append(last, c);
- // Skip over the semicolon
- last = c + 1;
- if (!newArg.empty() || emptyArgs) {
- // Add the last argument if the string is not empty.
- argsOut.push_back(newArg);
- newArg.clear();
- }
- }
- } break;
- default: {
- // Just append this character.
- } break;
- }
- }
- newArg.append(last, cend);
- if (!newArg.empty() || emptyArgs) {
- // Add the last argument if the string is not empty.
- argsOut.push_back(std::move(newArg));
- }
-}
-
-std::vector<std::string> cmExpandedList(cm::string_view arg, bool emptyArgs)
-{
- std::vector<std::string> argsOut;
- cmExpandList(arg, argsOut, emptyArgs);
- return argsOut;
-}
-
namespace {
template <std::size_t N, typename T>
inline void MakeDigits(cm::string_view& view, char (&digits)[N],
diff --git a/Source/cmStringAlgorithms.h b/Source/cmStringAlgorithms.h
index 9ea74919f6..4a9840b166 100644
--- a/Source/cmStringAlgorithms.h
+++ b/Source/cmStringAlgorithms.h
@@ -88,63 +88,6 @@ std::string cmJoin(cmStringRange const& rng, cm::string_view separator,
/** Extract tokens that are separated by any of the characters in @a sep. */
std::vector<std::string> cmTokenize(cm::string_view str, cm::string_view sep);
-/**
- * Expand the ; separated string @a arg into multiple arguments.
- * All found arguments are appended to @a argsOut.
- */
-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
- * ; separated strings into multiple arguments. All found arguments are
- * appended to @a argsOut.
- */
-template <class InputIt>
-void cmExpandLists(InputIt first, InputIt last,
- std::vector<std::string>& argsOut)
-{
- for (; first != last; ++first) {
- cmExpandList(*first, argsOut);
- }
-}
-
-/**
- * Same as cmExpandList but a new vector is created containing
- * the expanded arguments from the string @a arg.
- */
-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
- * versions of all arguments in the string range [@a first, @a last).
- */
-template <class InputIt>
-std::vector<std::string> cmExpandedLists(InputIt first, InputIt last)
-{
- std::vector<std::string> argsOut;
- for (; first != last; ++first) {
- cmExpandList(*first, argsOut);
- }
- return argsOut;
-}
-
/** Concatenate string pieces into a single string. */
std::string cmCatViews(
std::initializer_list<std::pair<cm::string_view, std::string*>> views);
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 5e558714e2..0fbe430140 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -23,6 +23,7 @@
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -92,7 +93,7 @@ cmValue cmTargetPropertyComputer::GetSources<cmTarget>(cmTarget const* tgt,
std::ostringstream ss;
const char* sep = "";
for (auto const& entry : entries) {
- std::vector<std::string> files = cmExpandedList(entry.Value);
+ cmList files{ entry.Value };
for (std::string const& file : files) {
if (cmHasLiteralPrefix(file, "$<TARGET_OBJECTS:") &&
file.back() == '>') {
@@ -396,6 +397,10 @@ TargetProperty const StaticTargetProperties[] = {
{ "MSVC_DEBUG_INFORMATION_FORMAT"_s, IC::CanCompileSources },
{ "MSVC_RUNTIME_LIBRARY"_s, IC::CanCompileSources },
{ "VS_JUST_MY_CODE_DEBUGGING"_s, IC::CanCompileSources },
+ { "VS_DEBUGGER_COMMAND"_s, IC::ExecutableTarget },
+ { "VS_DEBUGGER_COMMAND_ARGUMENTS"_s, IC::ExecutableTarget },
+ { "VS_DEBUGGER_ENVIRONMENT"_s, IC::ExecutableTarget },
+ { "VS_DEBUGGER_WORKING_DIRECTORY"_s, IC::ExecutableTarget },
// ---- OpenWatcom
{ "WATCOM_RUNTIME_LIBRARY"_s, IC::CanCompileSources },
// -- Language
@@ -545,6 +550,7 @@ TargetProperty const StaticTargetProperties[] = {
// -- Autogen
{ "AUTOGEN_ORIGIN_DEPENDS"_s, IC::CanCompileSources },
{ "AUTOGEN_PARALLEL"_s, IC::CanCompileSources },
+ { "AUTOGEN_USE_SYSTEM_INCLUDE"_s, IC::CanCompileSources },
// -- moc
{ "AUTOMOC_DEPEND_FILTERS"_s, IC::CanCompileSources },
// -- C++
@@ -1115,7 +1121,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
if (globals) {
const std::string genName = mf->GetGlobalGenerator()->GetName();
if (cmHasLiteralPrefix(genName, "Visual Studio")) {
- std::vector<std::string> props = cmExpandedList(*globals);
+ cmList props{ *globals };
const std::string vsGlobal = "VS_GLOBAL_";
for (const std::string& i : props) {
// split NAME=VALUE
@@ -1428,7 +1434,7 @@ public:
bool operator()(BT<std::string> const& entry)
{
- std::vector<std::string> files = cmExpandedList(entry.Value);
+ cmList files{ entry.Value };
std::vector<cmSourceFileLocation> locations;
locations.reserve(files.size());
std::transform(files.begin(), files.end(), std::back_inserter(locations),
@@ -2967,7 +2973,7 @@ std::vector<std::string> cmTarget::GetAllInterfaceFileSets() const
auto appendEntries = [=](const std::vector<BT<std::string>>& entries) {
for (auto const& entry : entries) {
- auto expanded = cmExpandedList(entry.Value);
+ cmList expanded{ entry.Value };
std::copy(expanded.begin(), expanded.end(), inserter);
}
};
@@ -3029,11 +3035,11 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config, cmValue& loc,
// Track the configuration-specific property suffix.
suffix = cmStrCat('_', config_upper);
- std::vector<std::string> mappedConfigs;
+ cmList mappedConfigs;
{
std::string mapProp = cmStrCat("MAP_IMPORTED_CONFIG_", config_upper);
if (cmValue mapValue = this->GetProperty(mapProp)) {
- cmExpandList(*mapValue, mappedConfigs, true);
+ mappedConfigs.assign(*mapValue, cmList::EmptyElements::Yes);
}
}
@@ -3115,9 +3121,9 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config, cmValue& loc,
// If we have not yet found it then the project is willing to try
// any available configuration.
if (!loc && !imp) {
- std::vector<std::string> availableConfigs;
+ cmList availableConfigs;
if (cmValue iconfigs = this->GetProperty("IMPORTED_CONFIGURATIONS")) {
- cmExpandList(*iconfigs, availableConfigs);
+ availableConfigs.assign(*iconfigs);
}
for (auto aci = availableConfigs.begin();
!loc && !imp && aci != availableConfigs.end(); ++aci) {
diff --git a/Source/cmTargetSourcesCommand.cxx b/Source/cmTargetSourcesCommand.cxx
index 53e25b5d3f..cd7ff7419d 100644
--- a/Source/cmTargetSourcesCommand.cxx
+++ b/Source/cmTargetSourcesCommand.cxx
@@ -13,6 +13,7 @@
#include "cmExperimental.h"
#include "cmFileSet.h"
#include "cmGeneratorExpression.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -320,7 +321,7 @@ bool TargetSourcesImpl::HandleOneFileSet(
fileSet.first->AddDirectoryEntry(
BT<std::string>(baseDirectories, this->Makefile->GetBacktrace()));
if (type == "HEADERS"_s || type == "CXX_MODULE_HEADER_UNITS"_s) {
- for (auto const& dir : cmExpandedList(baseDirectories)) {
+ for (auto const& dir : cmList{ baseDirectories }) {
auto interfaceDirectoriesGenex =
cmStrCat("$<BUILD_INTERFACE:", dir, ">");
if (cmFileSetVisibilityIsForSelf(visibility)) {
diff --git a/Source/cmTestGenerator.cxx b/Source/cmTestGenerator.cxx
index 5e325dd221..c4a2bc220d 100644
--- a/Source/cmTestGenerator.cxx
+++ b/Source/cmTestGenerator.cxx
@@ -13,6 +13,7 @@
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
@@ -147,16 +148,15 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
}
// Evaluate command line arguments
- std::vector<std::string> argv =
- this->EvaluateCommandLineArguments(this->Test->GetCommand(), ge, config);
-
- // Expand arguments if COMMAND_EXPAND_LISTS is set
- if (this->Test->GetCommandExpandLists()) {
- argv = cmExpandedLists(argv.begin(), argv.end());
- // Expanding lists on an empty command may have left it empty
- if (argv.empty()) {
- argv.emplace_back();
- }
+ cmList argv{
+ this->EvaluateCommandLineArguments(this->Test->GetCommand(), ge, config),
+ // Expand arguments if COMMAND_EXPAND_LISTS is set
+ this->Test->GetCommandExpandLists() ? cmList::ExpandElements::Yes
+ : cmList::ExpandElements::No
+ };
+ // Expanding lists on an empty command may have left it empty
+ if (argv.empty()) {
+ argv.emplace_back();
}
// Check whether the command executable is a target whose name is to
@@ -170,7 +170,7 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
// Prepend with the emulator when cross compiling if required.
cmValue emulator = target->GetProperty("CROSSCOMPILING_EMULATOR");
if (cmNonempty(emulator)) {
- std::vector<std::string> emulatorWithArgs = cmExpandedList(*emulator);
+ cmList emulatorWithArgs{ *emulator };
std::string emulatorExe(emulatorWithArgs[0]);
cmSystemTools::ConvertToUnixSlashes(emulatorExe);
os << cmOutputConverter::EscapeForCMake(emulatorExe) << " ";
diff --git a/Source/cmTryRunCommand.cxx b/Source/cmTryRunCommand.cxx
index b648d9b94f..368155c346 100644
--- a/Source/cmTryRunCommand.cxx
+++ b/Source/cmTryRunCommand.cxx
@@ -15,6 +15,7 @@
#include "cmCoreTryCompile.h"
#include "cmDuration.h"
#include "cmExecutionStatus.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmRange.h"
@@ -271,7 +272,7 @@ void TryRunCommandImpl::RunExecutable(const std::string& runArgs,
const std::string& emulator =
this->Makefile->GetSafeDefinition("CMAKE_CROSSCOMPILING_EMULATOR");
if (!emulator.empty()) {
- std::vector<std::string> emulatorWithArgs = cmExpandedList(emulator);
+ cmList emulatorWithArgs{ emulator };
finalCommand +=
cmSystemTools::ConvertToRunCommandPath(emulatorWithArgs[0]);
finalCommand += " ";
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 8926f9ed15..7360bf5d75 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -9,6 +9,7 @@
#include <set>
#include <sstream>
+#include <cm/filesystem>
#include <cm/memory>
#include <cm/optional>
#include <cm/string_view>
@@ -31,6 +32,7 @@
#include "cmGlobalVisualStudio7Generator.h"
#include "cmGlobalVisualStudioGenerator.h"
#include "cmLinkLineDeviceComputer.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmLocalVisualStudio10Generator.h"
@@ -50,6 +52,8 @@
#include "cmValue.h"
#include "cmVisualStudioGeneratorOptions.h"
+const std::string kBuildSystemSources = "Buildsystem Input Files";
+
struct cmIDEFlagTable;
static void ConvertToWindowsSlash(std::string& s);
@@ -1090,10 +1094,10 @@ void cmVisualStudio10TargetGenerator::WritePackageReferences(Elem& e0)
void cmVisualStudio10TargetGenerator::WriteDotNetReferences(Elem& e0)
{
- std::vector<std::string> references;
+ cmList references;
if (cmValue vsDotNetReferences =
this->GeneratorTarget->GetProperty("VS_DOTNET_REFERENCES")) {
- cmExpandList(*vsDotNetReferences, references);
+ references.assign(*vsDotNetReferences);
}
cmPropertyMap const& props = this->GeneratorTarget->Target->GetProperties();
for (auto const& i : props.GetList()) {
@@ -1110,7 +1114,7 @@ void cmVisualStudio10TargetGenerator::WriteDotNetReferences(Elem& e0)
}
if (!references.empty() || !this->DotNetHintReferences.empty()) {
Elem e1(e0, "ItemGroup");
- for (std::string const& ri : references) {
+ for (auto const& ri : references) {
// if the entry from VS_DOTNET_REFERENCES is an existing file, generate
// a new hint-reference and name it from the filename
if (cmsys::SystemTools::FileExists(ri, true)) {
@@ -1167,7 +1171,7 @@ void cmVisualStudio10TargetGenerator::WriteImports(Elem& e0)
cmValue imports =
this->GeneratorTarget->Target->GetProperty("VS_PROJECT_IMPORT");
if (imports) {
- std::vector<std::string> argsSplit = cmExpandedList(*imports, false);
+ cmList argsSplit{ *imports };
for (auto& path : argsSplit) {
if (!cmsys::SystemTools::FileIsFullPath(path)) {
path = this->Makefile->GetCurrentSourceDirectory() + "/" + path;
@@ -1365,20 +1369,20 @@ void cmVisualStudio10TargetGenerator::WriteTargetsFileReferences(Elem& e1)
void cmVisualStudio10TargetGenerator::WriteWinRTReferences(Elem& e0)
{
- std::vector<std::string> references;
+ cmList references;
if (cmValue vsWinRTReferences =
this->GeneratorTarget->GetProperty("VS_WINRT_REFERENCES")) {
- cmExpandList(*vsWinRTReferences, references);
+ references.assign(*vsWinRTReferences);
}
if (this->GlobalGenerator->TargetsWindowsPhone() &&
this->GlobalGenerator->GetSystemVersion() == "8.0" &&
references.empty()) {
- references.push_back("platform.winmd");
+ references.push_back(std::string{ "platform.winmd" });
}
if (!references.empty()) {
Elem e1(e0, "ItemGroup");
- for (std::string const& ri : references) {
+ for (auto const& ri : references) {
Elem e2(e1, "Reference");
e2.Attribute("Include", ri);
e2.Element("IsWinMDFile", "true");
@@ -1949,7 +1953,13 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
"http://schemas.microsoft.com/developer/msbuild/2003");
for (auto const& ti : this->Tools) {
- this->WriteGroupSources(e0, ti.first, ti.second, sourceGroups);
+ if ((this->GeneratorTarget->GetName() ==
+ CMAKE_CHECK_BUILD_SYSTEM_TARGET) &&
+ (ti.first == "None")) {
+ this->WriteBuildSystemSources(e0, ti.first, ti.second);
+ } else {
+ this->WriteGroupSources(e0, ti.first, ti.second, sourceGroups);
+ }
}
// Added files are images and the manifest.
@@ -2020,6 +2030,18 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
"rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;"
"gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms");
}
+
+ if (this->GeneratorTarget->GetName() ==
+ CMAKE_CHECK_BUILD_SYSTEM_TARGET) {
+ for (const std::string& filter : this->BuildSystemSourcesFilters) {
+ std::string guidName = "SG_Filter_";
+ guidName += filter;
+ std::string guid = this->GlobalGenerator->GetGUID(guidName);
+ Elem e2(e1, "Filter");
+ e2.Attribute("Include", filter);
+ e2.Element("UniqueIdentifier", "{" + guid + "}");
+ }
+ }
}
}
fout << '\n';
@@ -2086,6 +2108,39 @@ void cmVisualStudio10TargetGenerator::WriteGroupSources(
}
}
+void cmVisualStudio10TargetGenerator::WriteBuildSystemSources(
+ Elem& e0, std::string const& name, ToolSources const& sources)
+{
+ const std::string srcDir = this->Makefile->GetCurrentSourceDirectory();
+ const std::string::size_type srcDirLength = srcDir.length();
+
+ Elem e1(e0, "ItemGroup");
+ e1.SetHasElements();
+ for (ToolSource const& s : sources) {
+ cmSourceFile const* sf = s.SourceFile;
+ std::string const& source = sf->GetFullPath();
+
+ cm::filesystem::path sourcePath(source);
+ bool isInSrcDir = cmHasPrefix(source, srcDir);
+
+ std::string filter = kBuildSystemSources;
+ if (isInSrcDir) {
+ std::string parentPath = sourcePath.parent_path().string();
+ if (srcDir != parentPath) {
+ filter += parentPath.substr(srcDirLength);
+ }
+ ConvertToWindowsSlash(filter);
+ this->BuildSystemSourcesFilters.insert(filter);
+ }
+
+ std::string path = this->ConvertPath(source, s.RelativePath);
+ ConvertToWindowsSlash(path);
+ Elem e2(e1, name);
+ e2.Attribute("Include", path);
+ e2.Element("Filter", filter);
+ }
+}
+
void cmVisualStudio10TargetGenerator::WriteHeaderSource(
Elem& e1, cmSourceFile const* sf, ConfigToSettings const& toolSettings)
{
@@ -2113,8 +2168,8 @@ void cmVisualStudio10TargetGenerator::ParseSettingsProperty(
for (const std::string& config : this->Configurations) {
std::string evaluated = cge->Evaluate(this->LocalGenerator, config);
- std::vector<std::string> settings = cmExpandedList(evaluated);
- for (const std::string& setting : settings) {
+ cmList settings{ evaluated };
+ for (const auto& setting : settings) {
const std::string::size_type assignment = setting.find('=');
if (assignment != std::string::npos) {
const std::string propName = setting.substr(0, assignment);
@@ -2714,16 +2769,11 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
if (lang == "ASM_NASM") {
if (cmValue objectDeps = sf.GetProperty("OBJECT_DEPENDS")) {
- std::string dependencies;
- std::vector<std::string> depends = cmExpandedList(*objectDeps);
- const char* sep = "";
- for (std::string& d : depends) {
+ cmList depends{ *objectDeps };
+ for (auto& d : depends) {
ConvertToWindowsSlash(d);
- dependencies += sep;
- dependencies += d;
- sep = ";";
}
- e2.Element("AdditionalDependencies", dependencies);
+ e2.Element("AdditionalDependencies", depends.join(";"));
}
}
@@ -4767,13 +4817,13 @@ void cmVisualStudio10TargetGenerator::WriteSinglePlatformExtension(
void cmVisualStudio10TargetGenerator::WriteSDKReferences(Elem& e0)
{
- std::vector<std::string> sdkReferences;
+ cmList sdkReferences;
std::unique_ptr<Elem> spe1;
if (cmValue vsSDKReferences =
this->GeneratorTarget->GetProperty("VS_SDK_REFERENCES")) {
- cmExpandList(*vsSDKReferences, sdkReferences);
+ sdkReferences.assign(*vsSDKReferences);
spe1 = cm::make_unique<Elem>(e0, "ItemGroup");
- for (std::string const& ri : sdkReferences) {
+ for (auto const& ri : sdkReferences) {
Elem(*spe1, "SDKReference").Attribute("Include", ri);
}
}
diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h
index 97ae69fc37..a87cb01b7e 100644
--- a/Source/cmVisualStudio10TargetGenerator.h
+++ b/Source/cmVisualStudio10TargetGenerator.h
@@ -193,6 +193,9 @@ private:
void WriteGroupSources(Elem& e0, std::string const& name,
ToolSources const& sources,
std::vector<cmSourceGroup>&);
+ void WriteBuildSystemSources(Elem& e0, std::string const& name,
+ ToolSources const& sources);
+
void AddMissingSourceGroups(std::set<cmSourceGroup const*>& groupsUsed,
const std::vector<cmSourceGroup>& allGroups);
bool IsResxHeader(const std::string& headerFile);
@@ -243,6 +246,7 @@ private:
std::set<std::string> ASanEnabledConfigurations;
std::set<std::string> FuzzerEnabledConfigurations;
std::map<std::string, std::string> SpectreMitigation;
+ std::set<std::string> BuildSystemSourcesFilters;
cmGlobalVisualStudio10Generator* const GlobalGenerator;
cmLocalVisualStudio10Generator* const LocalGenerator;
std::set<std::string> CSharpCustomCommandNames;
diff --git a/Source/cmXCodeScheme.cxx b/Source/cmXCodeScheme.cxx
index e727d22141..7f26fd8b23 100644
--- a/Source/cmXCodeScheme.cxx
+++ b/Source/cmXCodeScheme.cxx
@@ -13,6 +13,7 @@
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
+#include "cmList.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -270,7 +271,7 @@ void cmXCodeScheme::WriteLaunchAction(cmXMLWriter& xout,
if (cmValue argList =
this->Target->GetTarget()->GetProperty("XCODE_SCHEME_ARGUMENTS")) {
- std::vector<std::string> arguments = cmExpandedList(*argList);
+ cmList arguments{ *argList };
if (!arguments.empty()) {
xout.StartElement("CommandLineArguments");
@@ -290,7 +291,7 @@ void cmXCodeScheme::WriteLaunchAction(cmXMLWriter& xout,
if (cmValue envList =
this->Target->GetTarget()->GetProperty("XCODE_SCHEME_ENVIRONMENT")) {
- std::vector<std::string> envs = cmExpandedList(*envList);
+ cmList envs{ *envList };
if (!envs.empty()) {
xout.StartElement("EnvironmentVariables");
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 8dee5cc13c..0fd7461339 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -53,6 +53,7 @@
# include "cmMakefileProfilingData.h"
#endif
#include "cmJSONState.h"
+#include "cmList.h"
#include "cmMessenger.h"
#include "cmState.h"
#include "cmStateDirectory.h"
@@ -813,7 +814,7 @@ bool cmake::FindPackage(const std::vector<std::string>& args)
}
} else if (mode == "COMPILE"_s) {
std::string includes = mf->GetSafeDefinition("PACKAGE_INCLUDE_DIRS");
- std::vector<std::string> includeDirs = cmExpandedList(includes);
+ cmList includeDirs{ includes };
this->GlobalGenerator->CreateGenerationObjects();
const auto& lg = this->GlobalGenerator->LocalGenerators[0];
@@ -829,7 +830,7 @@ bool cmake::FindPackage(const std::vector<std::string>& args)
tgt->SetProperty("LINKER_LANGUAGE", language);
std::string libs = mf->GetSafeDefinition("PACKAGE_LIBRARIES");
- std::vector<std::string> libList = cmExpandedList(libs);
+ cmList libList{ libs };
for (std::string const& lib : libList) {
tgt->AddLinkLibrary(*mf, lib, GENERAL_LibraryType);
}
@@ -1026,7 +1027,7 @@ void cmake::SetArgs(const std::vector<std::string>& args)
CommandArgument{ "--check-build-system", CommandArgument::Values::Two,
[](std::string const& value, cmake* state) -> bool {
- std::vector<std::string> values = cmExpandedList(value);
+ cmList values{ value };
state->CheckBuildSystemArgument = values[0];
state->ClearBuildSystem = (atoi(values[1].c_str()) > 0);
return true;
@@ -2163,7 +2164,7 @@ struct SaveCacheEntry
int cmake::HandleDeleteCacheVariables(const std::string& var)
{
- std::vector<std::string> argsSplit = cmExpandedList(var, true);
+ cmList argsSplit{ var, cmList::EmptyElements::Yes };
// erase the property to avoid infinite recursion
this->State->SetGlobalProperty("__CMAKE_DELETE_CACHE_CHANGE_VARS_", "");
if (this->GetIsInTryCompile()) {
@@ -3140,9 +3141,8 @@ int cmake::CheckBuildSystem()
}
// If any byproduct of makefile generation is missing we must re-run.
- std::vector<std::string> products;
- mf.GetDefExpandList("CMAKE_MAKEFILE_PRODUCTS", products);
- for (std::string const& p : products) {
+ cmList products{ mf.GetDefinition("CMAKE_MAKEFILE_PRODUCTS") };
+ for (auto const& p : products) {
if (!(cmSystemTools::FileExists(p) || cmSystemTools::FileIsSymlink(p))) {
if (verbose) {
cmSystemTools::Stdout(
@@ -3153,10 +3153,10 @@ int cmake::CheckBuildSystem()
}
// Get the set of dependencies and outputs.
- std::vector<std::string> depends;
- std::vector<std::string> outputs;
- if (mf.GetDefExpandList("CMAKE_MAKEFILE_DEPENDS", depends)) {
- mf.GetDefExpandList("CMAKE_MAKEFILE_OUTPUTS", outputs);
+ cmList depends{ mf.GetDefinition("CMAKE_MAKEFILE_DEPENDS") };
+ cmList outputs;
+ if (!depends.empty()) {
+ outputs.assign(mf.GetDefinition("CMAKE_MAKEFILE_OUTPUTS"));
}
if (depends.empty() || outputs.empty()) {
// Not enough information was provided to do the test. Just rerun.
@@ -3432,19 +3432,18 @@ void cmake::IssueMessage(MessageType t, std::string const& text,
std::vector<std::string> cmake::GetDebugConfigs()
{
- std::vector<std::string> configs;
+ cmList configs;
if (cmValue config_list =
this->State->GetGlobalProperty("DEBUG_CONFIGURATIONS")) {
// Expand the specified list and convert to upper-case.
- cmExpandList(*config_list, configs);
- std::transform(configs.begin(), configs.end(), configs.begin(),
- cmSystemTools::UpperCase);
+ configs.assign(*config_list);
+ configs.transform(cmList::TransformAction::TOUPPER);
}
// If no configurations were specified, use a default list.
if (configs.empty()) {
configs.emplace_back("DEBUG");
}
- return configs;
+ return std::move(configs.data());
}
int cmake::Build(int jobs, std::string dir, std::vector<std::string> targets,
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index f4e602bf02..ad27443596 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -26,6 +26,7 @@
#include "cmConsoleBuf.h"
#include "cmDocumentationEntry.h"
#include "cmGlobalGenerator.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmMessageMetadata.h"
#include "cmState.h"
@@ -457,7 +458,7 @@ int do_build(int ac, char const* const* av)
};
auto targetLambda = [&](std::string const& value) -> bool {
if (!value.empty()) {
- std::vector<std::string> values = cmExpandedList(value);
+ cmList values{ value };
for (auto const& v : values) {
targets.emplace_back(v);
if (v == "clean") {
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index a2a9e09cfc..9929e85905 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -3,6 +3,7 @@
#include "cmcmd.h"
#include <functional>
+#include <iterator>
#include <cm/optional>
#include <cmext/algorithm>
@@ -14,6 +15,7 @@
#include "cmConsoleBuf.h"
#include "cmDuration.h"
#include "cmGlobalGenerator.h"
+#include "cmList.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmQtAutoMocUic.h"
@@ -342,10 +344,9 @@ int HandleIWYU(const std::string& runCmd, const std::string& /* sourceFile */,
{
// Construct the iwyu command line by taking what was given
// and adding all the arguments we give to the compiler.
- std::vector<std::string> iwyu_cmd = cmExpandedList(runCmd, true);
+ cmList iwyu_cmd{ runCmd, cmList::EmptyElements::Yes };
cm::append(iwyu_cmd, orig_cmd.begin() + 1, orig_cmd.end());
// Run the iwyu command line. Capture its stderr and hide its stdout.
- // Ignore its return code because the tool always returns non-zero.
std::string stdErr;
int ret;
if (!cmSystemTools::RunSingleCommand(iwyu_cmd, nullptr, &stdErr, &ret,
@@ -359,14 +360,21 @@ int HandleIWYU(const std::string& runCmd, const std::string& /* sourceFile */,
std::cerr << "Warning: include-what-you-use reported diagnostics:\n"
<< stdErr << "\n";
}
- // always return 0 we don't want to break the compile
- return 0;
+ // Older versions of iwyu always returned a non-zero exit code,
+ // so ignore it unless the user has enabled errors.
+ auto has_error_opt = std::find_if(
+ iwyu_cmd.cbegin(), iwyu_cmd.cend(),
+ [](std::string const& opt) { return cmHasLiteralPrefix(opt, "--error"); });
+ bool errors_enabled = has_error_opt != iwyu_cmd.cend() &&
+ has_error_opt != iwyu_cmd.cbegin() &&
+ *std::prev(has_error_opt) == "-Xiwyu";
+ return errors_enabled ? ret : 0;
}
int HandleTidy(const std::string& runCmd, const std::string& sourceFile,
const std::vector<std::string>& orig_cmd)
{
- std::vector<std::string> tidy_cmd = cmExpandedList(runCmd, true);
+ cmList tidy_cmd{ runCmd, cmList::EmptyElements::Yes };
tidy_cmd.push_back(sourceFile);
for (auto const& arg : tidy_cmd) {
@@ -416,7 +424,7 @@ int HandleLWYU(const std::string& runCmd, const std::string& sourceFile,
{
// Construct the ldd -r -u (link what you use lwyu) command line
// ldd -u -r lwuy target
- std::vector<std::string> lwyu_cmd = cmExpandedList(runCmd, true);
+ cmList lwyu_cmd{ runCmd, cmList::EmptyElements::Yes };
lwyu_cmd.push_back(sourceFile);
// Run the lwyu check command line, currently ldd is expected.
@@ -444,7 +452,7 @@ int HandleCppLint(const std::string& runCmd, const std::string& sourceFile,
const std::vector<std::string>&)
{
// Construct the cpplint command line.
- std::vector<std::string> cpplint_cmd = cmExpandedList(runCmd, true);
+ cmList cpplint_cmd{ runCmd, cmList::EmptyElements::Yes };
cpplint_cmd.push_back(sourceFile);
// Run the cpplint command line. Capture its output.
@@ -471,7 +479,7 @@ int HandleCppCheck(const std::string& runCmd, const std::string& sourceFile,
const std::vector<std::string>& orig_cmd)
{
// Construct the cpplint command line.
- std::vector<std::string> cppcheck_cmd = cmExpandedList(runCmd, true);
+ cmList cppcheck_cmd{ runCmd, cmList::EmptyElements::Yes };
// extract all the -D, -U, and -I options from the compile line
for (auto const& opt : orig_cmd) {
if (opt.size() > 2) {
@@ -551,8 +559,8 @@ struct CoCompileJob
int cmcmd::HandleCoCompileCommands(std::vector<std::string> const& args)
{
std::vector<CoCompileJob> jobs;
- std::string sourceFile; // store --source=
- std::vector<std::string> launchers; // store --launcher=
+ std::string sourceFile; // store --source=
+ cmList launchers; // store --launcher=
// Default is to run the original command found after -- if the option
// does not need to do that, it should be specified here, currently only
@@ -585,7 +593,7 @@ int cmcmd::HandleCoCompileCommands(std::vector<std::string> const& args)
if (cmHasLiteralPrefix(arg, "--source=")) {
sourceFile = arg.substr(9);
} else if (cmHasLiteralPrefix(arg, "--launcher=")) {
- cmExpandList(arg.substr(11), launchers, true);
+ launchers.append(arg.substr(11), cmList::EmptyElements::Yes);
} else {
// if it was not a co-compiler or --source/--launcher then error
std::cerr << "__run_co_compile given unknown argument: " << arg